Skip to content

Commit

Permalink
Merge pull request #4 from tiagodread/add-model
Browse files Browse the repository at this point in the history
feat: Refactor model and add sqlite database
  • Loading branch information
tiagodread authored Aug 2, 2024
2 parents 95849a0 + 292cd05 commit 7571740
Show file tree
Hide file tree
Showing 17 changed files with 511 additions and 83 deletions.
10 changes: 2 additions & 8 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Test, Build and Release apk
name: Build & Test

on: push

Expand Down Expand Up @@ -33,10 +33,4 @@ jobs:
run: flutter test

- name: Build APP
run: flutter build apk --release

# - name: Push APK to Releases
# uses: ncipollo/release-action@v1
# with:
# artifacts: "build/app/outputs/apk/debug/*.apk"
# token: ${{ secrets.TOKEN }}
run: flutter build apk --release
45 changes: 45 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Release APK

on:
push:
branches:
- main

env:
FLUTTER_VERSION: 3.22.3

jobs:
build:
name: Build APK
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup JDK
uses: actions/setup-java@v3
with:
java-version: 11
distribution: "zulu"

- name: Install Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
channel: "stable"
architecture: x64

- name: Install Dependencies
run: flutter pub get

- name: Run tests
run: flutter test

- name: Build APP
run: flutter build apk --release

- name: Push APK to Releases
uses: ncipollo/release-action@v1
with:
artifacts: "build/app/outputs/flutter-apk/*.apk"
token: ${{ secrets.TOKEN }}
1 change: 1 addition & 0 deletions ios/Flutter/Debug.xcconfig
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
1 change: 1 addition & 0 deletions ios/Flutter/Release.xcconfig
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
44 changes: 44 additions & 0 deletions ios/Podfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '12.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}

def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end

File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_ios_podfile_setup

target 'Runner' do
use_frameworks!
use_modular_headers!

flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end

post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end
5 changes: 3 additions & 2 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:todo/models/task_model.dart';
import 'package:todo/repositories/sqlite_task_repository.dart';
import 'package:todo/screens/home_screen.dart';

void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(ChangeNotifierProvider(
create: (context) => TaskModel(),
create: (context) => SQLiteTaskRepository(),
child: const App(),
));
}
Expand Down
47 changes: 47 additions & 0 deletions lib/models/task.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import 'package:uuid/uuid.dart';

class Task {
String id;
String title;
String description;
DateTime createdAt;
DateTime? completedAt;
bool isCompleted;
int? rewardInSatoshis;

Task({
String? id,
required this.title,
required this.description,
required this.createdAt,
this.completedAt,
this.isCompleted = false,
this.rewardInSatoshis = 0,
}) : id = id ?? const Uuid().v4();

Map<String, dynamic> toMap() {
return {
'id': id,
'title': title,
'description': description,
'createdAt': createdAt.toIso8601String(),
'completedAt': completedAt?.toIso8601String(),
'isCompleted': isCompleted,
'rewardInSatoshis': rewardInSatoshis,
};
}

factory Task.fromMap(Map<String, dynamic> map) {
return Task(
id: map['id'],
title: map['title'],
description: map['description'],
createdAt: DateTime.parse(map['createdAt']),
completedAt: (map['completedAt'] == null || map['completedAt'] == 'null')
? null
: DateTime.parse(map['completedAt']),
isCompleted: map['isCompleted'] == 0 ? false : true,
rewardInSatoshis: map['rewardInSatoshis'],
);
}
}
11 changes: 0 additions & 11 deletions lib/models/task_model.dart

This file was deleted.

87 changes: 87 additions & 0 deletions lib/repositories/sqlite_task_repository.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import 'package:flutter/cupertino.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import '../models/task.dart';
import 'task_repository.dart';

class SQLiteTaskRepository extends ChangeNotifier implements TaskRepository {
Database? _database;

Future<Database> get database async {
if (_database != null) return _database!;
_database = await _initDatabase();
return _database!;
}

Future<Database> _initDatabase() async {
// await deleteDatabase(join(await getDatabasesPath(), 'tasks.db'));
return openDatabase(
join(await getDatabasesPath(), 'tasks.db'),
onCreate: (db, version) {
return db.execute(
'CREATE TABLE tasks(id TEXT PRIMARY KEY, title TEXT, description TEXT, createdAt TEXT, completedAt TEXT, isCompleted INTEGER, rewardInSatoshis INTEGER)',
);
},
version: 1,
);
}

@override
Future<List<Task>> getAllTasks() async {
final db = await database;
final List<Map<String, dynamic>> maps =
await db.query('tasks', orderBy: 'createdAt DESC');

return List.generate(maps.length, (i) {
return Task.fromMap(maps[i]);
});
}

@override
Future<Task?> getTaskById(String id) async {
final db = await database;
final List<Map<String, dynamic>> maps = await db.query(
'tasks',
where: 'id = ?',
whereArgs: [id],
);

if (maps.isNotEmpty) {
return Task.fromMap(maps.first);
} else {
return null;
}
}

@override
Future<void> addTask(Task task) async {
final db = await database;
await db.insert(
'tasks',
task.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
notifyListeners();
}

@override
Future<void> updateTask(Task task) async {
final db = await database;
await db.update(
'tasks',
task.toMap(),
where: 'id = ?',
whereArgs: [task.id],
);
}

@override
Future<void> deleteTask(String id) async {
final db = await database;
await db.delete(
'tasks',
where: 'id = ?',
whereArgs: [id],
);
}
}
9 changes: 9 additions & 0 deletions lib/repositories/task_repository.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import '../models/task.dart';

abstract class TaskRepository {
Future<List<Task>> getAllTasks();
Future<Task?> getTaskById(String id);
Future<void> addTask(Task task);
Future<void> updateTask(Task task);
Future<void> deleteTask(String id);
}
43 changes: 32 additions & 11 deletions lib/widgets/task_add_widget.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:todo/models/task_model.dart';
import 'package:todo/models/task.dart';
import 'package:todo/repositories/task_repository.dart';

import '../repositories/sqlite_task_repository.dart';

class AddTask extends StatefulWidget {
const AddTask({
Expand All @@ -12,6 +15,15 @@ class AddTask extends StatefulWidget {

class _AddTaskState extends State<AddTask> {
final textController = TextEditingController();
late SQLiteTaskRepository taskRepository;
late Future<List<Task>> taskListFuture;

@override
void initState() {
super.initState();
taskRepository = SQLiteTaskRepository();
taskListFuture = taskRepository.getAllTasks();
}

@override
void dispose() {
Expand All @@ -28,6 +40,7 @@ class _AddTaskState extends State<AddTask> {
child: Padding(
padding: const EdgeInsets.only(left: 20.0),
child: TextField(
key: const Key("task-input"),
controller: textController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
Expand All @@ -39,16 +52,24 @@ class _AddTaskState extends State<AddTask> {
flex: 1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Consumer(
builder: (context, value, child) => ElevatedButton(
onPressed: () {
final widget = context.read<TaskModel>();
if (textController.text.isNotEmpty) {
widget.addTask(textController.text);
textController.clear();
}
},
child: const Text("ADD")))),
child: ElevatedButton(
key: const Key("task-add-button"),
onPressed: () async {
if (textController.text.isNotEmpty) {
Task task = Task(
title: textController.text,
description: '',
createdAt: DateTime.now(),
isCompleted: false,
rewardInSatoshis: 0,
);
await Provider.of<SQLiteTaskRepository>(context,
listen: false)
.addTask(task);
textController.clear();
}
},
child: const Text("ADD"))),
),
],
);
Expand Down
Loading

0 comments on commit 7571740

Please sign in to comment.