diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7a74a4c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,17 @@
+.DS_Store
+.atom/
+.idea
+.vscode/
+.packages
+.pub/
+build/
+ios/.generated/
+packages
+.flutter-plugins
+.history/
+local.properties
+
+pubspec.lock
+pubspec.lock
+scripts/asb/
+.dart_tool/
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 261eeb9..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/android/app/build.gradle b/android/app/build.gradle
index e95268c..5f3a645 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -38,6 +38,7 @@ android {
targetSdkVersion 27
versionCode 1
versionName "1.0"
+ multiDexEnabled true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 7d4eeaf..5586c03 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -19,6 +19,8 @@
+
+
@@ -32,16 +34,11 @@
android:name="io.flutter.app.FlutterApplication"
android:label="maui"
android:icon="@mipmap/ic_launcher">
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/actions/add_comment.dart b/lib/actions/add_comment.dart
new file mode 100644
index 0000000..92bbb39
--- /dev/null
+++ b/lib/actions/add_comment.dart
@@ -0,0 +1,102 @@
+import 'dart:async';
+import 'package:flutter/services.dart';
+import 'package:flutter_redurx/flutter_redurx.dart';
+import 'package:maui/actions/fetch_initial_data.dart';
+import 'package:maui/db/entity/card_progress.dart';
+import 'package:maui/db/entity/comment.dart';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:maui/db/entity/tile.dart';
+import 'package:maui/models/root_state.dart';
+import 'package:maui/repos/card_progress_repo.dart';
+import 'package:maui/repos/comment_repo.dart';
+import 'package:maui/repos/log_repo.dart';
+import 'package:maui/repos/tile_repo.dart';
+import 'package:maui/state/app_state_container.dart';
+import 'package:uuid/uuid.dart';
+import 'package:maui/repos/p2p.dart' as p2p;
+
+class AddComment implements AsyncAction {
+ final Comment comment;
+ final TileType tileType;
+ final bool addTile;
+ CommentRepo commentRepo;
+ TileRepo tileRepo;
+
+ AddComment({this.comment, this.tileType, this.addTile = false});
+
+ @override
+ Future> reduce(RootState state) async {
+ assert(commentRepo != null, 'commentRepo not injected');
+ assert(tileRepo != null, 'tileRepo not injected');
+ commentRepo.insert(comment, tileType);
+ switch (tileType) {
+ case TileType.card:
+ state.cardMap[comment.parentId].comments =
+ (state.cardMap[comment.parentId].comments ?? 0) + 1;
+ break;
+ case TileType.drawing:
+ final commentTile = state.tiles
+ .firstWhere((t) => t.id == comment.parentId, orElse: () => null);
+ if (commentTile != null)
+ commentTile.comments = (commentTile.comments ?? 0) + 1;
+ break;
+ case TileType.message:
+ final commentTile = state.tiles
+ .firstWhere((t) => t.id == comment.parentId, orElse: () => null);
+ if (commentTile != null)
+ commentTile.comments = (commentTile.comments ?? 0) + 1;
+ break;
+ }
+
+ var tile;
+
+ if (addTile) {
+ var tiles = await tileRepo.getTilesByCardId(comment.parentId);
+ if (tiles.length == 0) {
+ tile = Tile(
+ id: Uuid().v4(),
+ cardId: comment.parentId,
+ type: TileType.card,
+ userId: comment.userId,
+ updatedAt: DateTime.now(),
+ card: state.cardMap[comment.parentId],
+ user: state.user); //TODO put real user
+ await tileRepo.insert(tile);
+ }
+ }
+ if (comment.userId == state.user.id)
+ try {
+ await p2p.addMessage(
+ state.user.id,
+ '0',
+ 'comment',
+ '${comment.id}${floresSeparator}${tileType.index}${floresSeparator}${comment.parentId}${floresSeparator}${comment.comment}',
+ true,
+ '');
+ } on PlatformException {
+ print('Flores: Failed addMessage');
+ } catch (e, s) {
+ print('Exception details:\n $e');
+ print('Stack trace:\n $s');
+ }
+ final commentMap = state.commentMap;
+ if (!addTile) {
+ if (commentMap[comment.parentId] == null) {
+ commentMap[comment.parentId] = [];
+ }
+ commentMap[comment.parentId].insert(0, comment);
+ }
+ writeLog('comment,${comment.parentId},${comment.comment}');
+ return (RootState state) => RootState(
+ frontMap: state.frontMap,
+ user: state.user,
+ collectionMap: state.collectionMap,
+ cardMap: state.cardMap,
+ activityMap: state.activityMap,
+ commentMap: commentMap,
+ tiles: tile == null ? state.tiles : (state.tiles..insert(0, tile)),
+ drawings: state.drawings,
+ userMap: state.userMap,
+ templates: state.templates);
+ }
+}
diff --git a/lib/actions/add_like.dart b/lib/actions/add_like.dart
new file mode 100644
index 0000000..81b1ce0
--- /dev/null
+++ b/lib/actions/add_like.dart
@@ -0,0 +1,113 @@
+import 'dart:async';
+import 'dart:convert';
+import 'package:flutter/services.dart';
+import 'package:flutter_redurx/flutter_redurx.dart';
+import 'package:maui/actions/fetch_initial_data.dart';
+import 'package:maui/db/entity/card_progress.dart';
+import 'package:maui/db/entity/like.dart';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:maui/db/entity/tile.dart';
+import 'package:maui/models/root_state.dart';
+import 'package:maui/quack/user_activity.dart';
+import 'package:maui/repos/card_progress_repo.dart';
+import 'package:maui/repos/like_repo.dart';
+import 'package:maui/repos/tile_repo.dart';
+import 'package:maui/repos/user_repo.dart';
+import 'package:maui/state/app_state_container.dart';
+import 'package:shared_preferences/shared_preferences.dart';
+import 'package:uuid/uuid.dart';
+import 'package:maui/repos/p2p.dart' as p2p;
+
+class AddLike implements AsyncAction {
+ final String parentId;
+ final TileType tileType;
+ final String userId;
+
+ LikeRepo likeRepo;
+ TileRepo tileRepo;
+ UserRepo userRepo;
+
+ AddLike({this.parentId, this.tileType, this.userId});
+
+ @override
+ Future> reduce(RootState state) async {
+ assert(likeRepo != null, 'likeRepo not injected');
+ assert(tileRepo != null, 'tileRepo not injected');
+ assert(userRepo != null, 'userRepo not injected');
+
+ final user = userId == null ? state.user : await userRepo.getUser(userId);
+ final like = Like(
+ id: Uuid().v4(),
+ parentId: parentId,
+ userId: userId ?? state.user.id,
+ timeStamp: DateTime.now(),
+ type: 0,
+ user: user);
+ likeRepo.insert(like, tileType);
+ //TODO maybe update card in db also
+ switch (tileType) {
+ case TileType.card:
+ state.cardMap[parentId].likes =
+ (state.cardMap[parentId].likes ?? 0) + 1;
+ break;
+ case TileType.drawing:
+ final likeTile =
+ state.tiles.firstWhere((t) => t.id == parentId, orElse: () => null);
+ if (likeTile != null) likeTile.likes = (likeTile.likes ?? 0) + 1;
+ break;
+ case TileType.message:
+ final likeTile =
+ state.tiles.firstWhere((t) => t.id == parentId, orElse: () => null);
+ if (likeTile != null) likeTile.likes = (likeTile.likes ?? 0) + 1;
+ break;
+ }
+
+// var tile =
+// state.tiles.firstWhere((t) => t.id == parentId, orElse: () => null);
+// print('tile: $tile');
+// if (tile == null) {
+// tile = Tile(
+// id: Uuid().v4(),
+// cardId: parentId,
+// content: '${user.name} liked this',
+// type: TileType.card,
+// userId: userId ?? state.user.id,
+// updatedAt: DateTime.now(),
+// card: state.cardMap[parentId],
+// user: state.user); //TODO put real user
+// await tileRepo.insert(tile);
+// }
+
+ final userActivity = state.activityMap[parentId] ?? UserActivity();
+ if (userId == null) {
+ userActivity.like = true;
+ SharedPreferences prefs = await SharedPreferences.getInstance();
+ prefs.setString('userActivity', json.encode(state.activityMap));
+
+ try {
+ await p2p.addMessage(state.user.id, '0', 'like',
+ '${tileType.index}${floresSeparator}$parentId', true, '');
+ } on PlatformException {
+ print('Flores: Failed addChat');
+ } catch (e, s) {
+ print('Exception details:\n $e');
+ print('Stack trace:\n $s');
+ }
+ }
+
+ return (RootState state) {
+ return RootState(
+ frontMap: state.frontMap,
+ user: state.user,
+ collectionMap: state.collectionMap,
+ cardMap: state.cardMap,
+ activityMap: userId != null ? state.activityMap : state.activityMap
+ ..[parentId] = userActivity,
+ commentMap: state.commentMap,
+ tiles: state.tiles,
+ drawings: state.drawings,
+ userMap: state.userMap,
+ templates: state.templates);
+ };
+ }
+}
diff --git a/lib/actions/add_progress.dart b/lib/actions/add_progress.dart
new file mode 100644
index 0000000..16629f7
--- /dev/null
+++ b/lib/actions/add_progress.dart
@@ -0,0 +1,63 @@
+import 'dart:async';
+import 'dart:convert';
+import 'package:flutter_redurx/flutter_redurx.dart';
+import 'package:maui/actions/fetch_initial_data.dart';
+import 'package:maui/db/entity/card_progress.dart';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:maui/models/root_state.dart';
+import 'package:maui/quack/user_activity.dart';
+import 'package:maui/repos/card_progress_repo.dart';
+import 'package:maui/repos/collection_repo.dart';
+import 'package:maui/repos/log_repo.dart';
+import 'package:shared_preferences/shared_preferences.dart';
+
+class AddProgress implements AsyncAction {
+ final String cardId;
+ final String parentCardId;
+ final int index;
+
+ CardProgressRepo cardProgressRepo;
+ CollectionRepo collectionRepo;
+
+ AddProgress({this.cardId, this.parentCardId, this.index});
+
+ @override
+ Future> reduce(RootState state) async {
+ assert(cardProgressRepo != null, 'CardProgressRepo not injected');
+ assert(collectionRepo != null, 'collectionRepo not injected');
+
+ await cardProgressRepo.upsert(CardProgress(
+ userId: state.user.id, cardId: cardId, updatedAt: DateTime.now()));
+ final progress =
+ await cardProgressRepo.getProgressStatusByCollectionAndTypeAndUserId(
+ parentCardId, CardType.knowledge, state.user.id);
+
+ final userActivity = state.activityMap[parentCardId] ?? UserActivity();
+ var frontMap = state.frontMap;
+ if ((userActivity.done ?? -1) < index) {
+ userActivity.done = index;
+ userActivity.total = userActivity.total ??
+ await collectionRepo
+ .getKnowledgeAndQuizCardCountInCollection(parentCardId);
+ SharedPreferences prefs = await SharedPreferences.getInstance();
+ state.activityMap[parentCardId] = userActivity;
+ prefs.setString('userActivity', json.encode(state.activityMap));
+ if (userActivity.done >= userActivity.total) {
+ frontMap = await FetchInitialData.fetchFrontMap(state);
+ }
+ writeLog('progress,$parentCardId,$cardId,$index,${userActivity.total}');
+ }
+
+ return (RootState state) => RootState(
+ frontMap: frontMap,
+ user: state.user,
+ collectionMap: state.collectionMap,
+ cardMap: state.cardMap,
+ activityMap: state.activityMap..[parentCardId] = userActivity,
+ commentMap: state.commentMap,
+ tiles: state.tiles,
+ userMap: state.userMap,
+ drawings: state.drawings,
+ templates: state.templates);
+ }
+}
diff --git a/lib/actions/fetch_card_detail.dart b/lib/actions/fetch_card_detail.dart
new file mode 100644
index 0000000..9776c21
--- /dev/null
+++ b/lib/actions/fetch_card_detail.dart
@@ -0,0 +1,92 @@
+import 'dart:async';
+import 'dart:convert';
+
+import 'package:flutter_redurx/flutter_redurx.dart';
+import 'package:maui/actions/fetch_initial_data.dart';
+import 'package:maui/db/entity/card_extra.dart';
+import 'package:maui/db/entity/like.dart';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:maui/db/entity/tile.dart';
+import 'package:maui/models/root_state.dart';
+import 'package:maui/repos/card_extra_repo.dart';
+import 'package:maui/repos/card_progress_repo.dart';
+import 'package:maui/repos/card_repo.dart';
+import 'package:maui/repos/collection_repo.dart';
+import 'package:maui/repos/comment_repo.dart';
+import 'package:maui/repos/like_repo.dart';
+import 'package:maui/repos/tile_repo.dart';
+
+class FetchCardDetail implements AsyncAction {
+ final String cardId;
+ CollectionRepo collectionRepo;
+ CardProgressRepo cardProgressRepo;
+ CardRepo cardRepo;
+ CommentRepo commentRepo;
+ LikeRepo likeRepo;
+ TileRepo tileRepo;
+ CardExtraRepo cardExtraRepo;
+
+ FetchCardDetail(this.cardId);
+
+ @override
+ Future> reduce(RootState state) async {
+ assert(collectionRepo != null, 'collectionRepo not injected');
+ assert(cardProgressRepo != null, 'cardProgressRepo not injected');
+ assert(cardRepo != null, 'cardRepo not injected');
+ assert(commentRepo != null, 'commentRepo not injected');
+ assert(likeRepo != null, 'likeRepo not injected');
+ assert(tileRepo != null, 'tileRepo not injected');
+ assert(cardExtraRepo != null, 'cardExtraRepo not injected');
+
+ final cardMap = Map();
+ final progressMap = Map();
+ final collectionMap = Map>();
+ final likeMap = Map();
+ var drawings = List();
+ var templates = List();
+
+ final card = state.cardMap[cardId];
+ if (card == null) {
+ cardMap[cardId] = await cardRepo.getCard(cardId);
+ likeMap[cardId] = await likeRepo.getLikeByParentIdAndUserId(
+ cardId, state.user.id, TileType.card);
+ }
+
+ if (card.type == CardType.concept) {
+ final mainCards =
+ (await collectionRepo.getCardsInCollection(cardId)).map((c) {
+ cardMap[c.id] = c;
+ return c.id;
+ }).toList(growable: false);
+ collectionMap[cardId] = mainCards;
+
+ await Future.forEach(mainCards, (mc) async {
+ progressMap[mc] = await cardProgressRepo
+ .getProgressStatusByCollectionAndTypeAndUserId(
+ mc, CardType.knowledge, state.user.id);
+ likeMap[mc] = await likeRepo.getLikeByParentIdAndUserId(
+ mc, state.user.id, TileType.card);
+ });
+ } else if (card.type == CardType.activity) {
+ drawings =
+ await tileRepo.getTilesByCardIdAndType(card.id, TileType.drawing);
+ templates = await cardExtraRepo.getCardExtrasByCardIdAndType(
+ card.id, CardExtraType.template);
+ }
+
+ final comments =
+ await commentRepo.getCommentsByParentId(cardId, TileType.card);
+
+ return (RootState state) => RootState(
+ frontMap: state.frontMap,
+ user: state.user,
+ collectionMap: state.collectionMap..addAll(collectionMap),
+ cardMap: state.cardMap..addAll(cardMap),
+ activityMap: state.activityMap,
+ tiles: state.tiles,
+ drawings: drawings,
+ userMap: state.userMap,
+ templates: templates,
+ commentMap: state.commentMap..[cardId] = comments);
+ }
+}
diff --git a/lib/actions/fetch_comments.dart b/lib/actions/fetch_comments.dart
new file mode 100644
index 0000000..b1aa10e
--- /dev/null
+++ b/lib/actions/fetch_comments.dart
@@ -0,0 +1,49 @@
+import 'dart:async';
+import 'dart:convert';
+
+import 'package:flutter_redurx/flutter_redurx.dart';
+import 'package:maui/actions/fetch_initial_data.dart';
+import 'package:maui/db/entity/card_extra.dart';
+import 'package:maui/db/entity/like.dart';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:maui/db/entity/tile.dart';
+import 'package:maui/models/root_state.dart';
+import 'package:maui/repos/card_extra_repo.dart';
+import 'package:maui/repos/card_progress_repo.dart';
+import 'package:maui/repos/card_repo.dart';
+import 'package:maui/repos/collection_repo.dart';
+import 'package:maui/repos/comment_repo.dart';
+import 'package:maui/repos/like_repo.dart';
+import 'package:maui/repos/tile_repo.dart';
+
+class FetchComments implements AsyncAction {
+ final String parentId;
+ final TileType tileType;
+
+ CommentRepo commentRepo;
+
+ FetchComments({this.parentId, this.tileType});
+
+ @override
+ Future> reduce(RootState state) async {
+ assert(commentRepo != null, 'commentRepo not injected');
+
+ final comments =
+ await commentRepo.getCommentsByParentId(parentId, tileType);
+ print('FecthComments: $parentId');
+ print(comments);
+ print(state.commentMap);
+
+ return (RootState state) => RootState(
+ frontMap: state.frontMap,
+ user: state.user,
+ collectionMap: state.collectionMap,
+ cardMap: state.cardMap,
+ activityMap: state.activityMap,
+ tiles: state.tiles,
+ drawings: state.drawings,
+ userMap: state.userMap,
+ templates: state.templates,
+ commentMap: state.commentMap..[parentId] = comments);
+ }
+}
diff --git a/lib/actions/fetch_initial_data.dart b/lib/actions/fetch_initial_data.dart
new file mode 100644
index 0000000..245160f
--- /dev/null
+++ b/lib/actions/fetch_initial_data.dart
@@ -0,0 +1,137 @@
+import 'dart:async';
+import 'dart:convert';
+import 'dart:math';
+
+import 'package:maui/quack/user_activity.dart';
+import 'package:maui/repos/card_repo.dart';
+import 'package:maui/repos/tile_repo.dart';
+import 'package:maui/repos/user_repo.dart';
+
+import 'package:shared_preferences/shared_preferences.dart';
+import 'package:flutter_redurx/flutter_redurx.dart';
+import 'package:maui/db/entity/like.dart';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:maui/db/entity/tile.dart';
+import 'package:maui/db/entity/user.dart';
+import 'package:maui/models/root_state.dart';
+import 'package:maui/repos/card_progress_repo.dart';
+import 'package:maui/repos/collection_repo.dart';
+import 'package:maui/repos/like_repo.dart';
+
+class FetchInitialData implements AsyncAction {
+ final User user;
+
+ CollectionRepo collectionRepo;
+ CardProgressRepo cardProgressRepo;
+ LikeRepo likeRepo;
+ TileRepo tileRepo;
+ UserRepo userRepo;
+ CardRepo cardRepo;
+
+ FetchInitialData(this.user);
+
+ @override
+ Future> reduce(RootState state) async {
+ assert(collectionRepo != null, 'collectionRepo not injected');
+ assert(cardProgressRepo != null, 'cardProgressRepo not injected');
+ assert(likeRepo != null, 'likeRepo not injected');
+ assert(tileRepo != null, 'tileRepo not injected');
+ assert(userRepo != null, 'userRepo not injected');
+ assert(cardRepo != null, 'cardRepo not injected');
+
+ final cardMap = Map();
+ final collectionMap = Map>();
+ final progressMap = Map();
+ final likeMap = Map();
+ var activityMap = Map();
+ await fetchCollection(
+ name: 'main',
+ cardMap: cardMap,
+ collectionMap: collectionMap,
+ progressMap: progressMap,
+ likeMap: likeMap);
+ await fetchCollection(
+ name: 'story',
+ cardMap: cardMap,
+ collectionMap: collectionMap,
+ progressMap: progressMap,
+ likeMap: likeMap);
+ await fetchCollection(
+ name: 'open',
+ cardMap: cardMap,
+ collectionMap: collectionMap,
+ progressMap: progressMap,
+ likeMap: likeMap);
+ final dummy = await cardRepo.getCard('dummy');
+ cardMap['dummy'] = dummy;
+ print('open ${collectionMap['open']}');
+ final tiles = await tileRepo.getTilesOtherThanDots();
+ SharedPreferences prefs = await SharedPreferences.getInstance();
+ final userActivity = prefs.getString('userActivity');
+ if (userActivity != null) {
+ activityMap = Map.fromIterable(json.decode(userActivity).entries,
+ key: (me) => me.key, value: (me) => UserActivity.fromJson(me.value));
+ }
+
+ final userList = await userRepo.getRemoteUsers();
+ final botUser = await userRepo.getUser(User.botId);
+ userList.insert(0, botUser);
+ Map userMap =
+ Map.fromIterable(userList, key: (u) => u, value: (u) => 0);
+ final frontMap = await fetchFrontMap(
+ RootState(cardMap: cardMap, collectionMap: collectionMap));
+ return (RootState state) => RootState(
+ frontMap: frontMap,
+ user: user,
+ collectionMap: state.collectionMap..addAll(collectionMap),
+ cardMap: state.cardMap..addAll(cardMap),
+ activityMap: activityMap,
+ tiles: tiles,
+ drawings: state.drawings,
+ userMap: userMap,
+ templates: state.templates,
+ commentMap: {});
+ }
+
+ Future fetchCollection(
+ {String name,
+ Map cardMap,
+ Map> collectionMap,
+ Map progressMap,
+ Map likeMap}) async {
+ final mainCards =
+ (await collectionRepo.getCardsInCollection(name)).map((c) {
+ cardMap[c.id] = c;
+ return c.id;
+ }).toList(growable: false);
+ collectionMap[name] = mainCards;
+
+ await Future.forEach(mainCards, (mc) async {
+ final cardNames =
+ (await collectionRepo.getCardsInCollection(mc)).map((c) {
+ cardMap[c.id] = c;
+ return c.id;
+ }).toList(growable: false);
+
+ collectionMap[mc] = cardNames;
+ });
+ }
+
+ static Future> fetchFrontMap(RootState state) async {
+ final rand = Random();
+ final openCollection = state.collectionMap['open'];
+ final mainCollection = state.collectionMap['main'];
+ final topic = mainCollection[rand.nextInt(mainCollection.length)];
+ final topicCollection = state.collectionMap[topic];
+ final storyCollection = state.collectionMap['story'];
+
+ return {
+ 'open':
+ state.cardMap[openCollection[rand.nextInt(openCollection.length)]],
+ 'topic':
+ state.cardMap[topicCollection[rand.nextInt(topicCollection.length)]],
+ 'story':
+ state.cardMap[storyCollection[rand.nextInt(storyCollection.length)]]
+ };
+ }
+}
diff --git a/lib/actions/fetch_tile_detail.dart b/lib/actions/fetch_tile_detail.dart
new file mode 100644
index 0000000..c801d36
--- /dev/null
+++ b/lib/actions/fetch_tile_detail.dart
@@ -0,0 +1,34 @@
+import 'dart:async';
+
+import 'package:flutter_redurx/flutter_redurx.dart';
+import 'package:maui/actions/fetch_initial_data.dart';
+import 'package:maui/db/entity/tile.dart';
+import 'package:maui/models/root_state.dart';
+import 'package:maui/repos/comment_repo.dart';
+
+class FetchTileDetail implements AsyncAction {
+ final Tile tile;
+ CommentRepo commentRepo;
+
+ FetchTileDetail(this.tile);
+
+ @override
+ Future> reduce(RootState state) async {
+ assert(commentRepo != null, 'commentRepo not injected');
+
+ final comments =
+ await commentRepo.getCommentsByParentId(tile.id, tile.type);
+
+ return (RootState state) => RootState(
+ frontMap: state.frontMap,
+ user: state.user,
+ collectionMap: state.collectionMap,
+ cardMap: state.cardMap,
+ activityMap: state.activityMap,
+ tiles: state.tiles,
+ userMap: state.userMap,
+ drawings: state.drawings,
+ templates: state.templates,
+ commentMap: state.commentMap..[tile.id] = comments);
+ }
+}
diff --git a/lib/actions/post_tile.dart b/lib/actions/post_tile.dart
new file mode 100644
index 0000000..97d63a4
--- /dev/null
+++ b/lib/actions/post_tile.dart
@@ -0,0 +1,78 @@
+import 'dart:async';
+import 'package:flutter/services.dart';
+import 'package:flutter_redurx/flutter_redurx.dart';
+import 'package:maui/actions/fetch_initial_data.dart';
+import 'package:maui/db/entity/card_progress.dart';
+import 'package:maui/db/entity/like.dart';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:maui/db/entity/tile.dart';
+import 'package:maui/models/root_state.dart';
+import 'package:maui/repos/card_progress_repo.dart';
+import 'package:maui/repos/like_repo.dart';
+import 'package:maui/repos/tile_repo.dart';
+import 'package:maui/state/app_state_container.dart';
+import 'package:uuid/uuid.dart';
+import 'package:maui/repos/p2p.dart' as p2p;
+
+class PostTile implements AsyncAction {
+ final Tile tile;
+ final String tileId;
+
+ TileRepo tileRepo;
+
+ PostTile({this.tileId, this.tile});
+
+ @override
+ Future> reduce(RootState state) async {
+ assert(tileRepo != null, 'tileRepo not injected');
+ Tile pTile;
+
+ if (tileId != null) {
+ pTile = await tileRepo.getTile(tileId);
+ } else {
+ await tileRepo.upsert(tile);
+ pTile = await tileRepo.getTile(tile.id);
+ }
+ print('post_tile: $pTile');
+ if (pTile.type == TileType.dot) {
+ pTile = null;
+ }
+
+ if (pTile != null &&
+ pTile.userId == state.user?.id &&
+ pTile.content.length < 12000)
+ try {
+ await p2p.addMessage(
+ state.user.id,
+ '0',
+ 'tile',
+ '${pTile.id}${floresSeparator}${pTile.type.index}${floresSeparator}${pTile.cardId}${floresSeparator}${pTile.content}',
+ true,
+ '');
+ } on PlatformException {
+ print('Flores: Failed addMessage');
+ } catch (e, s) {
+ print('Exception details:\n $e');
+ print('Stack trace:\n $s');
+ }
+
+ final updatedTiles = state.tiles;
+ print('posttile: $pTile ${pTile.card}');
+ if (pTile != null) {
+ state.tiles.removeWhere((t) => t.id == pTile.id);
+ state.tiles.insert(0, pTile);
+ }
+
+ return (RootState state) => RootState(
+ frontMap: state.frontMap,
+ user: state.user,
+ collectionMap: state.collectionMap,
+ cardMap: state.cardMap,
+ commentMap: state.commentMap,
+ activityMap: state.activityMap,
+ tiles: updatedTiles,
+ userMap: state.userMap,
+ drawings: state.drawings,
+ templates: state.templates);
+ }
+}
diff --git a/lib/actions/save_drawing.dart b/lib/actions/save_drawing.dart
new file mode 100644
index 0000000..21f36b3
--- /dev/null
+++ b/lib/actions/save_drawing.dart
@@ -0,0 +1,71 @@
+import 'dart:async';
+import 'dart:convert';
+import 'package:flutter_redurx/flutter_redurx.dart';
+import 'package:maui/actions/fetch_initial_data.dart';
+import 'package:maui/db/entity/card_progress.dart';
+import 'package:maui/db/entity/like.dart';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:maui/db/entity/tile.dart';
+import 'package:maui/models/root_state.dart';
+import 'package:maui/repos/card_progress_repo.dart';
+import 'package:maui/repos/card_repo.dart';
+import 'package:maui/repos/like_repo.dart';
+import 'package:maui/repos/tile_repo.dart';
+import 'package:uuid/uuid.dart';
+
+class SaveDrawing implements AsyncAction {
+ final String cardId;
+ final Map jsonMap;
+
+ TileRepo tileRepo;
+ CardRepo cardRepo;
+
+ SaveDrawing({this.cardId, this.jsonMap});
+
+ @override
+ Future> reduce(RootState state) async {
+ assert(tileRepo != null, 'tileRepo not injected');
+ assert(cardRepo != null, 'cardRepo not injected');
+
+ final card = await cardRepo.getCard(cardId);
+ final tileId = jsonMap['id'];
+ final tile = Tile(
+ id: tileId,
+ cardId: cardId,
+ type: TileType.drawing,
+ content: json.encode(jsonMap),
+ updatedAt: DateTime.now(),
+ userId: state.user.id,
+ card: card,
+ user: state.user);
+
+ final updatedTile = await tileRepo.upsert(tile);
+ final updatedDrawings = state.drawings ?? [];
+ final index = updatedDrawings.indexWhere((t) => t.id == tileId);
+ if (index >= 0) {
+ updatedDrawings[index] = updatedTile;
+ } else {
+ updatedDrawings.add(updatedTile);
+ }
+
+// final updatedTiles = state.tiles;
+// final tileIndex = updatedTiles.indexWhere((t) => t.id == tileId);
+// if (tileIndex >= 0) {
+// updatedTiles[index] = updatedTile;
+// } else {
+// updatedTiles.insert(0, updatedTile);
+// }
+
+ return (RootState state) => RootState(
+ frontMap: state.frontMap,
+ user: state.user,
+ collectionMap: state.collectionMap,
+ cardMap: state.cardMap,
+ activityMap: state.activityMap,
+ commentMap: state.commentMap,
+ tiles: state.tiles,
+ userMap: state.userMap,
+ drawings: updatedDrawings,
+ templates: state.templates);
+ }
+}
diff --git a/lib/actions/share_drawing.dart b/lib/actions/share_drawing.dart
new file mode 100644
index 0000000..5d0d50f
--- /dev/null
+++ b/lib/actions/share_drawing.dart
@@ -0,0 +1,67 @@
+import 'dart:async';
+import 'dart:convert';
+import 'package:flutter_redurx/flutter_redurx.dart';
+import 'package:maui/actions/fetch_initial_data.dart';
+import 'package:maui/db/entity/card_progress.dart';
+import 'package:maui/db/entity/like.dart';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:maui/db/entity/tile.dart';
+import 'package:maui/models/root_state.dart';
+import 'package:maui/repos/card_progress_repo.dart';
+import 'package:maui/repos/like_repo.dart';
+import 'package:maui/repos/tile_repo.dart';
+import 'package:uuid/uuid.dart';
+
+class ShareDrawing implements AsyncAction {
+ final String cardId;
+ final Map jsonMap;
+
+ TileRepo tileRepo;
+
+ ShareDrawing({this.cardId, this.jsonMap});
+
+ @override
+ Future> reduce(RootState state) async {
+ assert(tileRepo != null, 'tileRepo not injected');
+ final tileId = jsonMap['id'];
+ final tile = Tile(
+ id: tileId,
+ cardId: cardId,
+ type: TileType.drawing,
+ content: json.encode(jsonMap),
+ updatedAt: DateTime.now(),
+ userId: state.user.id,
+ card: state.cardMap[cardId],
+ user: state.user);
+
+ final updatedTile = await tileRepo.upsert(tile);
+ final updatedDrawings = state.drawings;
+ final index = updatedDrawings.indexWhere((t) => t.id == tileId);
+ if (index >= 0) {
+ print('save_drawing: saving index $index');
+ updatedDrawings[index] = updatedTile;
+ } else {
+ updatedDrawings.add(updatedTile);
+ }
+
+ final updatedTiles = state.tiles;
+ final tileIndex = updatedTiles.indexWhere((t) => t.id == tileId);
+ if (tileIndex >= 0) {
+ updatedTiles[index] = updatedTile;
+ } else {
+ updatedTiles.insert(0, updatedTile);
+ }
+
+ return (RootState state) => RootState(
+ frontMap: state.frontMap,
+ user: state.user,
+ collectionMap: state.collectionMap,
+ cardMap: state.cardMap,
+ activityMap: state.activityMap,
+ commentMap: state.commentMap,
+ tiles: updatedTiles,
+ userMap: state.userMap,
+ drawings: updatedDrawings,
+ templates: state.templates);
+ }
+}
diff --git a/lib/actions/update_points.dart b/lib/actions/update_points.dart
new file mode 100644
index 0000000..5debe8f
--- /dev/null
+++ b/lib/actions/update_points.dart
@@ -0,0 +1,41 @@
+import 'dart:async';
+import 'package:flutter_redurx/flutter_redurx.dart';
+import 'package:maui/actions/fetch_initial_data.dart';
+import 'package:maui/db/entity/card_progress.dart';
+import 'package:maui/db/entity/comment.dart';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:maui/db/entity/tile.dart';
+import 'package:maui/models/root_state.dart';
+import 'package:maui/repos/card_progress_repo.dart';
+import 'package:maui/repos/comment_repo.dart';
+import 'package:maui/repos/user_repo.dart';
+import 'package:uuid/uuid.dart';
+
+class UpdatePoints implements AsyncAction {
+ final int points;
+
+ UserRepo userRepo;
+
+ UpdatePoints({this.points});
+
+ @override
+ Future> reduce(RootState state) async {
+ assert(userRepo != null, 'userRepo not injected');
+
+ final user = state.user;
+ user.points = (user.points ?? 0) + points;
+ userRepo.update(user);
+
+ return (RootState state) => RootState(
+ frontMap: state.frontMap,
+ user: user,
+ collectionMap: state.collectionMap,
+ cardMap: state.cardMap,
+ activityMap: state.activityMap,
+ commentMap: state.commentMap,
+ tiles: state.tiles,
+ userMap: state.userMap,
+ drawings: state.drawings,
+ templates: state.templates);
+ }
+}
diff --git a/lib/app.dart b/lib/app.dart
index ad570c9..7813e15 100644
--- a/lib/app.dart
+++ b/lib/app.dart
@@ -3,15 +3,24 @@ import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:maui/games/head_to_head_game.dart';
import 'package:maui/games/single_game.dart';
+import 'package:maui/quack/bento.dart';
+import 'package:maui/quack/card_detail.dart';
+import 'package:maui/quack/main_collection.dart';
+import 'package:maui/quack/story_page.dart';
import 'package:maui/screens/chat_bot_screen.dart';
import 'package:maui/screens/chat_screen.dart';
import 'package:maui/screens/game_category_list_screen.dart';
+import 'package:maui/screens/game_list_view.dart';
import 'package:maui/screens/login_screen.dart';
+import 'package:maui/screens/switch_screen.dart';
import 'package:maui/screens/tab_home.dart';
import 'package:maui/state/app_state_container.dart';
import 'components/camera.dart';
+import 'package:maui/screens/welcome_screen.dart';
import 'loca.dart';
+final RouteObserver routeObserver = new RouteObserver();
+
class MauiApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
@@ -29,11 +38,17 @@ class MauiApp extends StatelessWidget {
theme: new ThemeData(
primarySwatch: Colors.blue,
),
+ navigatorObservers: [routeObserver],
routes: {
- '/': (BuildContext context) => new LoginScreen(),
- '/tab': (BuildContext context) => new TabHome(),
+ '/': (BuildContext context) => new SwitchScreen(),
+ '/login': (BuildContext context) => new LoginScreen(),
+ '/welcome': (BuildContext context) => new WelcomeScreen(),
+ '/tab': (BuildContext context) => new Bento(),
'/chatbot': (BuildContext context) => new ChatBotScreen(),
- '/camera': (BuildContext context) => CameraScreen()
+ '/camera': (BuildContext context) => CameraScreen(false),
+ '/stories': (BuildContext context) => StoryPage(),
+ '/topics': (BuildContext context) => MainCollection(),
+ '/games': (BuildContext context) => GameListView()
},
onGenerateRoute: _getRoute,
);
@@ -41,7 +56,6 @@ class MauiApp extends StatelessWidget {
Route _getRoute(RouteSettings settings) {
final List path = settings.name.split('/');
- print(path);
if (path[0] != '') return null;
if (path[1] == 'categories' && path.length == 3) {
@@ -50,9 +64,7 @@ class MauiApp extends StatelessWidget {
builder: (BuildContext context) =>
new GameCategoryListScreen(game: path[2]),
);
- }
-
- if (path[1] == 'games' && path.length == 6) {
+ } else if (path[1] == 'games' && path.length == 6) {
int gameCategoryId = int.parse(path[4], onError: (source) => null);
Random random = new Random();
final textMode = random.nextBool();
@@ -133,7 +145,15 @@ class MauiApp extends StatelessWidget {
),
);
}
+ } else if (path[1] == 'card' && path.length == 4) {
+// Provider.dispatch(context, FetchCardDetail(card.id));
+
+ return new MaterialPageRoute(
+ settings: settings,
+ builder: (BuildContext context) => new CardDetail(),
+ );
}
+
return null;
}
}
diff --git a/lib/app_database.dart b/lib/app_database.dart
index c7660c3..e5cc485 100644
--- a/lib/app_database.dart
+++ b/lib/app_database.dart
@@ -1,6 +1,8 @@
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
+import 'package:maui/db/dao/tile_dao.dart';
+import 'package:maui/db/entity/tile.dart';
import 'package:uuid/uuid.dart';
import 'package:flutter/services.dart' show rootBundle;
@@ -70,13 +72,6 @@ class AppDatabase {
.asUint8List(imageData3.offsetInBytes, imageData3.lengthInBytes);
await new File(imagePath3).writeAsBytes(imageBytes3);
- String imagePath4 = join(documentsDirectory.path, "face.png");
- ByteData imageData4 =
- await rootBundle.load(join("assets", "dict/face.png"));
- List imageBytes4 = imageData4.buffer
- .asUint8List(imageData4.offsetInBytes, imageData4.lengthInBytes);
- await new File(imagePath4).writeAsBytes(imageBytes4);
-
String imagePath5 = join(documentsDirectory.path, "chat_Bot_Icon.png");
ByteData imageData5 =
await rootBundle.load(join("assets", "chat_Bot_Icon.png"));
@@ -134,8 +129,6 @@ class AppDatabase {
image: imagePath5,
deviceId: deviceId,
currentLessonId: 1));
-
- await new UserDao().getUsers().then((u) => print(u));
} else {
_db = await openDatabase(path, version: 1);
}
diff --git a/lib/components/activity_progress_tracker.dart b/lib/components/activity_progress_tracker.dart
new file mode 100644
index 0000000..4fa1ec1
--- /dev/null
+++ b/lib/components/activity_progress_tracker.dart
@@ -0,0 +1,53 @@
+import 'package:flutter/material.dart';
+import 'package:maui/db/entity/user.dart';
+import 'package:maui/repos/card_progress_repo.dart';
+import 'package:maui/state/app_state_container.dart';
+import 'package:maui/db/entity/quack_card.dart';
+
+class ActivityProgressTracker extends StatefulWidget {
+ final String topicId;
+
+ ActivityProgressTracker({Key key, this.topicId}) : super(key: key);
+
+ @override
+ State createState() => new ActivityProgressTrackerState();
+}
+
+class ActivityProgressTrackerState extends State {
+ double _activityProgress;
+ bool _isLoading = true;
+
+ void _initData() async {
+ User _user = AppStateContainer.of(context).state.loggedInUser;
+ _activityProgress = await CardProgressRepo()
+ .getProgressStatusByCollectionAndTypeAndUserId(
+ widget.topicId, CardType.activity, _user.id);
+ setState(() => _isLoading = false);
+ }
+
+ @override
+ void didChangeDependencies() {
+ // TODO: implement didChangeDependencies
+ super.didChangeDependencies();
+ _initData();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ if (_isLoading == true) {
+ return new Container(
+ child: new LinearProgressIndicator(
+ value: 0.0,
+ backgroundColor: Colors.orange,
+ ),
+ );
+ }
+
+ return new Container(
+ child: new LinearProgressIndicator(
+ value: _activityProgress,
+ backgroundColor: Colors.orange,
+ ),
+ );
+ }
+}
diff --git a/lib/components/animations.dart b/lib/components/animations.dart
new file mode 100644
index 0000000..d860418
--- /dev/null
+++ b/lib/components/animations.dart
@@ -0,0 +1,196 @@
+import 'package:flutter/material.dart';
+import 'package:maui/loca.dart';
+import 'package:maui/quack/post_comments.dart';
+import 'package:nima/nima_actor.dart';
+import 'package:maui/components/drawing_wrapper.dart';
+import 'dart:ui';
+
+class Animations extends StatefulWidget {
+ @override
+ AnimationsState createState() {
+ return new AnimationsState();
+ }
+}
+
+class AnimationsState extends State {
+ List emotions = ["happy", "joy", "hello", "sad", "bored", "welcome with hello"];
+ String emotion, _animationName;
+ int count;
+ PageController _pageController;
+ int _currentPageIndex;
+ bool paused = false;
+
+ @override
+ void initState() {
+ count = 0;
+ _pageController = PageController(initialPage: 0);
+ _currentPageIndex = 0;
+ _animationName = emotions[0];
+ }
+
+ @override
+ void dispose() {
+ _pageController.dispose();
+ super.dispose();
+ }
+
+ void _complete(bool mounted) {
+ if (mounted) {
+ setState(() {
+ paused = true;
+ _animationName = null;
+ });
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ // TODO: implement build
+ print("Initial An imation - ${emotions[0]}");
+ MediaQueryData media = MediaQuery.of(context);
+
+ var size = media.size;
+ return Stack(
+ children: [
+ new BackdropFilter(
+ filter: new ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
+ child: new Container(
+ decoration:
+ new BoxDecoration(color: Colors.grey[200].withOpacity(0.1)),
+ ),
+ ),
+ Column(
+ children: [
+ Container(
+ height: size.height > size.width
+ ? size.height * 0.88
+ : size.height * 0.70,
+ width: double.maxFinite - size.width * 0.1,
+ child: Stack(
+ children: [
+ PageView.builder(
+ controller: _pageController,
+ scrollDirection: Axis.horizontal,
+ itemCount: emotions.length,
+ itemBuilder: (context, index) => Container(
+ height: double.maxFinite - size.height * 0.1,
+ width: double.maxFinite - size.height * 0.4,
+ //color: Colors.red,
+ child: new NimaActor(
+ "assets/quack",
+ alignment: Alignment.center,
+ fit: BoxFit.scaleDown,
+ animation: '${emotions[count]}',
+ mixSeconds: 0.2,
+ paused: paused,
+ completed: (String animationName) {
+ _complete(mounted);
+ },
+ ),
+ ),
+ onPageChanged: (index) {
+ print('onPageChanged: $index');
+ print('OnPageChanged Emotion: ${emotions[0 + index]}');
+ setState(() {
+ count = 0 + index;
+ paused = false;
+ });
+ }),
+ Align(
+ alignment: AlignmentDirectional.topStart,
+ child: FlatButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ child: new Icon(Icons.arrow_back,
+ size: size.height * 0.05, color: Colors.white)),
+ ),
+ Align(
+ alignment: AlignmentDirectional.centerStart,
+ child: FlatButton(
+ onPressed: () async =>
+ await _pageController.previousPage(
+ duration: Duration(milliseconds: 500),
+ curve: Curves.fastOutSlowIn),
+ child: new Icon(
+ Icons.keyboard_arrow_left,
+ size: size.height * 0.08,
+ color: count == 0 ? Colors.grey : Colors.white,
+ )),
+ ),
+ Align(
+ alignment: AlignmentDirectional.centerEnd,
+ child: FlatButton(
+ onPressed: () async => await _pageController.nextPage(
+ duration: Duration(milliseconds: 500),
+ curve: Curves.fastOutSlowIn),
+ child: new Icon(
+ Icons.keyboard_arrow_right,
+ size: size.height * 0.08,
+ color: count == emotions.length - 1
+ ? Colors.grey
+ : Colors.white,
+ )),
+ ),
+ ],
+ ),
+ ),
+ new Row(
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ new Container(
+ height: size.height * 0.08,
+ width: size.width * 0.35,
+ decoration: BoxDecoration(
+ shape: BoxShape.rectangle,
+ borderRadius: new BorderRadius.circular(12.0),
+ color: Colors.amber,
+ ),
+ child: new FlatButton(
+ onPressed: () {
+ Navigator.of(context).push(
+ new MaterialPageRoute(
+ builder: (BuildContext context) =>
+ DrawingWrapper(
+ activityId: 'lion_roar',
+ template: null,
+ )),
+ );
+ },
+ child: new Text(
+ Loca.of(context).draw,
+ style: new TextStyle(
+ fontSize: 40.0,
+ color: Colors.white,
+ fontWeight: FontWeight.bold),
+ ))),
+ new Container(
+ height: size.height * 0.08,
+ width: size.width * 0.35,
+ decoration: BoxDecoration(
+ shape: BoxShape.rectangle,
+ borderRadius: new BorderRadius.circular(12.0),
+ color: Colors.amber,
+ ),
+ child: new FlatButton(
+ onPressed: () {
+ Navigator.of(context).push(
+ new MaterialPageRoute(
+ builder: (BuildContext context) => PostComments()),
+ );
+ },
+ child: new Text(
+ Loca.of(context).post,
+ style: new TextStyle(
+ fontSize: 40.0,
+ color: Colors.white,
+ fontWeight: FontWeight.bold),
+ )))
+ ]),
+ ],
+ ),
+ ],
+ );
+ }
+}
diff --git a/lib/components/article_page.dart b/lib/components/article_page.dart
index 83f29b1..f871f7f 100644
--- a/lib/components/article_page.dart
+++ b/lib/components/article_page.dart
@@ -1,29 +1,33 @@
+import 'dart:async';
+import 'package:maui/db/entity/card_progress.dart';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:maui/db/entity/user.dart';
+import 'package:maui/repos/card_progress_repo.dart';
+import 'package:maui/quack/card_detail.dart';
import 'package:maui/state/app_state_container.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:flutter/material.dart';
+import 'package:video_player/video_player.dart';
+import 'dart:ui' as ui;
enum PlayerState { playing, paused, stopped }
class ArticlePage extends StatefulWidget {
final String articleId;
final String name;
- final String topicId;
- final String video;
final String audio;
- final String image;
+ final String header;
final String text;
- final int serial;
+ PageController page;
ArticlePage({
Key key,
@required this.articleId,
@required this.name,
- @required this.topicId,
- @required this.video,
@required this.audio,
- @required this.image,
+ @required this.header,
@required this.text,
- @required this.serial,
+ this.page,
}) : super(key: key);
@override
@@ -32,13 +36,68 @@ class ArticlePage extends StatefulWidget {
}
}
-class _ArticlePageState extends State {
+class _ArticlePageState extends State
+ with SingleTickerProviderStateMixin {
PlayerState playerState;
+ VideoPlayerController _controller;
+ bool _isPlaying = false;
+ var expheight;
+ var _clicked = false;
+ TabController tabController;
+
+ User user;
+ bool _isLoading = true;
+ bool showBottomBar = true;
+ bool _afterPress = false;
+ var top = 0.0;
@override
void initState() {
- playerState == PlayerState.stopped;
+ playerState = PlayerState.paused;
+ //articleProgressTracker();
super.initState();
+ tabController = new TabController(length: 3, vsync: this);
+ _isLoading = false;
+ _controller = VideoPlayerController.asset("assets/demo_video/video.mp4")
+ ..addListener(() {
+ final bool isPlaying = _controller.value.isPlaying;
+ if (isPlaying != _isPlaying) {
+ setState(() {
+ _isPlaying = isPlaying;
+ _afterPress = true;
+ if (_clicked == true) {
+ AppStateContainer.of(context).pauseArticleAudio();
+ _clicked = false;
+ }
+ });
+ }
+ })
+ ..initialize().then((_) {
+ // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
+ setState(() {
+// _controller.pause();
+ });
+ });
+ }
+
+ _forwardButtonBehaviour() {
+ widget.page.nextPage(
+ duration: new Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
+ }
+
+ void _backwardButtonBehaviour() {
+ widget.page.previousPage(
+ duration: new Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
+ }
+
+ void articleProgressTracker() async {
+ WidgetsBinding.instance.addPostFrameCallback((_) async {
+ user = AppStateContainer.of(context).state.loggedInUser;
+ await CardProgressRepo().upsert(CardProgress(
+ userId: user.id,
+ cardId: widget.articleId,
+ updatedAt: DateTime.now()));
+ });
}
void onComplete() {
@@ -49,46 +108,67 @@ class _ArticlePageState extends State {
@override
void deactivate() {
AppStateContainer.of(_ctx).stopArticleAudio();
+ _controller.dispose();
super.deactivate();
}
+ @override
+ void dispose() {
+ // TODO: implement dispose
+ _controller.dispose();
+ tabController.dispose();
+ super.dispose();
+ }
+
+ var _scrollController =
+ new ScrollController(initialScrollOffset: 0.0, keepScrollOffset: true);
+
+ Future _getImage() {
+ Image image = new Image.asset("${widget.header}");
+ Completer completer = new Completer();
+ image.image.resolve(new ImageConfiguration()).addListener(
+ (ImageInfo info, bool _) => completer.complete(info.image));
+ return completer.future;
+ }
+
BuildContext _ctx;
@override
Widget build(BuildContext context) {
_ctx = context;
- return new LayoutBuilder(builder: (context, constraints) {
- print("Size ${constraints.maxHeight} , ${constraints.maxWidth}");
- return Material(
- type: MaterialType.transparency,
- child: new Container(
- width: constraints.maxWidth,
- height: constraints.maxHeight,
- decoration: new BoxDecoration(
- shape: BoxShape.rectangle,
- color: Colors.white,
- borderRadius: new BorderRadius.all(new Radius.circular(20.0)),
- ),
- child: new Flex(
- direction: Axis.vertical,
- children: [
- Expanded(
- flex: 6,
- child: new Container(
- width: constraints.maxWidth * 0.992,
- height: constraints.maxHeight * 0.732,
- color: Colors.red,
- child: FittedBox(
- child: new Image.asset(
- widget.image,
- fit: BoxFit.cover,
+ MediaQueryData media = MediaQuery.of(context);
+ var size = media.size;
+ if (_isLoading) {
+ return new Center(
+ child: new SizedBox(
+ width: 20.0,
+ height: 20.0,
+ child: new CircularProgressIndicator(),
+ ));
+ }
+ return Scaffold(
+ bottomNavigationBar: Container(
+ height: showBottomBar ? size.height * 0.1 : 0.0,
+ child: new Material(
+ color: Colors.orange,
+ child: new Row(
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Padding(
+ padding: const EdgeInsets.all(10.0),
+ child: new Tab(
+ child: new GestureDetector(
+ onTap: () => _backwardButtonBehaviour(),
+ child: new Icon(
+ Icons.arrow_back,
+ size: 70.0,
+ semanticLabel: "previous",
+ ),
),
),
),
- ),
- widget.audio != null
- ? Expanded(
- flex: 1,
- child: new RawMaterialButton(
+ widget.audio != null
+ ? new RawMaterialButton(
shape: new CircleBorder(),
fillColor: Colors.white,
splashColor: Colors.teal,
@@ -97,43 +177,245 @@ class _ArticlePageState extends State {
highlightElevation: 5.0,
onPressed: () {
if (playerState == PlayerState.stopped ||
- playerState == PlayerState.playing) {
+ playerState == PlayerState.playing &&
+ _clicked == true) {
AppStateContainer.of(context).pauseArticleAudio();
setState(() {
playerState = PlayerState.paused;
+ _clicked = false;
+// _controller.pause();
});
} else {
- AppStateContainer
- .of(context)
+ AppStateContainer.of(context)
.playArticleAudio(widget.audio, onComplete);
setState(() {
playerState = PlayerState.playing;
+ _controller.pause();
+ _clicked = true;
+ print("this is audio click $_clicked");
});
}
},
child: new Icon(
(playerState == PlayerState.stopped ||
- playerState == PlayerState.playing)
+ playerState == PlayerState.playing &&
+ _clicked == true)
? Icons.pause
: Icons.play_arrow,
color: Colors.purple,
- size: 40.0,
+ size: 70.0,
),
+ )
+ : new Container(),
+ // tab audio
+ Padding(
+ padding: const EdgeInsets.all(10.0),
+ child: new Tab(
+ child: new GestureDetector(
+ onTap: () => _forwardButtonBehaviour(),
+ child: new Icon(
+ Icons.arrow_forward,
+ semanticLabel: "previous",
+ size: 70.0,
),
- )
- : new Container(),
- Expanded(
- flex: 3,
- child: new Container(
- color: Colors.grey,
- child: new Markdown(
- data: widget.text,
- )),
- ),
- ],
+ ),
+ ),
+ ),
+ ],
+ ),
),
),
- );
- });
+ body: new FutureBuilder(
+ future: _getImage(),
+ builder: (BuildContext context, AsyncSnapshot snapshot) {
+ if (snapshot.hasData) {
+ ui.Image image = snapshot.data;
+
+ expheight = image.height;
+
+ return new NotificationListener(
+ onNotification: (v) {
+ if (v is ScrollUpdateNotification) {
+ print("top is her ${_scrollController.offset} ");
+ print("top is her ${size.height / 2.5} ");
+ if (_afterPress == true) {
+ if (_scrollController.offset >= size.height / 2.5) {
+ setState(() {
+ _controller.pause();
+ });
+ }
+ if (_scrollController.offset == 0.0) {
+ setState(() {
+ _controller.play();
+ AppStateContainer.of(context).pauseArticleAudio();
+ setState(() {
+ playerState = PlayerState.paused;
+ });
+ });
+ }
+ }
+ }
+ },
+ child: Stack(
+ children: [
+ new CustomScrollView(
+ controller: _scrollController,
+ slivers: [
+ new SliverAppBar(
+ titleSpacing: 0.0,
+ elevation: 0.0,
+ backgroundColor: Colors.transparent,
+ automaticallyImplyLeading: false,
+ expandedHeight: double.parse("${image.height}"),
+ pinned: false,
+ floating: false,
+ // snap: true,
+
+ flexibleSpace: new FlexibleSpaceBar(
+ centerTitle: true,
+ background: new Stack(
+ fit: StackFit.expand,
+ children: [
+ !widget.header.endsWith('.mp4')
+ ? new Image.asset(
+ "${widget.header}",
+ fit: BoxFit.cover,
+ )
+ : Expanded(
+ child: Stack(children: [
+ Container(
+ height: media.size.height,
+ width: media.size.width,
+ color: Colors.white,
+ ),
+ GestureDetector(
+ onTap: _controller.value.isPlaying
+ ? _controller.pause
+ : _controller.play,
+ child: Center(
+ child: _controller
+ .value.initialized
+ ? Padding(
+ padding:
+ const EdgeInsets.all(
+ 10.0),
+ child: Center(
+ child: Container(
+ height: media
+ .size.height /
+ 2,
+ width:
+ media.size.width /
+ 1.5,
+ child: AspectRatio(
+ aspectRatio: 16 / 9,
+ child: VideoPlayer(
+ _controller),
+ ),
+ ),
+ ),
+ )
+ : Padding(
+ padding:
+ const EdgeInsets.all(
+ 10.0),
+ child: Center(
+ child: Container(
+ height: media.size
+ .height /
+ 2,
+ width: media.size
+ .width /
+ 1.5,
+ child: VideoPlayer(
+ _controller)),
+ ),
+ ),
+ ),
+ ),
+ GestureDetector(
+ onTap: _controller.value.isPlaying
+ ? _controller.pause
+ : _controller.play,
+ child: Center(
+ child: new Container(
+ height: 60.0,
+ width: 60.0,
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ ),
+ child: new Center(
+ child: Icon(
+ _controller.value.isPlaying
+ ? Icons.pause
+ : Icons.play_arrow,
+ color: Colors.white,
+ size: 100.0,
+ ),
+ ),
+ ),
+ ),
+ ),
+ ]),
+ ),
+ const DecoratedBox(
+ decoration: BoxDecoration(
+ gradient: LinearGradient(
+ begin: Alignment(0.0, -1.0),
+ end: Alignment(0.0, -0.4),
+ colors: [
+ Color(0x60000000),
+ Color(0x00000000)
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ new SliverList(
+ delegate: new SliverChildListDelegate([
+ Container(
+ decoration: new BoxDecoration(
+ color: Colors.transparent,
+ borderRadius: const BorderRadius.only(
+ topLeft: const Radius.circular(30.0),
+ topRight: const Radius.circular(40.0)),
+ ),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ MarkdownBody(
+ data: "${widget.text}",
+ styleSheet: new MarkdownStyleSheet(
+ p: new TextStyle(
+ fontSize: 40.0,
+ color: Colors.black)),
+ onTapLink: (e) => Navigator.of(_ctx)
+ .pushReplacement(
+ new MaterialPageRoute(
+ builder:
+ (BuildContext _ctx) =>
+ new CardDetail(
+ card: QuackCard(
+ id: 'fox',
+ title: 'fox'),
+ ))),
+ ),
+ ],
+ )),
+ ]),
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+ } else {
+ return Container();
+ }
+ },
+ ));
}
}
diff --git a/lib/components/article_progress_tracker.dart b/lib/components/article_progress_tracker.dart
new file mode 100644
index 0000000..acd33fe
--- /dev/null
+++ b/lib/components/article_progress_tracker.dart
@@ -0,0 +1,55 @@
+import 'package:flutter/material.dart';
+import 'package:maui/db/entity/user.dart';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:maui/repos/card_progress_repo.dart';
+import 'package:maui/state/app_state_container.dart';
+
+class ArticleProgressTracker extends StatefulWidget {
+ final String topicId;
+
+ ArticleProgressTracker({Key key, this.topicId}) : super(key: key);
+
+ @override
+ State createState() => new ArticleProgressTrackerState();
+}
+
+class ArticleProgressTrackerState extends State {
+ double _articleProgress;
+ bool _isLoading = true;
+ User user;
+
+ @override
+ void initState() {
+ super.initState();
+ articleProgressTracker();
+ }
+
+ void articleProgressTracker() async {
+ WidgetsBinding.instance.addPostFrameCallback((_) async {
+ user = AppStateContainer.of(context).state.loggedInUser;
+ _articleProgress = await CardProgressRepo()
+ .getProgressStatusByCollectionAndTypeAndUserId(
+ widget.topicId, CardType.knowledge, user.id);
+ setState(() => _isLoading = false);
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ if (_isLoading == true) {
+ return new Container(
+ child: new LinearProgressIndicator(
+ value: null,
+ backgroundColor: Colors.green,
+ ),
+ );
+ }
+
+ return new Container(
+ child: new LinearProgressIndicator(
+ value: _articleProgress,
+ backgroundColor: Colors.green,
+ ),
+ );
+ }
+}
diff --git a/lib/components/camera.dart b/lib/components/camera.dart
index 23d8620..b4538c9 100644
--- a/lib/components/camera.dart
+++ b/lib/components/camera.dart
@@ -1,216 +1,92 @@
import 'dart:async';
-
import 'dart:io';
-import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
+// import 'package:camera/camera.dart';
import 'package:flutter/services.dart';
+import 'package:maui/db/entity/user.dart';
+import 'package:maui/repos/user_repo.dart';
import 'package:maui/screens/login_screen.dart';
-import 'package:path_provider/path_provider.dart';
+import 'package:maui/state/app_state_container.dart';
import 'package:maui/loca.dart';
+import 'package:native_device_orientation/native_device_orientation.dart';
+
+import 'package:camera/camera.dart';
+
+import 'package:image/image.dart' as Img;
+import 'package:path_provider/path_provider.dart';
+
String imagePathStore;
String userNameStore;
+String bigImagePath, tempFilePath;
+String filePath;
+double side;
class CameraScreen extends StatefulWidget {
- @override
- _CameraScreenState createState() {
- return new _CameraScreenState();
+ bool editMode = false;
+ CameraScreen(bool edit) {
+ editMode = edit;
}
+ @override
+ _CameraControllerState createState() => new _CameraControllerState();
}
-class _CameraScreenState extends State {
- List cameras;
- CameraController controller;
- String imagePath = '';
- String _deviceId;
+List cameras;
- final GlobalKey _scaffoldKey = new GlobalKey();
- bool onTakePicture = true, onTakePicture1 = false;
- Orientation ornt;
- int mode = -1;
- @override
- Widget build(BuildContext context) {
- final Orientation orientation = MediaQuery.of(context).orientation;
- final bool isLandscape = orientation == Orientation.landscape;
-
- return Scaffold(
- backgroundColor: Colors.black87,
- key: _scaffoldKey,
- body: Stack(
- alignment: AlignmentDirectional.bottomCenter,
- children: [
- onTakePicture
- ? new Center(
- child: RotatedBox(
- quarterTurns: 1, child: _cameraPreviewWidget()),
- )
- : Container(
- child: imagePath != ''
- ? Center(
- child: onTakePicture1
- ? null
- : Image.file(new File(imagePath)))
- : new Container()),
- Container(
- color: Colors.black87,
- height: 120.0,
- child: Center(child: _captureControlRowWidget())),
- ],
- ));
+class _CameraControllerState extends State
+ with SingleTickerProviderStateMixin {
+ final GlobalKey _scaffoldKey = GlobalKey();
+ CameraController controller;
+ String imagePath;
+ Orientation orientation;
+ void logError(String code, String message) =>
+ print('Error: $code\nError Message: $message');
+ void _showCameraException(CameraException e) {
+ logError(e.code, e.description);
+ showInSnackBar('Error: ${e.code}\n${e.description}');
}
- /// Display the preview from the camera (or a message if the preview is not available).
- Widget _cameraPreviewWidget() {
- if (controller == null || !controller.value.isInitialized) {
- return RotatedBox(
- quarterTurns: -1,
- child: Text(
- Loca.of(context).tapACamera,
- style: const TextStyle(
- color: Colors.white,
- fontSize: 24.0,
- fontWeight: FontWeight.w900,
- ),
- ),
- );
- } else {
- return new Container(
- height: double.infinity,
- width: double.infinity,
- //aspectRatio: 1.6, //controller.value.aspectRatio,
- child: new CameraPreview(controller),
- );
- }
+ void showInSnackBar(String message) {
+ _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(message)));
}
- /// Display the control bar with buttons to take pictures and record videos.
- Widget _captureControlRowWidget() {
- if (onTakePicture)
- return Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- CircleAvatar(
- radius: 30.0,
- backgroundColor: Colors.white,
- child: Center(
- child: Transform.rotate(
- angle: .8,
- child: new IconButton(
- iconSize: 30.0,
- splashColor: Colors.white,
- icon: const Icon(
- Icons.add,
- ),
- color: Colors.blue,
- onPressed: () {
- Navigator.of(context).pop();
- imagePathStore = null;
- }),
- ),
- ),
- ),
- CircleAvatar(
- radius: 30.0,
- backgroundColor: Colors.white,
- child: Center(
- child: new IconButton(
- iconSize: 30.0,
- splashColor: Colors.white,
- icon: const Icon(
- Icons.camera_alt,
- ),
- color: Colors.blue,
- onPressed: controller != null &&
- controller.value.isInitialized &&
- !controller.value.isRecordingVideo
- ? onTakePictureButtonPressed
- : null,
- ),
- ),
- ),
- ],
- );
- else if (onTakePicture1) {
- return new Container(
- color: Colors.black12,
- );
- } else
- return Container(
- height: 120.0,
- color: Colors.black54,
- child: new Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- mainAxisSize: MainAxisSize.max,
- children: [
- CircleAvatar(
- backgroundColor: Colors.white,
- radius: 30.0,
- child: Transform.rotate(
- angle: .80,
- child: new IconButton(
- color: Colors.black54,
- iconSize: 30.0,
- onPressed: () {
- setState(() {
- imagePathStore = '';
- SystemChrome.setPreferredOrientations([
- DeviceOrientation.portraitUp,
- ]);
- onTakePicture = true;
- onTakePicture1 = true;
- });
- },
- icon: Icon(Icons.add),
- ),
- )),
- CircleAvatar(
- backgroundColor: Colors.white,
- radius: 30.0,
- child: Center(
- child: new IconButton(
- color: Colors.black54,
- iconSize: 30.0,
- onPressed: () {
- imagePathStore = imagePath;
- Navigator.of(context).pop();
- // Navigator.pushReplacementNamed(context, '/login_screen');
- // Navigator.push(
- // context,
- // MaterialPageRoute(builder: (context) => LoginScreen()),
- // );
- //Navigator.of(context).pop();
- },
- icon: Icon(Icons.done),
- ),
- )),
- ],
- ),
- );
+ String timestamp() => DateTime.now().millisecondsSinceEpoch.toString();
+
+ @override
+ initState() {
+ // SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
+
+ _initCamera();
+ super.initState();
}
- String timestamp() => new DateTime.now().millisecondsSinceEpoch.toString();
+ _initCamera() async {
+ cameras = await availableCameras();
+ controller = new CameraController(cameras[1], ResolutionPreset.medium);
+ controller.addListener(() {
+ if (mounted) setState(() {});
+ if (controller.value.hasError) {
+ showInSnackBar('Camera error ${controller.value.errorDescription}');
+ }
+ });
- void showInSnackBar(String message) {
- _scaffoldKey.currentState
- .showSnackBar(new SnackBar(content: new Text(message)));
+ try {
+ await controller.initialize();
+ } on CameraException catch (e) {
+ _showCameraException(e);
+ }
}
void onTakePictureButtonPressed() {
- SystemChrome.setPreferredOrientations([]);
- setState(() {
- onTakePicture1 = true;
- onTakePicture = false;
- });
- takePicture().then((String filePath) async {
+ takePicture().then((String filePath) {
if (mounted) {
- Future.delayed(Duration(milliseconds: 300), () {
- setState(() {
- imagePath = filePath;
- imagePathStore = imagePath;
- onTakePicture = false;
- onTakePicture1 = false;
- });
+ print("image");
+ setState(() {
+ imagePath = filePath;
+ imagePathStore = imagePath;
});
+
+ if (filePath == null) showInSnackBar('Picture saved to $filePath');
}
});
}
@@ -222,9 +98,8 @@ class _CameraScreenState extends State {
}
final Directory extDir = await getApplicationDocumentsDirectory();
final String dirPath = '${extDir.path}/Pictures/flutter_test';
- await new Directory(dirPath).create(recursive: true);
- final String filePath = '$dirPath/${timestamp()}.jpg';
-
+ await Directory(dirPath).create(recursive: true);
+ filePath = '$dirPath/${timestamp()}.jpg';
if (controller.value.isTakingPicture) {
// A capture is already pending, do nothing.
return null;
@@ -239,51 +114,570 @@ class _CameraScreenState extends State {
return filePath;
}
- void _showCameraException(CameraException e) {
- logError(e.code, e.description);
- showInSnackBar('Error: ${e.code}\n${e.description}');
- }
-
- @override
- void initState() {
- super.initState();
- initCamera();
+ void _changeState(User user) async {
+ if (imagePathStore != user.image && user.image != null) {
+ var user1 = user;
+ compressImage(imagePathStore).then((k) {
+ user1.image = k;
+ UserRepo().update(user1);
+ });
+ }
}
@override
void dispose() {
SystemChrome.setPreferredOrientations([]);
+ controller.dispose();
super.dispose();
}
- void initCamera() async {
- SystemChrome.setPreferredOrientations([
- DeviceOrientation.portraitUp,
- ]);
- cameras = await availableCameras();
- print("print camera lenafa$cameras");
- controller = new CameraController(cameras[1], ResolutionPreset.medium);
+ Widget __buildBottomIcons(User user) {
+ return Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: [
+ RawMaterialButton(
+ onPressed: () {
+ if (imagePath == null)
+ Navigator.of(context).pop();
+ else {
+ setState(() {
+ imagePath = null;
+ });
+ }
+ },
+ child: Icon(
+ Icons.close,
+ size: 30.0,
+ color: Colors.white,
+ ),
+ elevation: 10.0,
+ splashColor: Colors.white,
+ shape: CircleBorder(
+ side: BorderSide(width: 2.0, color: Colors.white24),
+ ),
+ constraints: BoxConstraints.tight(Size(60.0, 60.0)),
+ ),
+ imagePath == null
+ ? RawMaterialButton(
+ onPressed: () {
+ onTakePictureButtonPressed();
+ imagePathStore = imagePath;
+ },
+ child: Icon(
+ Icons.camera,
+ size: 40.0,
+ color: Colors.white,
+ ),
+ elevation: 10.0,
+ splashColor: Colors.white,
+ shape: CircleBorder(
+ side: BorderSide(width: 2.0, color: Colors.white24),
+ ),
+ constraints: BoxConstraints.tight(Size(70.0, 70.0)),
+ )
+ : RawMaterialButton(
+ onPressed: () {
+ Navigator.of(context).pop();
+ if (widget.editMode == true) {
+ _changeState(user);
+ }
+ },
+ child: Icon(
+ Icons.done,
+ size: 40.0,
+ color: Colors.white,
+ ),
+ elevation: 10.0,
+ splashColor: Colors.white,
+ shape: CircleBorder(
+ side: BorderSide(width: 2.0, color: Colors.white24),
+ ),
+ constraints: BoxConstraints.tight(Size(70.0, 70.0)),
+ ),
+ ],
+ );
+ }
- // If the controller is updated then update the UI.
- controller.addListener(() {
- if (mounted) setState(() {});
- if (controller.value.hasError) {
- showInSnackBar('Camera error ${controller.value.errorDescription}');
- }
- });
+ int turns;
+ Widget _imageViewer() {
+ return Stack(
+ alignment: AlignmentDirectional.center,
+ children: [
+ AspectRatio(
+ aspectRatio: 1.0,
+ child: Image.file(
+ File(imagePath),
+ fit: BoxFit.cover,
+ ),
+ )
+ ],
+ );
+ }
- try {
- await controller.initialize();
- } on CameraException catch (e) {
- _showCameraException(e);
+ Widget cameraActivity() {
+ if (imagePath == null) {
+ return AspectRatio(
+ aspectRatio: controller.value.aspectRatio,
+ child: NativeDeviceOrientationReader(
+ useSensor: true,
+ builder: (context) {
+ NativeDeviceOrientation orientation =
+ NativeDeviceOrientationReader.orientation(context);
+ // print('orientation:: $orientation');
+ switch (orientation) {
+ case NativeDeviceOrientation.landscapeLeft:
+ turns = 2;
+ break;
+ case NativeDeviceOrientation.landscapeRight:
+ turns = 4;
+ break;
+ case NativeDeviceOrientation.portraitDown:
+ turns = 1;
+ break;
+ default:
+ turns = 3;
+ break;
+ }
+ return RotatedBox(
+ quarterTurns: turns, child: CameraPreview(controller));
+ },
+ ));
+ // });
+ } else if (imagePath != null) {
+ return _imageViewer();
}
+ }
- if (mounted) {
- setState(() {});
+ @override
+ Widget build(BuildContext context) {
+ var mediaQuery = MediaQuery.of(context);
+ var user = AppStateContainer.of(context).state.loggedInUser;
+ side = mediaQuery.size.width * .05;
+ if (controller == null || !controller.value.isInitialized)
+ return Material(
+ child: Center(
+ child: new Container(
+ height: 60.0,
+ width: 300.0,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.all(Radius.circular(10.0)),
+ color: Colors.white),
+ // color: Colors.white,
+ child: new Stack(
+ alignment: AlignmentDirectional.center,
+ children: [
+ new Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ new CircularProgressIndicator(
+ backgroundColor: Colors.redAccent,
+ ),
+ new SizedBox(
+ width: 20.0,
+ ),
+ new Text(Loca.of(context).pleaseWait),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ else {
+ return new Material(
+ color: Colors.transparent,
+ borderRadius: BorderRadius.only(),
+ child: Container(
+ decoration: BoxDecoration(
+ border: Border(
+ left: BorderSide(width: side),
+ right: BorderSide(width: side)),
+ color: Colors.black),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: [
+ SizedBox(
+ height: mediaQuery.size.height * .85,
+ child: cameraActivity(),
+ width: mediaQuery.size.width * .80,
+ ),
+ Padding(
+ padding: const EdgeInsets.only(top: 10.0),
+ child: SizedBox(
+ height: mediaQuery.size.height * .10,
+ width: mediaQuery.size.width * .5,
+ child: Column(
+ children: [__buildBottomIcons(user)],
+ )),
+ )
+ ],
+ ),
+ ));
}
- print("contloafasfsa ${controller.value.aspectRatio}");
}
}
-void logError(String code, String message) =>
- print('Error: $code\nError Message: $message');
+// class CameraScreen extends StatefulWidget {
+// CameraScreen(this.editImage);
+// bool editImage = false;
+// @override
+// _CameraScreenState createState() {
+// return new _CameraScreenState();
+// }
+// }
+
+// class _CameraScreenState extends State {
+// List cameras;
+// CameraController controller;
+// String imagePath = '';
+// String _deviceId;
+// final GlobalKey _scaffoldKey = new GlobalKey();
+// bool onTakePicture = true, onTakePicture1 = false;
+// Orientation ornt;
+// int mode = -1;
+
+// @override
+// void didUpdateWidget(CameraScreen oldwidget) {
+// super.didUpdateWidget(oldwidget);
+// }
+
+// @override
+// Widget build(BuildContext context) {
+// final Orientation orientation = MediaQuery.of(context).orientation;
+// final bool isLandscape = orientation == Orientation.landscape;
+// var user = AppStateContainer.of(context).state.loggedInUser;
+
+// print("image path checking wether its working or not... $imagePath");
+// return Scaffold(
+// backgroundColor: Colors.black87,
+// key: _scaffoldKey,
+// body: Stack(
+// alignment: AlignmentDirectional.bottomCenter,
+// children: [
+// onTakePicture
+// ? new Center(
+// child: RotatedBox(
+// quarterTurns: 1, child: _cameraPreviewWidget()),
+// )
+// : Container(
+// child: bigImagePath != ''
+// ? Center(
+// child: onTakePicture1
+// ? null
+// : Image.file(new File(imagePath)))
+// : new Container()),
+// Container(
+// color: Colors.black87,
+// height: 120.0,
+// child: Center(child: _captureControlRowWidget(user))),
+// ],
+// ));
+// }
+
+// /// Display the preview from the camera (or a message if the preview is not available).
+// Widget _cameraPreviewWidget() {
+// if (controller == null || !controller.value.isInitialized) {
+// return RotatedBox(
+// quarterTurns: -1,
+// child: Text(
+// Loca.of(context).tapACamera,
+// style: const TextStyle(
+// color: Colors.white,
+// fontSize: 24.0,
+// fontWeight: FontWeight.w900,
+// ),
+// ),
+// );
+// } else {
+// return new Container(
+// height: double.infinity,
+// width: double.infinity,
+// //aspectRatio: 1.6, //controller.value.aspectRatio,
+// child: new CameraPreview(controller),
+// );
+// }
+// }
+
+// /// Display the control bar with buttons to take pictures and record videos.
+// Widget _captureControlRowWidget(User user) {
+// if (onTakePicture)
+// return Row(
+// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+// children: [
+// CircleAvatar(
+// radius: 30.0,
+// backgroundColor: Colors.white,
+// child: Center(
+// child: Transform.rotate(
+// angle: .8,
+// child: new IconButton(
+// iconSize: 30.0,
+// splashColor: Colors.white,
+// icon: const Icon(
+// Icons.add,
+// ),
+// color: Colors.blue,
+// onPressed: () {
+// Navigator.of(context).pop();
+// imagePathStore = null;
+// }),
+// ),
+// ),
+// ),
+// CircleAvatar(
+// radius: 30.0,
+// backgroundColor: Colors.white,
+// child: Center(
+// child: new IconButton(
+// iconSize: 30.0,
+// splashColor: Colors.white,
+// icon: const Icon(
+// Icons.camera_alt,
+// ),
+// color: Colors.blue,
+// onPressed: controller != null &&
+// controller.value.isInitialized &&
+// !controller.value.isRecordingVideo
+// ? onTakePictureButtonPressed
+// : null,
+// ),
+// ),
+// ),
+// ],
+// );
+// else if (onTakePicture1) {
+// return new Column(
+// mainAxisAlignment: MainAxisAlignment.center,
+// children: [
+// Row(
+// crossAxisAlignment: CrossAxisAlignment.center,
+// children: [
+// CircularProgressIndicator(),
+// SizedBox(
+// height: 20.0,
+// width: 20.0,
+// )
+// ],
+// )
+// ],
+// );
+// } else
+// return Container(
+// height: 120.0,
+// color: Colors.black54,
+// child: new Row(
+// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+// mainAxisSize: MainAxisSize.max,
+// children: [
+// CircleAvatar(
+// backgroundColor: Colors.white,
+// radius: 30.0,
+// child: Transform.rotate(
+// angle: .80,
+// child: new IconButton(
+// color: Colors.black54,
+// iconSize: 30.0,
+// onPressed: () {
+// setState(() {
+// imagePathStore = '';
+// SystemChrome.setPreferredOrientations([
+// DeviceOrientation.portraitUp,
+// ]);
+// onTakePicture = true;
+// onTakePicture1 = true;
+// });
+// },
+// icon: Icon(Icons.add),
+// ),
+// )),
+// CircleAvatar(
+// backgroundColor: Colors.white,
+// radius: 30.0,
+// child: Center(
+// child: new IconButton(
+// color: Colors.black54,
+// iconSize: 30.0,
+// onPressed: () {
+// if (widget.editImage == true) {
+// print("object is fine ${widget.editImage}");
+// _changeState(user);
+// }
+// imagePathStore = imagePath;
+
+// Navigator.of(context).pop();
+// },
+// icon: Icon(Icons.done),
+// ),
+// )),
+// ],
+// ),
+// );
+// }
+
+// String timestamp() => new DateTime.now().millisecondsSinceEpoch.toString();
+
+// void showInSnackBar(String message) {
+// _scaffoldKey.currentState
+// .showSnackBar(new SnackBar(content: new Text(message)));
+// }
+
+// // void onTakenPicture() {
+// // SystemChrome.setPreferredOrientations([]);
+// // setState(() {
+// // onTakePicture1 = true;
+// // onTakePicture = false;
+// // });
+// // takePicture().then((String bigFilePath) async {
+// // String filePath;
+// // final bigImage = Img.decodeImage(new File(bigFilePath).readAsBytesSync());
+// // // int ht = bigImage.height;
+// // // int wd = bigImage.width;
+// // // int reducedHt = ((ht - wd)/2).toInt();
+// // // int reducedWd = 0;
+// // // print("Values of Reduced height and Width - $reducedHt.........$reducedWd");
+// // // final croppedImage = bigImage.width > bigImage.height
+// // // ? Img.copyCrop(
+// // // bigImage,
+// // // ((bigImage.height - bigImage.width)/2).toInt(),
+// // // ((bigImage.height - bigImage.width)/2).toInt(),
+// // // bigImage.height,
+// // // bigImage.width)
+// // // : Img.copyCrop(
+// // // bigImage,
+// // // ((bigImage.height - bigImage.width)/2).toInt(),
+// // // ((bigImage.height - bigImage.width)/2).toInt(),
+// // // bigImage.width,
+// // // bigImage.height);
+// // new File(bigFilePath)..writeAsBytesSync(Img.encodePng(bigImage));
+
+// // if (mounted) {
+// // setState(() {
+// // bigImagePath = bigFilePath;
+// // imagePath = bigImagePath;
+// // onTakePicture = false;
+// // onTakePicture1 = false;
+// // });
+// // onTakePictureButtonPressed();
+// // // Resize the image to a 120x? thumbnail (maintaining the aspect ratio).
+// // // final thumbnail = Img.copyResize(bigImage, 64);
+
+// // // // // Save the thumbnail as a PNG.
+// // // new File(imagePath)..writeAsBytesSync(Img.encodePng(thumbnail));
+// // // setState(() {
+// // // // imagePath = bigFilePath;
+// // // imagePathStore = imagePath;
+// // // });
+// // }
+// // });
+// // }
+
+// void onTakePictureButtonPressed() {
+// SystemChrome.setPreferredOrientations([]);
+// setState(() {
+// onTakePicture1 = true;
+// onTakePicture = false;
+// });
+// takePicture().then((String filePath) async {
+// // final image = Img.decodeImage(new File(filePath).readAsBytesSync());
+
+// // // Resize the image to a 120x? thumbnail (maintaining the aspect ratio).
+// // final thumbnail = Img.copyResize(image, 64);
+
+// // // Save the thumbnail as a PNG.
+// // new File(filePath)..writeAsBytesSync(Img.encodePng(thumbnail));
+
+// if (mounted) {
+// Future.delayed(Duration(milliseconds: 300), () {
+// setState(() {
+// imagePath = filePath;
+// imagePathStore = imagePath;
+// onTakePicture = false;
+// onTakePicture1 = false;
+// });
+// });
+// }
+// });
+// }
+
+// Future takePicture() async {
+// if (!controller.value.isInitialized) {
+// showInSnackBar('Error: select a camera first.');
+// return null;
+// }
+// final Directory extDir = await getApplicationDocumentsDirectory();
+// final String dirPath = '${extDir.path}/Pictures/flutter_test';
+// await new Directory(dirPath).create(recursive: true);
+// final String filePath = '$dirPath/${timestamp()}.jpg';
+
+// if (controller.value.isTakingPicture) {
+// // A capture is already pending, do nothing.
+// return null;
+// }
+
+// try {
+// await controller.takePicture(filePath);
+// } on CameraException catch (e) {
+// _showCameraException(e);
+// return null;
+// }
+// return filePath;
+// }
+
+// void _showCameraException(CameraException e) {
+// logError(e.code, e.description);
+// showInSnackBar('Error: ${e.code}\n${e.description}');
+// }
+
+// @override
+// void initState() {
+// super.initState();
+// initCamera();
+// }
+
+// @override
+// void dispose() {
+// SystemChrome.setPreferredOrientations([]);
+// controller.dispose();
+// super.dispose();
+// }
+
+// void initCamera() async {
+// SystemChrome.setPreferredOrientations([
+// DeviceOrientation.portraitUp,
+// ]);
+// cameras = await availableCameras();
+// print("print camera lenafa$cameras");
+// controller = new CameraController(cameras[1], ResolutionPreset.medium);
+
+// // If the controller is updated then update the UI.
+// controller.addListener(() {
+// if (mounted) setState(() {});
+// if (controller.value.hasError) {
+// showInSnackBar('Camera error ${controller.value.errorDescription}');
+// }
+// });
+
+// try {
+// await controller.initialize();
+// } on CameraException catch (e) {
+// _showCameraException(e);
+// }
+
+// if (mounted) {
+// setState(() {});
+// }
+// print("contloafasfsa ${controller.value.aspectRatio}");
+// }
+
+// void _changeState(User user) async {
+// if (imagePathStore != user.image && user.image != null) {
+// var user1 = user;
+// user1.image = imagePathStore;
+// UserRepo().update(user1);
+// }
+// }
+// }
+
+// void logError(String code, String message) =>
+// print('Error: $code\nError Message: $message');
diff --git a/lib/components/drawing_list.dart b/lib/components/drawing_list.dart
deleted file mode 100644
index efe78eb..0000000
--- a/lib/components/drawing_list.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-import 'dart:convert';
-import 'package:flutter/material.dart';
-import 'package:maui/repos/drawing_repo.dart';
-import 'package:maui/db/entity/drawing.dart';
-import 'package:maui/screens/drawing_screen.dart';
-import 'package:tahiti/paper.dart';
-import 'package:tahiti/activity_model.dart';
-import 'package:scoped_model/scoped_model.dart';
-
-class DrawingList extends StatelessWidget {
- final List drawings;
-
- const DrawingList({Key key, @required this.drawings}) : super(key: key);
-
- @override
- Widget build(BuildContext context) {
- return GridView.count(
- crossAxisCount: 2,
- mainAxisSpacing: 8.0,
- crossAxisSpacing: 8.0,
- children: drawings
- .map((d) => RaisedButton(
- onPressed: () => Navigator.of(context).push(
- MaterialPageRoute(
- builder: (BuildContext context) {
- return DrawingScreen(
- activityId: d.activityId,
- drawingId: d.id,
- );
- })),
- child: ScopedModel(
- model: ActivityModel.fromJson(json.decode(d.json))
- ..isInteractive = false,
- child: Paper(),
- ),
- ))
- .toList(growable: false),
- );
- }
-}
diff --git a/lib/components/drawing_wrapper.dart b/lib/components/drawing_wrapper.dart
index 02fb075..62ee4ca 100644
--- a/lib/components/drawing_wrapper.dart
+++ b/lib/components/drawing_wrapper.dart
@@ -1,23 +1,29 @@
+import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
-import 'package:maui/db/entity/drawing.dart';
+import 'package:flutter_redurx/flutter_redurx.dart';
+import 'package:maui/actions/post_tile.dart';
+import 'package:maui/actions/save_drawing.dart';
+import 'package:maui/db/entity/card_progress.dart';
+import 'package:maui/db/entity/tile.dart';
+import 'package:maui/db/entity/card_extra.dart';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:maui/db/entity/user.dart';
+import 'package:maui/models/root_state.dart';
+import 'package:maui/repos/card_progress_repo.dart';
+import 'package:maui/repos/card_repo.dart';
import 'package:tahiti/tahiti.dart';
-import 'package:maui/repos/activity_template_repo.dart';
-import 'package:maui/repos/drawing_repo.dart';
+import 'package:maui/repos/card_extra_repo.dart';
+import 'package:maui/repos/tile_repo.dart';
import 'package:maui/state/app_state_container.dart';
-enum DrawingSelect { create, latest, id }
-
class DrawingWrapper extends StatefulWidget {
final String activityId;
- final DrawingSelect drawingSelect;
final String drawingId;
+ final String template;
const DrawingWrapper(
- {Key key,
- @required this.activityId,
- this.drawingSelect = DrawingSelect.latest,
- this.drawingId})
+ {Key key, @required this.activityId, this.drawingId, this.template})
: super(key: key);
@override
@@ -28,10 +34,10 @@ class DrawingWrapper extends StatefulWidget {
class DrawingWrapperState extends State {
bool _isLoading = true;
- DrawingSelect _drawingSelect;
- Drawing _drawing;
- List _templates;
+ Tile _drawing;
Map _jsonMap;
+ QuackCard _activity;
+ String tileId;
@override
void initState() {
@@ -39,36 +45,20 @@ class DrawingWrapperState extends State {
_initData();
}
- @override
- void didUpdateWidget(DrawingWrapper oldWidget) {
- if (oldWidget.drawingSelect != widget.drawingSelect ||
- widget.drawingSelect == DrawingSelect.create) {
- print('hi didupdate');
- _initData();
- }
- }
-
void _initData() async {
- setState(() => _isLoading = true);
- _drawingSelect = widget.drawingSelect;
- _jsonMap = null;
- if (widget.drawingSelect == DrawingSelect.latest) {
- _drawing =
- await DrawingRepo().getLatestDrawingByActivityId(widget.activityId);
- if (_drawing == null) _drawingSelect = DrawingSelect.create;
- } else if (widget.drawingSelect == DrawingSelect.id) {
- if (widget.drawingId != null)
- _drawing = await DrawingRepo().getDrawing(widget.drawingId);
- if (_drawing == null) _drawingSelect = DrawingSelect.create;
- }
- if (_drawingSelect == DrawingSelect.create) {
- final activityTemplates = await ActivityTemplateRepo()
- .getActivityTemplatesByActivityId(widget.activityId);
- _templates =
- activityTemplates.map((t) => t.image).toList(growable: false);
- } else {
- _jsonMap = json.decode(_drawing.json);
+ _activity = await CardRepo().getCard(widget.activityId);
+
+ if (widget.drawingId != null) {
+ _drawing = await TileRepo().getTile(widget.drawingId);
+ _jsonMap = json.decode(_drawing.content);
}
+ WidgetsBinding.instance.addPostFrameCallback((_) async {
+ User user = AppStateContainer.of(context).state.loggedInUser;
+ await CardProgressRepo().upsert(CardProgress(
+ cardId: widget.activityId,
+ userId: user.id,
+ updatedAt: DateTime.now()));
+ });
setState(() => _isLoading = false);
}
@@ -82,13 +72,35 @@ class DrawingWrapperState extends State {
child: new CircularProgressIndicator(),
));
}
- return ActivityBoard(
- json: _jsonMap,
- templates: _templates,
- saveCallback: ({Map jsonMap}) => DrawingRepo().upsert(
- jsonMap: jsonMap,
- activityId: widget.activityId,
- userId: AppStateContainer.of(context).state.loggedInUser.id),
+ return WillPopScope(
+ onWillPop: () => _onWillPop(context),
+ child: Scaffold(
+ body: ActivityBoard(
+ json: _jsonMap,
+ template: widget.template,
+ title: _activity.title,
+ extStorageDir: AppStateContainer.of(context).extStorageDir,
+ saveCallback: ({Map jsonMap}) {
+ tileId = jsonMap['id'];
+ Provider.dispatch(context,
+ SaveDrawing(cardId: widget.activityId, jsonMap: jsonMap));
+ },
+ backCallback: () {
+ print('backCallback: $tileId');
+ if (tileId != null)
+ Provider.dispatch(context, PostTile(tileId: tileId));
+ Navigator.of(context).pop();
+ print('backCallback: end');
+ },
+ ),
+ ),
);
}
+
+ Future _onWillPop(BuildContext context) {
+ final completer = Completer();
+ completer.complete(true);
+ Provider.dispatch(context, PostTile(tileId: _jsonMap['id']));
+ return completer.future;
+ }
}
diff --git a/lib/components/expansionTile.dart b/lib/components/expansionTile.dart
index 60d0dc5..b66251d 100644
--- a/lib/components/expansionTile.dart
+++ b/lib/components/expansionTile.dart
@@ -1,12 +1,12 @@
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-
+
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
-
+
const Duration _kExpand = const Duration(milliseconds: 200);
-
+
/// A single-line [ListTile] with a trailing button that expands or collapses
/// the tile to reveal or hide the [children].
///
@@ -35,45 +35,47 @@ class ControlledExpansionTile extends StatefulWidget {
this.children: const [],
this.trailing,
this.initiallyExpanded: false,
- }) : assert(initiallyExpanded != null),
+ }) : assert(initiallyExpanded != null),
super(key: key);
-
+
/// A widget to display before the title.
///
/// Typically a [CircleAvatar] widget.
final Widget leading;
-
+
/// The primary content of the list item.
///
/// Typically a [Text] widget.
final Widget title;
-
+
/// Called when the tile expands or collapses.
///
/// When the tile starts expanding, this function is called with the value
/// true. When the tile starts collapsing, this function is called with
/// the value false.
final ValueChanged onExpansionChanged;
-
+
/// The widgets that are displayed when the tile expands.
///
/// Typically [ListTile] widgets.
final List children;
-
+
/// The color to display behind the sublist when expanded.
final Color backgroundColor;
-
+
/// A widget to display instead of a rotating arrow icon.
final Widget trailing;
-
+
/// Specifies if the list tile is initially expanded (true) or collapsed (false, the default).
final bool initiallyExpanded;
-
+
@override
- ControlledExpansionTileState createState() => new ControlledExpansionTileState();
+ ControlledExpansionTileState createState() =>
+ new ControlledExpansionTileState();
}
-
-class ControlledExpansionTileState extends State with SingleTickerProviderStateMixin {
+
+class ControlledExpansionTileState extends State
+ with SingleTickerProviderStateMixin {
AnimationController _controller;
CurvedAnimation _easeOutAnimation;
CurvedAnimation _easeInAnimation;
@@ -82,32 +84,35 @@ class ControlledExpansionTileState extends State with S
ColorTween _iconColor;
ColorTween _backgroundColor;
Animation _iconTurns;
-
+
bool _isExpanded = false;
-
+
@override
void initState() {
super.initState();
_controller = new AnimationController(duration: _kExpand, vsync: this);
- _easeOutAnimation = new CurvedAnimation(parent: _controller, curve: Curves.easeOut);
- _easeInAnimation = new CurvedAnimation(parent: _controller, curve: Curves.easeIn);
+ _easeOutAnimation =
+ new CurvedAnimation(parent: _controller, curve: Curves.easeOut);
+ _easeInAnimation =
+ new CurvedAnimation(parent: _controller, curve: Curves.easeIn);
_borderColor = new ColorTween();
_headerColor = new ColorTween();
_iconColor = new ColorTween();
- _iconTurns = new Tween(begin: 0.0, end: 0.5).animate(_easeInAnimation);
+ _iconTurns =
+ new Tween(begin: 0.0, end: 0.5).animate(_easeInAnimation);
_backgroundColor = new ColorTween();
-
- _isExpanded = PageStorage.of(context)?.readState(context) ?? widget.initiallyExpanded;
- if (_isExpanded)
- _controller.value = 1.0;
+
+ _isExpanded =
+ PageStorage.of(context)?.readState(context) ?? widget.initiallyExpanded;
+ if (_isExpanded) _controller.value = 1.0;
}
-
+
@override
void dispose() {
_controller.dispose();
super.dispose();
}
-
+
void handleTap() {
print("handle tap!!!");
setState(() {
@@ -115,7 +120,7 @@ class ControlledExpansionTileState extends State with S
if (_isExpanded)
_controller.forward();
else
- _controller.reverse().then((Null value) {
+ _controller.reverse().then((value) {
setState(() {
// Rebuild without widget.children.
});
@@ -125,35 +130,41 @@ class ControlledExpansionTileState extends State with S
if (widget.onExpansionChanged != null)
widget.onExpansionChanged(_isExpanded);
}
-
+
Widget _buildChildren(BuildContext context, Widget child) {
- final Color borderSideColor = _borderColor.evaluate(_easeOutAnimation) ?? Colors.transparent;
+ final Color borderSideColor =
+ _borderColor.evaluate(_easeOutAnimation) ?? Colors.transparent;
final Color titleColor = _headerColor.evaluate(_easeInAnimation);
-
+
return new Container(
decoration: new BoxDecoration(
- color: _backgroundColor.evaluate(_easeOutAnimation) ?? Colors.transparent,
+ color: _backgroundColor.evaluate(_easeOutAnimation) ??
+ Colors.transparent,
border: new Border(
top: new BorderSide(color: borderSideColor),
bottom: new BorderSide(color: borderSideColor),
- )
- ),
+ )),
child: new Column(
mainAxisSize: MainAxisSize.min,
children: [
IconTheme.merge(
- data: new IconThemeData(color: _iconColor.evaluate(_easeInAnimation)),
+ data:
+ new IconThemeData(color: _iconColor.evaluate(_easeInAnimation)),
child: new ListTile(
onTap: handleTap,
leading: widget.leading,
title: new DefaultTextStyle(
- style: Theme.of(context).textTheme.subhead.copyWith(color: titleColor),
+ style: Theme.of(context)
+ .textTheme
+ .subhead
+ .copyWith(color: titleColor),
child: widget.title,
),
- trailing: widget.trailing ?? new RotationTransition(
- turns: _iconTurns,
- child: const Icon(Icons.expand_more),
- ),
+ trailing: widget.trailing ??
+ new RotationTransition(
+ turns: _iconTurns,
+ child: const Icon(Icons.expand_more),
+ ),
),
),
new ClipRect(
@@ -166,7 +177,7 @@ class ControlledExpansionTileState extends State with S
),
);
}
-
+
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
@@ -178,13 +189,12 @@ class ControlledExpansionTileState extends State with S
..begin = theme.unselectedWidgetColor
..end = theme.accentColor;
_backgroundColor.end = widget.backgroundColor;
-
+
final bool closed = !_isExpanded && _controller.isDismissed;
return new AnimatedBuilder(
animation: _controller.view,
builder: _buildChildren,
child: closed ? null : new Column(children: widget.children),
);
-
}
-}
\ No newline at end of file
+}
diff --git a/lib/components/flash_card.dart b/lib/components/flash_card.dart
index 616088f..44a64ce 100644
--- a/lib/components/flash_card.dart
+++ b/lib/components/flash_card.dart
@@ -1,3 +1,5 @@
+import 'dart:io';
+
import 'package:flutter/material.dart';
import 'package:maui/db/entity/unit.dart';
import 'package:maui/repos/unit_repo.dart';
@@ -122,7 +124,11 @@ class _FlashCardState extends State {
constraints.maxHeight *
0.11,
fontWeight: FontWeight.bold)))
- : Image.asset(_unit.image))),
+ : Image.file(
+ File(AppStateContainer.of(context)
+ .extStorageDir +
+ _unit.image),
+ ))),
new IconButton(
icon: new Icon(Icons.arrow_right),
onPressed: () {
diff --git a/lib/components/friend_item.dart b/lib/components/friend_item.dart
index d81c322..c1bdd12 100644
--- a/lib/components/friend_item.dart
+++ b/lib/components/friend_item.dart
@@ -33,88 +33,88 @@ class FriendItem extends StatelessWidget {
var user = AppStateContainer.of(context).state.loggedInUser;
print('FriendItem: $id $imageUrl');
- final encImageUrl = imageUrl.replaceAll(new RegExp(r'/'), '/');
- return new Padding(
- padding: const EdgeInsets.all(0.0),
- child: new Column(
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- numNotifs > 0
- ? Badge(
- color: Colors.red,
- textStyle:
- const TextStyle(fontSize: 30.0, color: Colors.white),
- borderSize: 5.0,
- borderColor: Colors.red,
- value: '$numNotifs',
- child: _buildFriendItem(id, user))
- : _buildFriendItem(id, user),
- new Text(
- name ?? '',
- textAlign: TextAlign.right,
- textDirection: TextDirection.rtl,
- overflow: TextOverflow.ellipsis,
- style: new TextStyle(
- fontSize: 15.0,
- color: Colors.black,
- fontWeight: FontWeight.bold),
- ),
- ],
- ));
- }
-
- Widget _buildFriendItem(String id, User user) {
+// final encImageUrl = imageUrl.replaceAll(new RegExp(r'/'), '/')
+// ;
return new InkWell(
onTap: onTap,
- child: new CircleAvatar(
- radius: 80.0,
-// maxRadius: 40.0,
- backgroundImage: new AssetImage("assets/chat_image/chat icon_04.png"),
- child: new Center(
- child: RawMaterialButton(
- elevation: 20.0,
-
- shape: new CircleBorder(
- side: new BorderSide(
- color: Color(color),
- width: 4.0,
+ child: new Padding(
+ padding: const EdgeInsets.fromLTRB(8.0, 4.0, 8.0, 4.0),
+ child: new Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ numNotifs > 0
+ ? Badge(
+ color: Colors.red,
+ textStyle:
+ const TextStyle(fontSize: 8.0, color: Colors.white),
+ borderSize: 5.0,
+ borderColor: Colors.red,
+ value: '$numNotifs',
+ child: _buildFriendItem(id, user))
+ : _buildFriendItem(id, user),
+ new Text(
+ name ?? '',
+ overflow: TextOverflow.ellipsis,
+ style: new TextStyle(
+ fontSize: 15.0,
+ color: Colors.white,
+ fontWeight: FontWeight.bold),
),
- ),
- child: new CircleAvatar(
- radius: 50.0,
- child: new Container(
- width: 100.0,
- height: 100.0,
- decoration: new BoxDecoration(
- shape: BoxShape.circle,
- image: new DecorationImage(
- image: replaceWithHoodie && user.id == id
- ? new AssetImage('assets/chat_Bot_Icon.png')
- : isFile
- ? FileImage(File(imageUrl))
- : imageMemory != null
- ? MemoryImage(imageMemory)
- : AssetImage('assets/hoodie_bear.png'),
- fit: BoxFit.fill)))),
-// child: new Container(
-// width: 100.0,
-// height: 100.0,
-// decoration: new BoxDecoration(
-// shape: BoxShape.circle,
-//
-// image: new DecorationImage(
-// image: replaceWithHoodie && user.id == id
-// ? new AssetImage('assets/koala_neutral.png')
-// : isFile
-// ? FileImage(File(imageUrl))
-// : imageMemory != null
-// ? MemoryImage(imageMemory)
-// : AssetImage('assets/hoodie_bear.png'),
-// fit: BoxFit.fill))),
- ),
- ),
- ),
+ ],
+ )),
+ );
+ }
+
+ Widget _buildFriendItem(String id, User user) {
+ return new CircleAvatar(
+ backgroundImage: replaceWithHoodie && user.id == id
+ ? new AssetImage('assets/chat_Bot_Icon.png')
+ : isFile
+ ? FileImage(File(imageUrl))
+ : imageMemory != null
+ ? MemoryImage(imageMemory)
+ : AssetImage('assets/hoodie_bear.png'),
);
}
+
+// Widget _buildFriendItem(String id, User user) {
+// return new InkWell(
+// onTap: onTap,
+// child: new CircleAvatar(
+// radius: 80.0,
+//// maxRadius: 40.0,
+// backgroundImage: new AssetImage("assets/chat_image/chat icon_04.png"),
+// child: new Center(
+// child: RawMaterialButton(
+// elevation: 20.0,
+//
+// shape: new CircleBorder(
+// side: new BorderSide(
+// color: Color(color),
+// width: 4.0,
+// ),
+// ),
+// child: new CircleAvatar(
+// radius: 50.0,
+// child: new Container(
+// width: 100.0,
+// height: 100.0,
+// decoration: new BoxDecoration(
+// shape: BoxShape.circle,
+// image: new DecorationImage(
+// image: replaceWithHoodie && user.id == id
+// ? new AssetImage('assets/chat_Bot_Icon.png')
+// : isFile
+// ? FileImage(File(imageUrl))
+// : imageMemory != null
+// ? MemoryImage(imageMemory)
+// : AssetImage('assets/hoodie_bear.png'),
+// fit: BoxFit.fill)))),
+// ),
+// ),
+// ),
+// );
+// }
+
}
diff --git a/lib/components/hud.dart b/lib/components/hud.dart
index d7cb0c9..0776df5 100644
--- a/lib/components/hud.dart
+++ b/lib/components/hud.dart
@@ -1,15 +1,16 @@
import 'dart:io';
import 'dart:math';
import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
+
import 'package:maui/db/entity/user.dart';
import 'package:maui/games/single_game.dart';
+import 'package:maui/components/progress_circle.dart';
class Hud extends StatelessWidget {
User user;
bool amICurrentUser;
double height;
-
+ double width;
bool start;
Color backgroundColor;
Color foregroundColor;
@@ -18,35 +19,77 @@ class Hud extends StatelessWidget {
Function onEnd;
double progress;
int score;
+ bool quizeType;
- Hud({
- Key key,
- this.user,
- this.height,
- this.start = true,
- this.backgroundColor,
- this.foregroundColor,
- this.gameMode,
- this.playTime,
- this.onEnd,
- this.amICurrentUser,
- this.progress,
- this.score,
- }) : super(key: key);
+ Hud(
+ {Key key,
+ this.user,
+ this.height,
+ this.width,
+ this.start = true,
+ this.backgroundColor,
+ this.foregroundColor,
+ this.gameMode,
+ this.playTime,
+ this.onEnd,
+ this.amICurrentUser,
+ this.progress,
+ this.score,
+ this.quizeType})
+ : super(key: key);
@override
Widget build(BuildContext context) {
height = height * 0.6;
- // final fontSize = min(18.0, height / 2);
+ width = width;
+
+ final fontSize = min(18.0, height / 2);
+
var headers = [
- new Container(
- width: height,
- height: height,
- decoration: new BoxDecoration(
- shape: BoxShape.circle,
- image: new DecorationImage(
- image: new FileImage(new File(user.image)),
- fit: BoxFit.fill))),
+ new Stack(
+
+ alignment: AlignmentDirectional.center,
+ children: [
+ new Container(
+ width: height / 1.4,
+ height: height / 1.4,
+ decoration: new BoxDecoration(
+ shape: BoxShape.circle,
+ image: new DecorationImage(
+ image: new FileImage(new File(user.image)),
+ fit: BoxFit.fill))),
+ new SizedBox(
+ width: height / 1.4,
+ height: height / 1.4,
+ child: new CircularProgressIndicator(
+ strokeWidth: height / 8.5,
+ value: 1.0,
+ valueColor: new AlwaysStoppedAnimation(backgroundColor),
+ )),
+ new SizedBox(
+ width: height / 1.4,
+ height: height / 1.4,
+ child: gameMode == GameMode.timed
+ ? new ProgressCircle(
+ time: playTime,
+ onEnd: () => onEnd(context),
+ strokeWidth: height / 8.5,
+ )
+ : new ProgressCircle(
+ progress: progress,
+ strokeWidth: height / 8.5,
+ )),
+ ],
+ ),
+ Padding(
+ padding: const EdgeInsets.all(10.0),
+ child: Stack(children: [
+ Text(
+ '$score',
+ style: new TextStyle(fontSize: fontSize, color: foregroundColor),
+ ),
+ ]),
+ ),
];
return new Row(
diff --git a/lib/components/nima.dart b/lib/components/nima.dart
index 31b2280..02ff1a1 100644
--- a/lib/components/nima.dart
+++ b/lib/components/nima.dart
@@ -5,7 +5,8 @@ class Nima extends StatefulWidget {
final String name;
final int score;
final String tag;
- Nima({this.name, this.score, this.tag});
+ final bool pageExited;
+ Nima({this.name, this.score, this.tag, this.pageExited});
@override
_NimaState createState() {
@@ -17,6 +18,8 @@ class _NimaState extends State with TickerProviderStateMixin {
int _prevScore;
String _name;
String _emotion = 'blinking';
+ bool paused = false;
+ String _animation;
@override
void initState() {
@@ -25,23 +28,37 @@ class _NimaState extends State with TickerProviderStateMixin {
_prevScore = widget.score;
}
+ @override
+ void didUpdateWidget(Nima oldWidget) {
+ super.didUpdateWidget(oldWidget);
+ if (oldWidget.pageExited != widget.pageExited) {
+ setState(() {
+ paused = true;
+ _animation = null;
+ });
+ }
+ }
+
@override
Widget build(BuildContext context) {
- if (_emotion == 'blinking') {
- if (_prevScore < widget.score) {
- _emotion = 'happy';
- } else if (_prevScore > widget.score) {
- _emotion = 'sad';
+ if (!paused) {
+ if (_emotion == 'blinking') {
+ if (_prevScore < widget.score) {
+ _emotion = 'happy';
+ } else if (_prevScore > widget.score) {
+ _emotion = 'sad';
+ }
}
+ _animation = '${_name}_$_emotion';
}
- print('emotion: $_emotion');
_prevScore = widget.score;
return NimaActor("assets/solo",
alignment: Alignment.center,
fit: BoxFit.contain,
- animation: '${_name}_$_emotion', completed: (String animationName) {
+ paused: paused,
+ animation: _animation, completed: (_) {
setState(() {
- _emotion = 'blinking';
+ if (!paused) _emotion = 'blinking';
});
});
}
diff --git a/lib/components/quiz_button.dart b/lib/components/quiz_button.dart
index a8e26e8..d1f50ef 100644
--- a/lib/components/quiz_button.dart
+++ b/lib/components/quiz_button.dart
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
enum Status { notSelected, correct, incorrect, disabled }
-class QuizButton extends StatelessWidget {
+class QuizButton extends StatefulWidget {
final String text;
final Function onPress;
final Status buttonStatus;
@@ -14,25 +14,117 @@ class QuizButton extends StatelessWidget {
@required this.buttonStatus})
: super(key: key);
+ @override
+ QuizButtonState createState() {
+ return new QuizButtonState();
+ }
+}
+
+class QuizButtonState extends State with TickerProviderStateMixin {
+ Animation blinkAnimation;
+ Animation resizeAnimation, noAnimation;
+ AnimationController controller, _controller;
+ bool isBlinking = true;
+
+ initState() {
+ super.initState();
+ controller = AnimationController(
+ duration: const Duration(milliseconds: 3000), vsync: this)
+ ..addStatusListener((status) {
+ if (status == AnimationStatus.completed) {
+ controller.reverse();
+ }
+ if (status == AnimationStatus.dismissed) {
+ setState(() {
+ isBlinking = false;
+ });
+ }
+ });
+
+ final CurvedAnimation curve =
+ CurvedAnimation(parent: controller, curve: Curves.linear);
+ blinkAnimation =
+ ColorTween(begin: Colors.red, end: Colors.white).animate(curve);
+
+ _controller = AnimationController(
+ duration: const Duration(milliseconds: 2000), vsync: this)
+ ..addStatusListener((status) {
+ if (status == AnimationStatus.completed) {
+ _controller.reverse();
+ }
+ });
+
+ resizeAnimation = Tween(
+ begin: 1.0,
+ end: 0.9,
+ ).animate(
+ CurvedAnimation(
+ parent: _controller,
+ curve: Curves.easeIn,
+ ),
+ );
+ noAnimation = Tween(
+ begin: 1.0,
+ end: 1.0,
+ ).animate(
+ CurvedAnimation(
+ parent: _controller,
+ curve: Curves.easeIn,
+ ),
+ );
+ }
+
+ @override
+ void didUpdateWidget(QuizButton oldWidget) {
+ print(
+ "oldWidget ButtonStatus: ${oldWidget.buttonStatus} widget ButtonStatus: ${widget.buttonStatus}");
+ if (oldWidget.buttonStatus == Status.disabled &&
+ widget.buttonStatus == Status.incorrect) {
+ controller.forward();
+ }
+
+ if (oldWidget.buttonStatus == Status.disabled &&
+ widget.buttonStatus == Status.correct) {
+ _controller.forward();
+ }
+
+ super.didUpdateWidget(oldWidget);
+ }
+
+ @override
+ void dispose() {
+ controller.dispose();
+ _controller.dispose();
+ super.dispose();
+ }
+
Widget build(BuildContext context) {
+ MediaQueryData media = MediaQuery.of(context);
+ var size = media.size;
print("QuizButton.build");
- print("ButtonStatus - $buttonStatus");
-
- return new RaisedButton(
- onPressed: buttonStatus == Status.notSelected ? onPress : null,
- color: Color(0xFFffffff),
- disabledColor: buttonStatus == Status.disabled
- ? Colors.grey
- : buttonStatus == Status.correct
- ? Colors.greenAccent
- : Colors.redAccent,
- shape: new RoundedRectangleBorder(
- borderRadius: const BorderRadius.all(const Radius.circular(16.0))),
- child: text.endsWith(".png")
- ? new Center(child: new Image.asset("assets/${text}"))
- : new Center(
- child: new Text(text,
- key: new Key("${key}"),
- style: new TextStyle(color: Colors.black))));
+
+ return ScaleTransition(
+ scale:
+ widget.buttonStatus == Status.correct ? resizeAnimation : noAnimation,
+ child: new RaisedButton(
+ onPressed:
+ widget.buttonStatus == Status.notSelected ? widget.onPress : null,
+ color: Colors.amber,
+ disabledColor: widget.buttonStatus == Status.disabled
+ ? Colors.grey
+ : widget.buttonStatus == Status.correct
+ ? Colors.green
+ : isBlinking == true ? blinkAnimation.value : Colors.red,
+ shape: new RoundedRectangleBorder(
+ borderRadius:
+ const BorderRadius.all(const Radius.circular(16.0))),
+ child: widget.text.endsWith(".png")
+ ? new Center(child: new Image.asset("assets/${widget.text}"))
+ : new Center(
+ child: new Text(widget.text,
+ key: new Key("${widget.key}"),
+ style: new TextStyle(
+ fontSize: size.height * 0.02, color: Colors.black)))),
+ );
}
}
diff --git a/lib/components/quiz_keyboard.dart b/lib/components/quiz_keyboard.dart
new file mode 100644
index 0000000..573c27c
--- /dev/null
+++ b/lib/components/quiz_keyboard.dart
@@ -0,0 +1,84 @@
+import 'package:flutter/material.dart';
+
+class QuizKeyboard extends StatefulWidget {
+ final Function onSubmit;
+
+ QuizKeyboard({Key key, this.onSubmit}) : super(key: key);
+ @override
+ _QuizKeyboardState createState() => new _QuizKeyboardState();
+}
+
+class _QuizKeyboardState extends State {
+ final TextEditingController _textController = new TextEditingController();
+ String keyboardAnswer;
+
+ void _handleSubmitted(String text) {
+ _textController.clear();
+ widget.onSubmit(text);
+ }
+
+ @override
+ void initState() {
+ super.initState();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return new Center(
+ child: new Container(
+ margin: const EdgeInsets.symmetric(horizontal: 8.0),
+ child: new Row(
+ children: [
+ new Flexible(
+ child: new TextField(
+ controller: _textController,
+ onSubmitted: _handleSubmitted,
+ onChanged: (String text) {
+ keyboardAnswer = text;
+ },
+ key: Key("keyboard"),
+ keyboardType: TextInputType.text,
+ obscureText: false,
+ style:
+ TextStyle(fontSize: 40.0, height: 1.5, color: Colors.black),
+ maxLines: 1,
+ autocorrect: false,
+ enabled: true,
+ decoration: new InputDecoration(
+ enabledBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.all(Radius.circular(15.0)),
+ borderSide: BorderSide(
+ style: BorderStyle.solid,
+ color: Theme.of(context).primaryColor)),
+ border: OutlineInputBorder(
+ borderRadius: BorderRadius.all(Radius.circular(15.0)),
+ ),
+ filled: true,
+ fillColor: Color.fromRGBO(255, 255, 255, 100.0),
+ contentPadding: EdgeInsets.only(left: 20.0),
+ hintText: 'Type here',
+ ),
+ autofocus: true,
+ ),
+ ),
+ new Container(
+ margin: const EdgeInsets.symmetric(horizontal: 4.0),
+ child: new IconButton(
+ icon: new Icon(
+ Icons.check,
+ size: 40.0,
+ ),
+ color: Theme.of(context).primaryColor,
+ onPressed: () {
+ print("KeyboardText ${_textController.text}");
+ _handleSubmitted(_textController.text);
+ widget.onSubmit(_textController.text);
+ },
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/components/quiz_progress_tracker.dart b/lib/components/quiz_progress_tracker.dart
index ee34b8c..50126cc 100644
--- a/lib/components/quiz_progress_tracker.dart
+++ b/lib/components/quiz_progress_tracker.dart
@@ -1,5 +1,8 @@
import 'package:flutter/material.dart';
-import '../repos/quiz_progress_repo.dart';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:maui/db/entity/user.dart';
+import 'package:maui/repos/card_progress_repo.dart';
+import 'package:maui/state/app_state_container.dart';
class QuizProgressTracker extends StatefulWidget {
final String topicId;
@@ -21,8 +24,10 @@ class QuizProgressTrackerState extends State {
}
void _initData() async {
- _quizProgress =
- await QuizProgressRepo().getScoreSummaryByTopicId(widget.topicId);
+ User _user = AppStateContainer.of(context).state.loggedInUser;
+ _quizProgress = await CardProgressRepo()
+ .getProgressStatusByCollectionAndTypeAndUserId(
+ widget.topicId, CardType.question, _user.id);
setState(() => _isLoading = false);
}
diff --git a/lib/components/quiz_welcome.dart b/lib/components/quiz_welcome.dart
new file mode 100644
index 0000000..486ebbc
--- /dev/null
+++ b/lib/components/quiz_welcome.dart
@@ -0,0 +1,87 @@
+import 'package:flutter/material.dart';
+import 'package:nima/nima_actor.dart';
+import 'package:maui/quack/quiz_navigator.dart';
+
+class QuizWelcome extends StatefulWidget {
+ final String cardId;
+
+ QuizWelcome({Key key, this.cardId}) : super(key: key);
+
+ @override
+ QuizWelcomeState createState() {
+ return new QuizWelcomeState();
+ }
+}
+
+class QuizWelcomeState extends State {
+ String _animation = 'joy';
+ bool paused = false;
+
+ @override
+ Widget build(BuildContext context) {
+ // TODO: implement build
+ final media = MediaQuery.of(context);
+
+ var size = media.size;
+ void _complete() {
+ setState(() {
+ paused = true;
+ _animation = null;
+ });
+ }
+
+ return new Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Padding(
+ padding: new EdgeInsets.only(right: size.width * 0.1),
+ child: Container(
+ height: media.size.height * 0.69,
+ width: size.width * 0.9,
+ child: AspectRatio(
+ aspectRatio: 2.0,
+ child: new NimaActor("assets/quack",
+ alignment: Alignment.center,
+ paused: paused,
+ fit: BoxFit.scaleDown,
+ animation: _animation,
+ mixSeconds: 0.2, completed: (String animtionName) {
+ _complete();
+ })),
+ ),
+ ),
+ Center(
+ child: Container(
+ decoration: BoxDecoration(
+ shape: BoxShape.rectangle,
+ borderRadius: new BorderRadius.circular(12.0),
+ color: Colors.amber,
+ ),
+ padding: new EdgeInsets.only(
+ top: size.height * 0.01, bottom: media.size.height * 0.01),
+ height: size.height * 0.2,
+ width: size.width * 0.4,
+ child: FlatButton(
+ color: Colors.amber,
+ child: Text(
+ 'Quiz',
+ style: new TextStyle(
+ fontSize: size.height > size.width
+ ? size.height * 0.06
+ : size.height * 0.1,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ onPressed: () =>
+ Navigator.of(context).pushReplacement(MaterialPageRoute(
+ builder: (BuildContext context) => QuizNavigator(
+ cardId: widget.cardId,
+ ))),
+ ),
+ ),
+ )
+ ],
+ );
+ }
+}
diff --git a/lib/components/show_help.dart b/lib/components/show_help.dart
index bc7b657..d7c634d 100644
--- a/lib/components/show_help.dart
+++ b/lib/components/show_help.dart
@@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
-import 'package:maui/components/topic_page_view.dart';
+import 'package:maui/quack/card_detail_wrapper.dart';
class ShowHelp extends StatelessWidget {
- final String topicId;
+ final String topicId;
const ShowHelp({
Key key,
@required this.topicId,
@@ -15,7 +15,10 @@ class ShowHelp extends StatelessWidget {
height: constraints.maxHeight,
width: constraints.maxWidth * 0.89,
child: new Drawer(
- child: new TopicPageView(topicId: topicId,),
+ child: new CardDetailWrapper(
+ cardId: topicId,
+ showBackButton: false,
+ ),
),
);
});
diff --git a/lib/components/signin_button.dart b/lib/components/signin_button.dart
new file mode 100644
index 0000000..3341ef6
--- /dev/null
+++ b/lib/components/signin_button.dart
@@ -0,0 +1,28 @@
+import 'package:flutter/material.dart';
+import 'package:maui/loca.dart';
+
+class SignIn extends StatelessWidget {
+ SignIn();
+ @override
+ Widget build(BuildContext context) {
+ return (new Container(
+ width: 320.0,
+ height: 60.0,
+ alignment: FractionalOffset.center,
+ decoration: new BoxDecoration(
+ color: const Color.fromRGBO(247, 64, 106, 1.0),
+ borderRadius: new BorderRadius.all(const Radius.circular(30.0)),
+ ),
+ child: new Text(
+ Loca.of(context).signIn,
+ style: new TextStyle(
+ color: Colors.amber,
+ fontSize: 36.0,
+ fontWeight: FontWeight.w300,
+ letterSpacing: 0.3,
+ ),
+ ),
+ ));
+ }
+}
+
diff --git a/lib/components/topic_button.dart b/lib/components/topic_button.dart
deleted file mode 100644
index f72b851..0000000
--- a/lib/components/topic_button.dart
+++ /dev/null
@@ -1,95 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter_svg/flutter_svg.dart';
-import 'package:maui/components/quiz_progress_tracker.dart';
-
-class TopicButton extends StatefulWidget {
- final String text;
- final int color;
- final String image;
- final VoidCallback onPress;
- final String topicId;
-
- TopicButton({
- Key key,
- @required this.text,
- this.color,
- this.image,
- this.onPress,
- this.topicId,
-// this.sizeHieght,
-// this.sizeWidth
- }) : super(key: key);
-
- @override
- State createState() => new TopicButtonState();
-}
-
-class TopicButtonState extends State {
- @override
- void initState() {
- super.initState();
- }
-
- @override
- Widget build(BuildContext context) {
- // TODO: implement build
- print("hello Topic button ${widget.image} and ${widget.text}");
- return Padding(
- padding: const EdgeInsets.all(8.0),
- child: new Material(
- elevation: 8.0,
- borderRadius: const BorderRadius.all(const Radius.circular(16.0)),
- child: new Container(
- color: Colors.brown,
- child: new InkWell(
- onTap: widget.onPress,
- child: new Stack(children: [
- new Column(
- children: [
- new QuizProgressTracker(topicId: widget.topicId),
- widget.image == null
- ? new Expanded(
- child: Container(color: Colors.red),
- )
- : widget.image.endsWith(".svg")
- ? new Expanded(
- child: new Container(
- color: Colors.red,
- child: new AspectRatio(
- aspectRatio: 2.0,
- child: new SvgPicture.asset(
- widget.image,
- allowDrawingOutsideViewBox: false,
- ),
- ),
- ),
- )
- : new Expanded(
- child: Container(
- decoration: new BoxDecoration(
- image: new DecorationImage(
- image: new AssetImage(widget.image),
- fit: BoxFit.cover,
- ),
- color: Colors.red),
- ),
- ),
- Container(
- child: new Text(widget.text,
- style: new TextStyle(
- color: Colors.white,
- fontSize: 30.0,
- ),
-// textAlign: TextAlign.center,
- overflow: TextOverflow.ellipsis),
- )
- ],
- )
- ]),
- ),
- ),
- ),
- );
- }
-}
diff --git a/lib/components/topic_page_view.dart b/lib/components/topic_page_view.dart
deleted file mode 100644
index c0662f2..0000000
--- a/lib/components/topic_page_view.dart
+++ /dev/null
@@ -1,149 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:maui/loca.dart';
-import 'package:maui/repos/article_repo.dart';
-import 'package:maui/db/entity/article.dart';
-import 'package:maui/components/article_page.dart';
-
-class TopicPageView extends StatefulWidget {
- final String topicId;
-
- TopicPageView({key, @required this.topicId}) : super(key: key);
- @override
- _TopicPageViewState createState() => new _TopicPageViewState();
-}
-
-class _TopicPageViewState extends State {
- List _articles;
- bool _isDataAvailable = false;
- bool _isForwardDisable = false;
- bool _isBackwardDisable = true;
- PageController pageController = new PageController(initialPage: 0);
-
- void _initArticles() async {
- await new ArticleRepo()
- .getArticlesByTopicId(widget.topicId)
- .then((articles) async {
- setState(() {
- articles.sort((a, b) => a.serial.compareTo(b.serial));
- _articles = articles;
- _articles.length != 0
- ? _isDataAvailable = true
- : _isDataAvailable = false;
- });
- });
- }
-
- @override
- void initState() {
- super.initState();
- _initArticles();
- }
-
- void _forwardButtonBehaviour() {
- pageController.nextPage(
- duration: new Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
- if (pageController.page == 0.0) {
- setState(() {
- _isBackwardDisable = false;
- });
- }
- if ((pageController.page + 1.0).toInt() == (_articles.length - 1)) {
- setState(() {
- _isForwardDisable = true;
- });
- }
- }
-
- void _backwardButtonBehaviour() {
- pageController.previousPage(
- duration: new Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
- if ((pageController.page).toInt() == (_articles.length - 1)) {
- setState(() {
- _isForwardDisable = false;
- });
- }
- if (pageController.page - 1.0 == 0.0) {
- setState(() {
- _isBackwardDisable = true;
- });
- }
- }
-
- @override
- void dispose() {
- pageController.dispose();
- super.dispose();
- }
-
- @override
- Widget build(BuildContext context) {
- return _isDataAvailable == false
- ? new Container(
- child: new Center(
- child: new Text(
- Loca.of(context).no_data,
- style:
- new TextStyle(fontSize: 50.0, fontWeight: FontWeight.bold),
- ),
- ),
- )
- : new Stack(
- children: [
- new PageView.builder(
- pageSnapping: false,
- physics: NeverScrollableScrollPhysics(),
- scrollDirection: Axis.horizontal,
- itemCount: _articles.length,
- controller: pageController,
- itemBuilder: (context, index) {
- return new ArticlePage(
- topicId: _articles[index].topicId,
- articleId: _articles[index].id,
- name: _articles[index].name,
- text: _articles[index].text,
- audio: _articles[index].audio,
- video: _articles[index].video,
- image: _articles[index].image,
- serial: _articles[index].serial,
- );
- },
- ),
- _articles.length > 1
- ? new Row(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- new Expanded(
- flex: 2,
- child: _isBackwardDisable
- ? new Container()
- : new IconButton(
- onPressed: () => _backwardButtonBehaviour(),
- icon: new Icon(
- Icons.arrow_left,
- color: Colors.black,
- ),
- iconSize: 50.0,
- ),
- ),
- new Expanded(flex: 10, child: new Container()),
- new Expanded(
- flex: 2,
- child: _isForwardDisable
- ? new Container()
- : new IconButton(
- onPressed: () => _forwardButtonBehaviour(),
- icon: new Icon(
- Icons.arrow_right,
- color: Colors.black,
- ),
- iconSize: 50.0,
- ),
- ),
- ],
- )
- : new Container(),
- ],
- );
- }
-}
diff --git a/lib/components/unit_button.dart b/lib/components/unit_button.dart
index f1c5647..00d240b 100644
--- a/lib/components/unit_button.dart
+++ b/lib/components/unit_button.dart
@@ -1,3 +1,5 @@
+import 'dart:io';
+
import 'package:flutter/material.dart';
import 'package:maui/db/entity/unit.dart';
import 'package:maui/games/single_game.dart';
@@ -137,8 +139,7 @@ class _UnitButtonState extends State {
onPressed: widget.disabled
? null
: () {
- AppStateContainer
- .of(context)
+ AppStateContainer.of(context)
.play(widget.text.toLowerCase());
widget.onPress();
},
@@ -151,8 +152,8 @@ class _UnitButtonState extends State {
? Theme.of(context).primaryColor
: Colors.white,
width: 4.0),
- borderRadius: BorderRadius
- .all(Radius.circular(buttonConfig?.radius ?? 8.0))),
+ borderRadius: BorderRadius.all(
+ Radius.circular(buttonConfig?.radius ?? 8.0))),
child: _buildUnit(widget.fontSize ?? buttonConfig.fontSize)));
}
@@ -160,7 +161,12 @@ class _UnitButtonState extends State {
if (_unitMode == UnitMode.audio) {
return new Icon(Icons.volume_up);
} else if (_unitMode == UnitMode.image) {
- return _isLoading ? new Container() : new Image.asset(_unit.image);
+ return _isLoading
+ ? new Container()
+ : new Image.file(
+ File(AppStateContainer.of(context).extStorageDir + _unit.image),
+ fit: BoxFit.cover,
+ );
}
return Center(
child: Text(widget.text,
diff --git a/lib/components/user_item.dart b/lib/components/user_item.dart
index 2e56766..db6a1e1 100644
--- a/lib/components/user_item.dart
+++ b/lib/components/user_item.dart
@@ -12,7 +12,6 @@ class LoginUserItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
- print(user);
return new Center(
child: new InkWell(
onTap: () => AppStateContainer.of(context).setLoggedInUser(user),
diff --git a/lib/components/videoplayer.dart b/lib/components/videoplayer.dart
index 9262b7a..7caba5d 100644
--- a/lib/components/videoplayer.dart
+++ b/lib/components/videoplayer.dart
@@ -1,4 +1,5 @@
import 'dart:async';
+import 'dart:io';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
@@ -20,10 +21,9 @@ import 'package:maui/components/gameaudio.dart';
// void main() => runApp(VideoApp());
class VideoApp extends StatefulWidget {
- final String gamename;
+ final File file;
final int gameCategoryId;
- const VideoApp({Key key, this.gamename, this.gameCategoryId})
- : super(key: key);
+ const VideoApp({Key key, this.file, this.gameCategoryId}) : super(key: key);
@override
_VideoAppState createState() => _VideoAppState();
}
@@ -35,12 +35,8 @@ class _VideoAppState extends State {
@override
void initState() {
super.initState();
- print("hello data i have to check...::${widget.gamename}");
- final name = widget.gamename;
- _controller = VideoPlayerController.asset("assets/demo_video/$name.mp4")
- // VideoPlayerController.network(
- // 'http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_20mb.mp4',
- // )
+
+ _controller = VideoPlayerController.file(widget.file)
..addListener(() {
final bool isPlaying = _controller.value.isPlaying;
if (isPlaying != _isPlaying) {
@@ -53,7 +49,7 @@ class _VideoAppState extends State {
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
setState(() {});
});
- print("hello data i have to check..rrrrrrrr.::${widget.gamename}");
+ print("hello data i have to check..rrrrrrrr.::${widget.file}");
}
@override
diff --git a/lib/db/dao/activity_dao.dart b/lib/db/dao/activity_dao.dart
deleted file mode 100644
index 98138d0..0000000
--- a/lib/db/dao/activity_dao.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-import 'dart:async';
-import 'package:maui/app_database.dart';
-import 'package:maui/db/entity/activity.dart';
-import 'package:maui/db/entity/topic.dart';
-import 'package:sqflite/sqflite.dart';
-
-class ActivityDao {
- Future getActivity(String id, {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- List maps = await db.query(Activity.table,
- columns: [
- Activity.idCol,
- Activity.topicIdCol,
- Activity.serialCol,
- Activity.textCol,
- Activity.stickerPackCol
- ],
- where: "${Activity.idCol} = ? ",
- whereArgs: [id]);
- if (maps.length > 0) {
- return Activity.fromMap(maps.first);
- }
- return null;
- }
-
- Future> getActivitiesByTopicId(String topicId,
- {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- List maps =
- await db.query('${Activity.table} a,${Topic.table} t', columns: [
- 'a.${Activity.idCol}',
- 'a.${Activity.topicIdCol}',
- 'a.${Activity.serialCol}',
- 'a.${Activity.imageCol}',
- 'a.${Activity.videoCol}',
- 'a.${Activity.audioCol}',
- 'a.${Activity.textCol}',
- 'a.${Activity.stickerPackCol}',
- ], where: '''
- a.${Activity.topicIdCol} = t.${Topic.idCol}
- AND a.${Activity.topicIdCol} = ?
- ''', whereArgs: [
- topicId
- ]);
- return maps.map((el) => new Activity.fromMap(el)).toList();
- }
-}
diff --git a/lib/db/dao/activity_template_dao.dart b/lib/db/dao/activity_template_dao.dart
deleted file mode 100644
index f8ca836..0000000
--- a/lib/db/dao/activity_template_dao.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-import 'dart:async';
-import 'package:maui/app_database.dart';
-import 'package:sqflite/sqflite.dart';
-import '../entity/activity_template.dart';
-
-class ActivityTemplateDao {
- Future> getActivityTemplatesByActivityId(
- String activityId,
- {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- List maps = await db.query(ActivityTemplate.table,
- columns: [
- ActivityTemplate.activityIdCol,
- ActivityTemplate.imageCol,
- ],
- where: '${ActivityTemplate.activityIdCol} = ?',
- whereArgs: [activityId]);
-
- return maps.map((el) => new ActivityTemplate.fromMap(el)).toList();
- }
-}
diff --git a/lib/db/dao/activity_topic_dao.dart b/lib/db/dao/activity_topic_dao.dart
deleted file mode 100644
index 6e0ec98..0000000
--- a/lib/db/dao/activity_topic_dao.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-import 'dart:async';
-
-import 'package:maui/app_database.dart';
-import 'package:maui/db/entity/activity_topic.dart';
-import 'package:sqflite/sqflite.dart';
-
-class ActivityTopicDao {
- Future> getActivityTopicByTopicId(String topicId,
- {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- List maps = await db.query(ActivityTopic.table,
- columns: [
- ActivityTopic.activityIdCol,
- ActivityTopic.topicIdCol,
- ],
- where: "${ActivityTopic.topicIdCol} = ?",
- whereArgs: [topicId]);
- if (maps.length > 0) {
- return maps.map((el) => new ActivityTopic.fromMap(el)).toList();
- }
- return null;
- }
-}
diff --git a/lib/db/dao/article_dao.dart b/lib/db/dao/article_dao.dart
deleted file mode 100644
index b6c8080..0000000
--- a/lib/db/dao/article_dao.dart
+++ /dev/null
@@ -1,49 +0,0 @@
-import 'dart:async';
-
-import 'package:maui/app_database.dart';
-import 'package:maui/db/entity/article.dart';
-import 'package:sqflite/sqflite.dart';
-
-class ArticleDao {
- Future getArticleByTopicId(String topicId, {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- List maps = await db.query(Article.table,
- columns: [
- Article.idCol,
- Article.nameCol,
- Article.topicIdCol,
- Article.serialCol,
- Article.videoCol,
- Article.audioCol,
- Article.imageCol,
- Article.textCol
- ],
- where: '${Article.topicIdCol} = ?',
- whereArgs: [topicId]);
- if (maps.length > 0) {
- return Article.fromMap(maps.first);
- }
- return null;
- }
-
- Future> getArticlesByTopicId(String topicId,
- {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- List maps = await db.query(
- Article.table,
- columns: [
- Article.idCol,
- Article.nameCol,
- Article.topicIdCol,
- Article.serialCol,
- Article.videoCol,
- Article.audioCol,
- Article.imageCol,
- Article.textCol,
- ],
- where: '${Article.topicIdCol} = ?',
- whereArgs: [topicId],
- );
- return maps.map((article) => new Article.fromMap(article)).toList();
- }
-}
diff --git a/lib/db/dao/card_dao.dart b/lib/db/dao/card_dao.dart
new file mode 100644
index 0000000..e781fad
--- /dev/null
+++ b/lib/db/dao/card_dao.dart
@@ -0,0 +1,36 @@
+import 'dart:async';
+
+import 'package:flutter/material.dart';
+import 'package:maui/app_database.dart';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:sqflite/sqflite.dart';
+
+class CardDao {
+ Future getCard(String id, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query(QuackCard.table,
+ columns: QuackCard.allCols,
+ where: '${QuackCard.idCol} = ?',
+ whereArgs: [id]);
+ if (maps.length > 0) {
+ return QuackCard.fromMap(maps.first);
+ }
+ return null;
+ }
+
+ Future incrementComments(String id, int amount, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ QuackCard card = await getCard(id, db: db);
+ card.comments = (card.comments ?? 0) + amount;
+ await db.update(QuackCard.table, card.toMap(),
+ where: '${QuackCard.idCol} = ?', whereArgs: [card.id]);
+ }
+
+ Future incrementLikes(String id, int amount, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ QuackCard card = await getCard(id, db: db);
+ card.likes = (card.likes ?? 0) + amount;
+ await db.update(QuackCard.table, card.toMap(),
+ where: '${QuackCard.idCol} = ?', whereArgs: [card.id]);
+ }
+}
diff --git a/lib/db/dao/card_extra_dao.dart b/lib/db/dao/card_extra_dao.dart
new file mode 100644
index 0000000..2ea4081
--- /dev/null
+++ b/lib/db/dao/card_extra_dao.dart
@@ -0,0 +1,19 @@
+import 'dart:async';
+
+import 'package:maui/app_database.dart';
+import 'package:maui/db/entity/card_extra.dart';
+import 'package:sqflite/sqflite.dart';
+
+class CardExtraDao {
+ Future> getCardExtrasByCardIdAndType(
+ String cardId, CardExtraType cardExtraType,
+ {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query(CardExtra.table,
+ columns: CardExtra.allCols,
+ where: '${CardExtra.cardIdCol} = ? AND ${CardExtra.typeCol} = ?',
+ whereArgs: [cardId, cardExtraType.index],
+ orderBy: CardExtra.serialCol);
+ return maps.map((el) => new CardExtra.fromMap(el)).toList(growable: false);
+ }
+}
diff --git a/lib/db/dao/card_progress_dao.dart b/lib/db/dao/card_progress_dao.dart
new file mode 100644
index 0000000..3fa431c
--- /dev/null
+++ b/lib/db/dao/card_progress_dao.dart
@@ -0,0 +1,100 @@
+import 'dart:async';
+import 'package:maui/app_database.dart';
+import 'package:maui/db/entity/card_progress.dart';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:maui/db/entity/collection.dart';
+import 'package:sqflite/sqflite.dart';
+
+class CardProgressDao {
+ const CardProgressDao();
+
+ Future getCardProgressByCardIdAndUserId(
+ String cardId, String userId,
+ {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query(CardProgress.table,
+ columns: CardProgress.allCols,
+ where:
+ '${CardProgress.cardIdCol} = ? AND ${CardProgress.userIdCol} = ?',
+ whereArgs: [cardId, userId]);
+ if (maps.length > 0) {
+ return CardProgress.fromMap(maps.first);
+ }
+ return null;
+ }
+
+ Future> getCardProgressesByCollectionAndTypeAndUserId(
+ String cardId, CardType cardType, String userId,
+ {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query(
+ '${CardProgress.table}, ${QuackCard.table}, ${Collection.table}',
+ columns: CardProgress.allCols,
+ where: '''
+${Collection.idCol} = ?
+AND ${Collection.cardIdCol} = ${QuackCard.table}.${QuackCard.idCol}
+AND ${QuackCard.table}.${QuackCard.typeCol} = ?
+AND ${CardProgress.table}.${CardProgress.cardIdCol} = ${QuackCard.table}.${QuackCard.idCol}
+AND ${CardProgress.table}.${CardProgress.userIdCol} = ?
+''',
+ whereArgs: [cardId, cardType.index, userId]);
+ return maps.map((el) => CardProgress.fromMap(el)).toList();
+ }
+
+ Future getCardProgressCountByCollectionAndTypeAndUserId(
+ String cardId, CardType cardType, String userId,
+ {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query(
+ '${CardProgress.table}, ${QuackCard.table}, ${Collection.table}',
+ columns: ['count(${CardProgress.table}.${CardProgress.cardIdCol})'],
+ where: '''
+${Collection.idCol} = ?
+AND ${Collection.cardIdCol} = ${QuackCard.table}.${QuackCard.idCol}
+AND ${QuackCard.table}.${QuackCard.typeCol} = ?
+AND ${CardProgress.table}.${CardProgress.cardIdCol} = ${QuackCard.table}.${QuackCard.idCol}
+AND ${CardProgress.table}.${CardProgress.userIdCol} = ?
+''',
+ whereArgs: [cardId, cardType.index, userId]);
+ if (maps.length > 0) {
+ return maps
+ .first['count(${CardProgress.table}.${CardProgress.cardIdCol})'];
+ }
+ return 0;
+ }
+
+ Future getCardProgressCountByCollectionAndUserId(
+ String cardId, String userId,
+ {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query(
+ '${CardProgress.table}, ${QuackCard.table}, ${Collection.table}',
+ columns: ['count(${CardProgress.table}.${CardProgress.cardIdCol})'],
+ where: '''
+${Collection.idCol} = ?
+AND ${Collection.cardIdCol} = ${QuackCard.table}.${QuackCard.idCol}
+AND ${CardProgress.table}.${CardProgress.cardIdCol} = ${QuackCard.table}.${QuackCard.idCol}
+AND ${CardProgress.table}.${CardProgress.userIdCol} = ?
+''',
+ whereArgs: [cardId, userId]);
+ if (maps.length > 0) {
+ return maps
+ .first['count(${CardProgress.table}.${CardProgress.cardIdCol})'];
+ }
+ return 0;
+ }
+
+ Future insert(CardProgress cardProgress, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ await db.insert(CardProgress.table, cardProgress.toMap());
+ return cardProgress;
+ }
+
+ Future update(CardProgress cardProgress, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ return await db.update(CardProgress.table, cardProgress.toMap(),
+ where:
+ "${CardProgress.cardIdCol} = ? AND ${CardProgress.userIdCol} = ?",
+ whereArgs: [cardProgress.cardId, cardProgress.userId]);
+ }
+}
diff --git a/lib/db/dao/collection_dao.dart b/lib/db/dao/collection_dao.dart
new file mode 100644
index 0000000..61ef90d
--- /dev/null
+++ b/lib/db/dao/collection_dao.dart
@@ -0,0 +1,91 @@
+import 'dart:async';
+import 'package:maui/db/entity/quack_card.dart';
+import 'package:sqflite/sqflite.dart';
+
+import 'package:maui/app_database.dart';
+import 'package:maui/db/entity/collection.dart';
+
+class CollectionDao {
+ Future getCollection(String id, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query(Collection.table,
+ columns: Collection.allCols,
+ where: "${Collection.idCol} = ?",
+ whereArgs: [id]);
+ if (maps.length > 0) {
+ return new Collection.fromMap(maps.first);
+ }
+ return null;
+ }
+
+ Future> getCardsInCollection(String id, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query('${QuackCard.table}, ${Collection.table}',
+ columns: QuackCard.allCols,
+ where: '''
+${Collection.idCol} = ?
+AND ${Collection.cardIdCol} = ${QuackCard.table}.${QuackCard.idCol}
+''',
+ whereArgs: [id],
+ orderBy: '${Collection.serialCol}');
+ return maps.map((el) => QuackCard.fromMap(el)).toList();
+ }
+
+ Future> getKnowledgeAndQuizCardsInCollection(String id,
+ {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query('${QuackCard.table}, ${Collection.table}',
+ columns: QuackCard.allCols,
+ where: '''
+${Collection.idCol} = ?
+AND ${Collection.cardIdCol} = ${QuackCard.table}.${QuackCard.idCol}
+AND ${QuackCard.table}.${QuackCard.typeCol} in (?, ?)
+''',
+ whereArgs: [id, CardType.knowledge.index, CardType.question.index],
+ orderBy: '${Collection.serialCol}');
+ return maps.map((el) => QuackCard.fromMap(el)).toList();
+ }
+
+ Future getKnowledgeAndQuizCardCountInCollection(String id,
+ {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query('${QuackCard.table}, ${Collection.table}',
+ columns: ['count(${QuackCard.table}.${QuackCard.idCol})'], where: '''
+${Collection.idCol} = ?
+AND ${Collection.cardIdCol} = ${QuackCard.table}.${QuackCard.idCol}
+AND ${QuackCard.table}.${QuackCard.typeCol} in (?, ?)
+''', whereArgs: [id, CardType.knowledge.index, CardType.question.index]);
+ if (maps.length > 0) {
+ return maps.first['count(${QuackCard.table}.${QuackCard.idCol})'];
+ }
+ return 0;
+ }
+
+ Future getCardCountInCollection(String id, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query('${QuackCard.table}, ${Collection.table}',
+ columns: ['count(${QuackCard.table}.${QuackCard.idCol})'], where: '''
+${Collection.idCol} = ?
+AND ${Collection.cardIdCol} = ${QuackCard.table}.${QuackCard.idCol}
+''', whereArgs: [id]);
+ if (maps.length > 0) {
+ return maps.first['count(${QuackCard.table}.${QuackCard.idCol})'];
+ }
+ return 0;
+ }
+
+ Future getCardCountInCollectionByType(String id, CardType cardType,
+ {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query('${QuackCard.table}, ${Collection.table}',
+ columns: ['count(${QuackCard.table}.${QuackCard.idCol})'], where: '''
+${Collection.idCol} = ?
+AND ${QuackCard.table}.${QuackCard.typeCol} = ?
+AND ${Collection.cardIdCol} = ${QuackCard.table}.${QuackCard.idCol}
+''', whereArgs: [id, cardType.index]);
+ if (maps.length > 0) {
+ return maps.first['count(${QuackCard.table}.${QuackCard.idCol})'];
+ }
+ return 0;
+ }
+}
diff --git a/lib/db/dao/comment_dao.dart b/lib/db/dao/comment_dao.dart
new file mode 100644
index 0000000..bb65220
--- /dev/null
+++ b/lib/db/dao/comment_dao.dart
@@ -0,0 +1,52 @@
+import 'dart:async';
+import 'package:maui/db/entity/tile.dart';
+import 'package:maui/db/entity/user.dart';
+import 'package:sqflite/sqflite.dart';
+import 'package:maui/db/entity/comment.dart';
+
+import 'package:maui/app_database.dart';
+
+class CommentDao {
+ static const Map tableMap = {
+ TileType.card: 'cardComment',
+ TileType.drawing: 'tileComment',
+ TileType.message: 'tileComment'
+ };
+
+ Future> getCommentsByParentId(
+ String parentId, TileType tileType,
+ {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query(
+ '${tableMap[tileType]} ${Comment.table}, ${User.table}',
+ columns: Comment.allCols,
+ where: '''
+${Comment.table}.${Comment.parentIdCol} = ?
+AND ${Comment.table}.${Comment.userIdCol} = ${User.table}.${User.idCol}
+''',
+ whereArgs: [parentId],
+ orderBy: "${Comment.timeStampCol} DESC",
+ );
+ return maps.map((el) => new Comment.fromMap(el)).toList(growable: true);
+ }
+
+ Future insert(Comment tileComment, TileType tileType,
+ {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ await db.insert(tableMap[tileType], tileComment.toMap());
+ }
+
+ Future delete(Comment tileComment, TileType tileType,
+ {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ await db.delete(tableMap[tileType],
+ where: '${Comment.idCol} = ?', whereArgs: [tileComment.id]);
+ }
+
+ Future update(Comment tileComment, TileType tileType,
+ {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ await db.update(tableMap[tileType], tileComment.toMap(),
+ where: '${Comment.idCol} = ?', whereArgs: [tileComment.id]);
+ }
+}
diff --git a/lib/db/dao/comments_dao.dart b/lib/db/dao/comments_dao.dart
new file mode 100644
index 0000000..6a292b4
--- /dev/null
+++ b/lib/db/dao/comments_dao.dart
@@ -0,0 +1,52 @@
+import 'dart:async';
+import 'package:sqflite/sqflite.dart';
+import 'package:maui/db/entity/comments.dart';
+
+import 'package:maui/app_database.dart';
+
+class CommentsDao {
+ Future> getCommentsByTileId(String tileId,
+ {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query(
+ Comments.table,
+ columns: [
+ Comments.tileIdCol,
+ Comments.commentCol,
+ Comments.timeStampCol,
+ Comments.commentingUserIdCol
+ ],
+ where: " ${Comments.tileIdCol} = ? ",
+ whereArgs: [tileId],
+ // orderBy: "${Comments.timeStampCol}",
+ );
+ if (maps.length > 0) {
+ return maps.map((el) => new Comments.fromMap(el)).toList(growable: true);
+ }
+ return null;
+ }
+
+ Future insertAComment(Comments comments, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ await db.insert(Comments.table, comments.toMap());
+ }
+
+ Future deleteAComment(Comments comments, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ await db.delete(Comments.table,
+ where: ''' ${Comments.tileIdCol} = ? AND ${Comments.commentCol} = ?''',
+ whereArgs: [comments.tileId, comments.comment]);
+ }
+
+ Future updateAComment(Comments comments, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ await db.update(Comments.table, comments.toMap(),
+ where:
+ ''' ${Comments.tileIdCol} = ? AND ${Comments.commentingUserIdCol} = ? AND ${Comments.timeStampCol} = ?''',
+ whereArgs: [
+ comments.tileId,
+ comments.commentingUserId,
+ comments.timeStamp
+ ]);
+ }
+}
diff --git a/lib/db/dao/drawing_dao.dart b/lib/db/dao/drawing_dao.dart
deleted file mode 100644
index 2e7a93a..0000000
--- a/lib/db/dao/drawing_dao.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-import 'dart:async';
-import 'package:maui/app_database.dart';
-import 'package:maui/db/entity/drawing.dart';
-import 'package:sqflite/sqflite.dart';
-
-class DrawingDao {
- Future getDrawing(String id, {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- List maps = await db.query(Drawing.table,
- columns: Drawing.allCols,
- where: "${Drawing.idCol} = ? ",
- whereArgs: [id]);
- if (maps.length > 0) {
- return Drawing.fromMap(maps.first);
- }
- return null;
- }
-
- Future> getDrawingsByActivityId(String activityId,
- {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- List maps = await db.query(Drawing.table,
- columns: Drawing.allCols,
- where: "${Drawing.activityIdCol} = ? ",
- whereArgs: [activityId]);
- return maps.map((el) => new Drawing.fromMap(el)).toList();
- }
-
- Future getLatestDrawingByActivityId(String activityId,
- {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- List maps = await db.query(Drawing.table,
- columns: Drawing.allCols,
- where: "${Drawing.activityIdCol} = ? ",
- whereArgs: [activityId],
- orderBy: '${Drawing.updatedAtCol} DESC',
- limit: 1);
- if (maps.length > 0) {
- return Drawing.fromMap(maps.first);
- }
- return null;
- }
-
- Future insert(Drawing drawing, {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- await db.insert(Drawing.table, drawing.toMap());
- return drawing;
- }
-
- Future delete(int id, {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- return await db
- .delete(Drawing.table, where: "${Drawing.idCol} = ?", whereArgs: [id]);
- }
-
- Future update(Drawing drawing, {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- return await db.update(Drawing.table, drawing.toMap(),
- where: "${Drawing.idCol} = ?", whereArgs: [drawing.id]);
- }
-}
diff --git a/lib/db/dao/home_page_dao.dart b/lib/db/dao/home_page_dao.dart
new file mode 100644
index 0000000..0575e21
--- /dev/null
+++ b/lib/db/dao/home_page_dao.dart
@@ -0,0 +1,35 @@
+import 'dart:async';
+import 'package:sqflite/sqflite.dart';
+import 'package:maui/db/entity/home.dart';
+
+import 'package:maui/app_database.dart';
+
+class HomeDao {
+ Future> getHomeTiles({Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query(
+ Home.table,
+ columns: [
+ Home.tileIdCol,
+ Home.typeCol,
+ Home.typeIdCol,
+ Home.userIdCol,
+ ],
+ );
+ if (maps.length > 0) {
+ return maps.map((el) => new Home.fromMap(el)).toList(growable: true);
+ }
+ return null;
+ }
+
+ Future insertAHomeTile(Home home, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ await db.insert(Home.table, home.toMap());
+ }
+
+ Future deleteAHomeTile(Home home, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ await db.delete(Home.table,
+ where: ''' ${Home.tileIdCol} = ? ''', whereArgs: [home.tileId]);
+ }
+}
diff --git a/lib/db/dao/like_dao.dart b/lib/db/dao/like_dao.dart
new file mode 100644
index 0000000..4320d34
--- /dev/null
+++ b/lib/db/dao/like_dao.dart
@@ -0,0 +1,70 @@
+import 'dart:async';
+import 'package:maui/db/entity/tile.dart';
+import 'package:maui/db/entity/user.dart';
+import 'package:sqflite/sqflite.dart';
+import 'package:maui/db/entity/like.dart';
+
+import 'package:maui/app_database.dart';
+
+class LikeDao {
+ static const Map tableMap = {
+ TileType.card: 'cardLike',
+ TileType.drawing: 'tileLike',
+ TileType.message: 'tileLike'
+ };
+
+ Future> getLikesByParentId(String parentId, TileType tileType,
+ {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query(
+ '${tableMap[tileType]} ${Like.table}, ${User.table}',
+ columns: Like.allCols,
+ where: '''
+${Like.table}.${Like.parentIdCol} = ?
+AND ${Like.table}.${Like.userIdCol} = ${User.table}.${User.idCol}
+''',
+ whereArgs: [parentId],
+ orderBy: "${Like.timeStampCol}",
+ );
+ if (maps.length > 0) {
+ return maps.map((el) => new Like.fromMap(el)).toList(growable: true);
+ }
+ return null;
+ }
+
+ Future getLikeByParentIdAndUserId(
+ String parentId, String userId, TileType tileType,
+ {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query(
+ '${tableMap[tileType]} ${Like.table}, ${User.table}',
+ columns: Like.allCols,
+ where: '''
+${Like.table}.${Like.parentIdCol} = ?
+AND ${Like.table}.${Like.userIdCol} = ?
+AND ${Like.table}.${Like.userIdCol} = ${User.table}.${User.idCol}
+''',
+ whereArgs: [parentId, userId]);
+ if (maps.length > 0) {
+ return Like.fromMap(maps.first);
+ }
+ return null;
+ }
+
+ Future insert(Like tileLike, TileType tileType, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ await db.insert(tableMap[tileType], tileLike.toMap());
+ }
+
+ Future delete(Like tileLike, TileType tileType, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ await db.delete(tableMap[tileType],
+ where: '${Like.idCol} = ?', whereArgs: [tileLike.id]);
+ }
+
+ Future update(Like tileLike, TileType tileType, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ await db.update(tableMap[tileType], tileLike.toMap(),
+ where: '${Like.idCol} = ?', whereArgs: [tileLike.id]);
+ }
+}
diff --git a/lib/db/dao/likes_dao.dart b/lib/db/dao/likes_dao.dart
new file mode 100644
index 0000000..932609c
--- /dev/null
+++ b/lib/db/dao/likes_dao.dart
@@ -0,0 +1,49 @@
+import 'dart:async';
+import 'package:sqflite/sqflite.dart';
+import 'package:maui/db/entity/likes.dart';
+
+import 'package:maui/app_database.dart';
+
+class LikesDao {
+ Future> getLikesByTileId(String tileId, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query(
+ Likes.table,
+ columns: [Likes.tileIdCol, Likes.likedUserIdCol],
+ where: " ${Likes.tileIdCol} = ? ",
+ whereArgs: [tileId],
+ );
+ if (maps.length > 0) {
+ return maps.map((el) => new Likes.fromMap(el)).toList(growable: true);
+ }
+ return null;
+ }
+
+ Future getLikesByTileIdAndLikedUserId(
+ String tileId, String likedUserId,
+ {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ List maps = await db.query(
+ Likes.table,
+ columns: [Likes.tileIdCol, Likes.likedUserIdCol],
+ where: " ${Likes.tileIdCol} = ? AND ${Likes.likedUserIdCol} = ? ",
+ whereArgs: [tileId, likedUserId],
+ );
+ if (maps.length > 0) {
+ return new Likes.fromMap(maps.first);
+ }
+ return null;
+ }
+
+ Future insertALike(Likes likes, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ await db.insert(Likes.table, likes.toMap());
+ }
+
+ Future deleteALike(Likes likes, {Database db}) async {
+ db = db ?? await new AppDatabase().getDb();
+ await db.delete(Likes.table,
+ where: ''' ${Likes.tileIdCol} = ? AND ${Likes.likedUserIdCol} = ? ''',
+ whereArgs: [likes.tileId, likes.likedUserId]);
+ }
+}
diff --git a/lib/db/dao/notif_dao.dart b/lib/db/dao/notif_dao.dart
index ec6d5b7..9cb1174 100644
--- a/lib/db/dao/notif_dao.dart
+++ b/lib/db/dao/notif_dao.dart
@@ -69,11 +69,9 @@ class NotifDao {
List maps = await db.query(Notif.table,
columns: [Notif.typeCol, 'count(${Notif.typeCol})'],
groupBy: '${Notif.typeCol}');
- print('getNotifCountByType: $maps');
Map returnMap = Map();
maps.forEach(
(n) => returnMap[n[Notif.typeCol]] = n['count(${Notif.typeCol})']);
- print('getNotifCountByType: $returnMap');
return returnMap;
}
diff --git a/lib/db/dao/quiz_dao.dart b/lib/db/dao/quiz_dao.dart
deleted file mode 100644
index 55b3403..0000000
--- a/lib/db/dao/quiz_dao.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-import 'dart:async';
-
-import 'package:maui/app_database.dart';
-import 'package:maui/db/entity/quiz.dart';
-import 'package:sqflite/sqflite.dart';
-
-class QuizDao {
- Future getQuiz(int id, {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- List maps = await db.query(Quiz.table,
- columns: [
- Quiz.idCol,
- Quiz.topicIdCol,
- Quiz.levelCol,
- Quiz.typeCol,
- Quiz.contentCol
- ],
- where: "${Quiz.idCol} = ?",
- whereArgs: [id]);
- if (maps.length > 0) {
- return new Quiz.fromMap(maps.first);
- }
- return null;
- }
-
- Future> getQuizzesByTopicId(String topicId, {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- List maps = await db.query(Quiz.table,
- columns: [
- Quiz.idCol,
- Quiz.topicIdCol,
- Quiz.levelCol,
- Quiz.typeCol,
- Quiz.contentCol
- ],
- where: "${Quiz.topicIdCol} = ?",
- whereArgs: [topicId]);
- return maps.map((el) => new Quiz.fromMap(el)).toList();
- }
-}
diff --git a/lib/db/dao/quiz_progress_dao.dart b/lib/db/dao/quiz_progress_dao.dart
deleted file mode 100644
index 87372cd..0000000
--- a/lib/db/dao/quiz_progress_dao.dart
+++ /dev/null
@@ -1,73 +0,0 @@
-import 'dart:async';
-import 'package:maui/app_database.dart';
-import 'package:maui/db/entity/quiz_progress.dart';
-import 'package:sqflite/sqflite.dart';
-
-class QuizProgressDao {
- Future getScoreSummaryByTopicId(String topicId, {Database db}) async {
- print("Topic Id received by Quiz Progress Dao - $topicId");
- db = db ?? await new AppDatabase().getDb();
-
- List maxScoreSum = (await db.query(QuizProgress.table,
- columns: ['sum(${QuizProgress.maxScoreCol})'],
- where: "${QuizProgress.topicIdCol} = ?",
- whereArgs: [topicId]));
-
- List outOfTotalScoreSum = (await db.query(QuizProgress.table,
- columns: ['sum(${QuizProgress.outOfTotalCol})'],
- where: "${QuizProgress.topicIdCol} = ?",
- whereArgs: [topicId]));
-
- print("Value of maxScoreSum = ${maxScoreSum.first["sum(maxScore)"]}");
- print(
- "Value of outOfTotalScoreSum = ${outOfTotalScoreSum.first["sum(outOfTotal)"]}");
-
- if (maxScoreSum != null) {
- return (maxScoreSum.first["sum(maxScore)"] /
- outOfTotalScoreSum.first["sum(outOfTotal)"]);
- } else {
- return null;
- }
- }
-
- Future getQuizProgressByTopicAndQuizId(
- String topicId, String quizId,
- {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- List maps = await db.query(QuizProgress.table,
- columns: [
- QuizProgress.idCol,
- QuizProgress.userIdCol,
- QuizProgress.topicIdCol,
- QuizProgress.quizIdCol,
- QuizProgress.maxScoreCol,
- QuizProgress.outOfTotalCol
- ],
- where:
- '''${QuizProgress.topicIdCol} = ? AND ${QuizProgress.quizIdCol} = ?''',
- whereArgs: [
- topicId,
- quizId
- ]);
- print("Topic Id received in QuizprogressDao - $topicId");
- if (maps.length > 0) {
- return QuizProgress.fromMap(maps.first);
- }
- return null;
- }
-
- Future insertQuizProgress(QuizProgress quizProgress,
- {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- await db.insert(QuizProgress.table, quizProgress.toMap());
- }
-
- Future updateQuizProgress(QuizProgress quizProgress,
- {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- await db.update(QuizProgress.table, quizProgress.toMap(),
- where:
- '''${QuizProgress.topicIdCol} = ? AND ${QuizProgress.quizIdCol} = ?''',
- whereArgs: [quizProgress.topicId, quizProgress.quizId]);
- }
-}
diff --git a/lib/db/dao/related_topic_dao.dart b/lib/db/dao/related_topic_dao.dart
deleted file mode 100644
index c459ca2..0000000
--- a/lib/db/dao/related_topic_dao.dart
+++ /dev/null
@@ -1,44 +0,0 @@
-import 'dart:async';
-
-import 'package:maui/app_database.dart';
-import 'package:maui/db/entity/related_topic.dart';
-import 'package:maui/db/entity/topic.dart';
-import 'package:sqflite/sqflite.dart';
-
-class RelatedTopicDao {
- Future> getRelatedTopicsByTopicId(String topicId,
- {Database db}) async {
- db = db ?? await new AppDatabase().getDb();
- List