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

refractor: update code and project to use latest Appwrite SDK #23

Merged
merged 21 commits into from Aug 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 12 additions & 6 deletions lib/built_with_appwrite_wrapper.dart
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher/url_launcher_string.dart';

class BuiltWithAppwriteWrapper extends StatelessWidget {
const BuiltWithAppwriteWrapper({Key? key, required this.child})
Expand All @@ -17,12 +18,17 @@ class BuiltWithAppwriteWrapper extends StatelessWidget {
),
const SizedBox(height: 10.0),
GestureDetector(
onTap: () {
try {
launchUrl(Uri.parse('https://appwrite.io'));
} catch (e) {}
},
child: SvgPicture.asset('assets/built-with-appwrite-hr.svg')),
onTap: () async {
//
bool canLaunch = await canLaunchUrlString(
'https://appwrite.io',
);
//
canLaunch ? launchUrl(Uri.parse('https://appwrite.io')) : null;
//
},
child: SvgPicture.asset('assets/built-with-appwrite-hr.svg'),
),
const SizedBox(height: 10.0),
],
),
Expand Down
1 change: 1 addition & 0 deletions lib/constants.dart
Expand Up @@ -2,4 +2,5 @@ class AppConstants {
static const String endPoint = "https://demo.appwrite.io/v1";
static const String project = "606d5bc9de604";
static const String collection = "quiz_questions";
static const String database = "default";
}
4 changes: 3 additions & 1 deletion lib/home.dart
Expand Up @@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_appwrite_quizeee/quiz.dart';

class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Scaffold(
Expand All @@ -23,7 +25,7 @@ class HomePage extends StatelessWidget {
),
onPressed: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => QuizPage(),
builder: (_) => const QuizPage(),
),
),
),
Expand Down
6 changes: 4 additions & 2 deletions lib/main.dart
Expand Up @@ -4,18 +4,20 @@ import 'package:flutter_appwrite_quizeee/built_with_appwrite_wrapper.dart';
import 'home.dart';

void main() {
runApp(MyApp());
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Appwrite Quizeee',
theme: ThemeData(
primarySwatch: Colors.red,
),
home: BuiltWithAppwriteWrapper(child: HomePage()),
home: const BuiltWithAppwriteWrapper(child: HomePage()),
);
}
}
72 changes: 28 additions & 44 deletions lib/question.dart
@@ -1,33 +1,22 @@
import 'dart:convert';

import 'package:flutter/foundation.dart';

class Question {
String? id;
String? question;
List<String>? options;
String? answer;
Question({
this.id,
this.question,
this.options,
this.answer,
import 'package:appwrite/models.dart';
import 'package:equatable/equatable.dart';

class Question extends Equatable {
//
final String id;
final String question;
final List<String> options;
final String answer;
//
const Question({
required this.id,
required this.question,
required this.options,
required this.answer,
});

Question copyWith({
String? id,
String? question,
List<String>? options,
String? answer,
}) {
return Question(
id: id ?? this.id,
question: question ?? this.question,
options: options ?? this.options,
answer: answer ?? this.answer,
);
}

Map<String, dynamic> toMap() {
return {
'id': id,
Expand All @@ -39,6 +28,15 @@ class Question {

/* Give a man a program, frustrate him for a day.
Teach a man to program, frustrate him for a lifetime */
factory Question.fromModel(Document document) {
return Question(
id: document.$id,
question: document.data['question'],
options: List<String>.from(document.data['options']),
answer: document.data['answer']
);
}

factory Question.fromMap(Map<String?, dynamic> map) {
return Question(
id: map['\$id'],
Expand All @@ -50,29 +48,15 @@ Teach a man to program, frustrate him for a lifetime */

String toJson() => json.encode(toMap());

factory Question.fromJson(String source) => Question.fromMap(json.decode(source));
factory Question.fromJson(String source) =>
Question.fromMap(json.decode(source));

@override
String toString() {
return 'Question(id: $id, question: $question, options: $options, answer: $answer)';
}

@override
bool operator ==(Object other) {
if (identical(this, other)) return true;

return other is Question &&
other.id == id &&
other.question == question &&
listEquals(other.options, options) &&
other.answer == answer;
}

/// Equality Operator
@override
int get hashCode {
return id.hashCode ^
question.hashCode ^
options.hashCode ^
answer.hashCode;
}
List<Object> get props => [id, question, options, answer];
}
93 changes: 49 additions & 44 deletions lib/quiz.dart
@@ -1,11 +1,14 @@
import 'package:appwrite/appwrite.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_appwrite_quizeee/constants.dart';
import 'package:flutter_appwrite_quizeee/question.dart';

class QuizPage extends StatefulWidget {
const QuizPage({Key? key}) : super(key: key);

@override
_QuizPageState createState() => _QuizPageState();
State<QuizPage> createState() => _QuizPageState();
}

class _QuizPageState extends State<QuizPage> {
Expand All @@ -32,15 +35,19 @@ class _QuizPageState extends State<QuizPage> {
Client client = Client(endPoint: AppConstants.endPoint);
client.setProject(AppConstants.project);

Database db = Database(client);
Databases db = Databases(client, databaseId: AppConstants.database);
/* I'm not a great programmer; I'm just a good programmer with great habits. */
try {
final res = await db.listDocuments(collectionId: AppConstants.collection);
questions = res.convertTo<Question>(
(q) => Question.fromMap(q as Map<String?, dynamic>));

// Convert using Model instead
questions = res.documents.isEmpty
? []
: res.documents.map((e) => Question.fromModel(e)).toList();

questions!.shuffle();
} on AppwriteException catch (e) {
print(e);
if(kDebugMode) print(e);
} finally {
setState(() {
loading = false;
Expand All @@ -56,7 +63,7 @@ class _QuizPageState extends State<QuizPage> {
title: Text("Score: $score"),
),
body: loading
? Center(
? const Center(
child: CircularProgressIndicator(),
)
: questions != null && questions!.isNotEmpty
Expand All @@ -66,38 +73,38 @@ class _QuizPageState extends State<QuizPage> {
itemCount: questions!.length,
itemBuilder: (context, index) {
final question = questions![index];
return Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
question.question!,
style: Theme.of(context).textTheme.headline5,
),
const SizedBox(height: 10.0),
...question.options!.map(
(opt) => Card(
color: _getColor(question, opt),
elevation: 1,
clipBehavior: Clip.antiAlias,
child: RadioListTile(
value: opt,
title: Text(opt),
groupValue: _answers[question.id],
onChanged: _answers[question.id] != null
? null
: (dynamic opt) {
if (opt == question.answer)
score += 5;
setState(() {
_answers[question.id] = opt;
});
},
),
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
question.question,
style: Theme.of(context).textTheme.headline5,
),
const SizedBox(height: 10.0),
...question.options.map(
(opt) => Card(
color: _getColor(question, opt),
elevation: 1,
clipBehavior: Clip.antiAlias,
child: RadioListTile(
value: opt,
title: Text(opt),
groupValue: _answers[question.id],
onChanged: _answers[question.id] != null
? null
: (dynamic opt) {
if (opt == question.answer) {
score += 5;
}

setState(() {
_answers[question.id] = opt;
});
},
),
)
],
),
),
)
],
);
},
controller: _controller,
Expand All @@ -108,13 +115,11 @@ class _QuizPageState extends State<QuizPage> {
},
),
)
: Container(
child: Text("Some error! Check console"),
),
: const Text("Some error! Check console"),
/* A language that doesn't affect the way you think about programming is not worth knowing. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's outdated now. You can remove these comments too😆

bottomNavigationBar: (questions != null && questions!.isNotEmpty)
? BottomAppBar(
child: Container(
child: SizedBox(
height: 60.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
Expand All @@ -125,23 +130,23 @@ class _QuizPageState extends State<QuizPage> {
: () {
_controller!.jumpToPage(currentPage - 1);
},
child: Text("Prev"),
child: const Text("Prev"),
),
const SizedBox(width: 10.0),
(currentPage == questions!.length - 1)
? ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("Done"),
child: const Text("Done"),
)
: ElevatedButton(
onPressed: currentPage >= questions!.length - 1
? null
: () {
_controller!.jumpToPage(currentPage + 1);
},
child: Text("Next"),
child: const Text("Next"),
),
],
),
Expand Down