hp_data 0.0.1 hp_data: ^0.0.1 copied to clipboard
Local data implementation has been more secure and easier by using encryption in shared preferences and SQL cipher.
import 'dart:async';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hp_data/access/id/access.dart' as a;
import 'package:hp_data/factory/factory.dart';
import 'package:hp_data/hp_data.dart';
import 'package:hp_data/model/id/model.dart';
import 'package:hp_data/model/model.dart' as b;
import 'package:hp_data/sqflite/column/id/sqflite.dart' as c;
import 'package:hp_data/sqflite/column/sqflite.dart' as d;
import 'package:hp_data/sqflite/table/id/sqflite.dart' as e;
import 'package:hp_data/sqflite/table/sqflite.dart' as f;
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
final _hpDataPlugin = HpData();
final List<BookModel> _bookList = [];
@override
void initState() {
super.initState();
initPlatformState();
refresh();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
// We also handle the message potentially returning null.
try {
platformVersion = await _hpDataPlugin.getPlatformVersion() ??
'Unknown platform version';
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Column(children: [
Flexible(
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: SingleChildScrollView(
padding: const EdgeInsets.only(bottom: 8.0),
physics: const ClampingScrollPhysics(),
child: Column(
children: List.generate(
_bookList.length,
(final int index) => Padding(
key: ValueKey(_bookList[index].id),
padding: EdgeInsets.fromLTRB(
8.0,
index > 0 ? 4.0 : 12.0,
8.0,
index < _bookList.length - 1
? 4.0
: 12.0),
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 4.0, horizontal: 8.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius:
BorderRadius.circular(8.0),
boxShadow: [
BoxShadow(
color: Colors.black38
.withOpacity(.5),
offset:
const Offset(.2, 1.5))
]),
width: double.infinity,
child: Column(children: [
SizedBox(
width: double.infinity,
child: Text(
'ID [${_bookList[index].id.toString()}]')),
SizedBox(
width: double.infinity,
child: Text(_bookList[index]
.title
.toUpperCase())),
SizedBox(
width: double.infinity,
child: Text(_bookList[index]
.published ==
null
? '- Unknown publish date -'
: '${_bookList[index].published?.day.toString()} - ${_bookList[index].published?.month.toString()} - ${_bookList[index].published?.year.toString()}')),
SizedBox(
width: double.infinity,
child: Text(
'IDR ${_bookList[index].price.toString()}'))
])))))))),
Center(child: Text('Running on: $_platformVersion\n'))
]),
floatingActionButton: GestureDetector(
onTap: _addMoreBook,
child: Container(
decoration: BoxDecoration(
color: Colors.orangeAccent,
boxShadow: [
BoxShadow(
color: Colors.black38.withOpacity(.5),
offset: const Offset(.2, 1.5))
],
shape: BoxShape.circle),
width: 55.0,
height: 55.0,
child: const Center(child: Icon(Icons.plus_one)))),
backgroundColor: Colors.white70),
scrollBehavior: ScrollBehavior());
}
Future<void> _addMoreBook() async {
final DateTime now = DateTime.now();
final BookModel book = BookModel(
Factory().business.random.generateRandomInt(minimum: 1, maximum: 1000),
title:
'${Factory().business.random.generateRandomString(Factory().business.random.generateRandomInt(minimum: 1, maximum: 8), includeUppercase: false, includeNumber: false)} ${Factory().business.random.generateRandomString(Factory().business.random.generateRandomInt(minimum: 1, maximum: 8), includeUppercase: false, includeNumber: false)}',
published: now.second % 2 == 0
? now.subtract(Duration(
days: Factory()
.business
.random
.generateRandomInt(minimum: 1, maximum: 5000)))
: null,
price: Factory()
.business
.random
.generateRandomInt(minimum: 1000, maximum: 500000) /
100);
await MyFactory().access.book.insert(book);
refresh();
}
Future<void> refresh() async {
_bookList.clear();
_bookList.addAll(await MyFactory().access.book.selectAll());
setState(() {});
}
}
class BookModel extends Model {
final String title;
final DateTime? published;
final double price;
BookModel(final int id,
{required this.title, this.published, required this.price})
: super(id);
}
class BookTable extends e.Sqflite {
BookTable() : super('BCMZTI', id: c.Sqflite('IUYHQT'));
d.Sqflite get title => d.Sqflite('R95FHB', isNullable: false);
d.Sqflite get published => d.Sqflite('KGOVWO');
d.Sqflite get price => d.Sqflite('DVTMB8', isNullable: false);
@override
List<d.Sqflite> get columnList => [id, title, published, price];
@override
List<d.Sqflite> get uniqueColumnList => [];
}
class TableFactory {
BookTable? _book;
BookTable get book {
_book ??= BookTable();
return _book!;
}
List<f.Sqflite> get values => [book];
}
abstract class IdAccess extends a.Access {
@override
List<f.Sqflite> get sqfliteTableList => MyFactory().table.values;
@override
int get sqfliteVersion => 1;
}
class BookAccess extends IdAccess {
@override
Future<List<BookModel>> selectAll() async {
final List<b.Model> list = await super.selectAll();
final List<BookModel> bookList = [];
for (final b.Model object in list) {
bookList.add(object as BookModel);
}
return bookList;
}
@override
Future<String?> encryptId(final dynamic id) async =>
await encryptionFactory.int.encrypt(id);
@override
Future<int?> decryptId(final String? id) async =>
await encryptionFactory.int.decrypt(id);
@override
Future<Map<String, dynamic>> toMap(final b.Model? model) async {
if (model == null) {
return {};
}
return {
sqfliteTable.id.name: await encryptId((model as BookModel).id),
sqfliteTable.title.name:
await encryptionFactory.string.encrypt(model.title),
sqfliteTable.published.name: await encryptionFactory.int.encrypt(
model.published?.millisecondsSinceEpoch),
sqfliteTable.price.name:
await encryptionFactory.double.encrypt(model.price)
};
}
@override
Future<BookModel?> toModel(final Map<String, dynamic> map) async {
if (map.isEmpty) {
return null;
}
return BookModel(
(await encryptionFactory.int.decrypt(map[sqfliteTable.id.name]))!,
title: (await encryptionFactory.string
.decrypt(map[sqfliteTable.title.name]))!,
published: map[sqfliteTable.published.name] == null
? null
: DateTime.fromMillisecondsSinceEpoch(
(await encryptionFactory.int.decrypt(
map[sqfliteTable.published.name]))!),
price: (await encryptionFactory.double.decrypt(
map[sqfliteTable.price.name]))!);
}
@override
BookTable get sqfliteTable => MyFactory().table.book;
}
class AccessFactory {
BookAccess? _book;
BookAccess get book {
_book ??= BookAccess();
return _book!;
}
}
class MyFactory {
static final MyFactory _instance = MyFactory._();
AccessFactory? _access;
TableFactory? _table;
factory MyFactory() => _instance;
MyFactory._();
AccessFactory get access {
_access ??= AccessFactory();
return _access!;
}
TableFactory get table {
_table ??= TableFactory();
return _table!;
}
}
class ScrollBehavior extends MaterialScrollBehavior {
@override
Set<PointerDeviceKind> get dragDevices => PointerDeviceKind.values.toSet();
}