Browse Source

added hive as local database

pull/3/head
Khoren Markosyan 3 years ago
parent
commit
7cf29d7598
  1. 6
      .vscode/settings.json
  2. 2
      example/lib/main.dart
  3. 24
      example/lib/models/code.dart
  4. 46
      example/lib/models/code.g.dart
  5. 34
      example/lib/models/encode.dart
  6. 52
      example/lib/models/encode.g.dart
  7. 2
      example/lib/models/models.dart
  8. 85
      example/lib/pages/history_page.dart
  9. 6
      example/lib/pages/home_page.dart
  10. 27
      example/lib/pages/scanner_page.dart
  11. 50
      example/lib/utils/db_service.dart
  12. 28
      example/pubspec.lock
  13. 3
      example/pubspec.yaml
  14. 2
      ios/Classes/src/native_zxing.cpp
  15. 4
      ios/Classes/src/native_zxing.h
  16. 16
      lib/flutter_zxing.dart
  17. 11
      lib/generated_bindings.dart

6
.vscode/settings.json vendored

@ -1,3 +1,7 @@
{
"cmake.sourceDirectory": "${workspaceFolder}/ios/Classes/src"
"cmake.sourceDirectory": "${workspaceFolder}/ios/Classes/src",
"files.associations": {
"__config": "cpp",
"__nullptr": "cpp"
}
}

2
example/lib/main.dart

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:flutter_zxing_example/utils/db_service.dart';
import 'package:flutter_zxing_example/utils/extensions.dart';
import 'package:nb_utils/nb_utils.dart';
@ -13,6 +14,7 @@ import 'utils/scroll_behavior.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await _initializeAppStore();
await DbService.instance.initializeApp();
runApp(const MyApp());
}

24
example/lib/models/code.dart

@ -0,0 +1,24 @@
import 'package:flutter_zxing/flutter_zxing.dart';
import 'package:hive_flutter/hive_flutter.dart';
part "code.g.dart";
@HiveType(typeId: 0)
class Code extends HiveObject {
@HiveField(0)
bool? isValid;
@HiveField(1)
int? format;
@HiveField(2)
String? text;
Code();
Code.fromCodeResult(CodeResult result) {
isValid = result.isValidBool;
format = result.format;
text = result.textString;
}
}

46
example/lib/models/code.g.dart

@ -0,0 +1,46 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'code.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class CodeAdapter extends TypeAdapter<Code> {
@override
final int typeId = 0;
@override
Code read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return Code()
..isValid = fields[0] as bool?
..format = fields[1] as int?
..text = fields[2] as String?;
}
@override
void write(BinaryWriter writer, Code obj) {
writer
..writeByte(3)
..writeByte(0)
..write(obj.isValid)
..writeByte(1)
..write(obj.format)
..writeByte(2)
..write(obj.text);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is CodeAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

34
example/lib/models/encode.dart

@ -0,0 +1,34 @@
import 'dart:typed_data';
import 'package:flutter_zxing/flutter_zxing.dart';
import 'package:hive_flutter/hive_flutter.dart';
part "encode.g.dart";
@HiveType(typeId: 1)
class Encode extends HiveObject {
@HiveField(0)
bool? isValid;
@HiveField(1)
int? format;
@HiveField(2)
String? text;
@HiveField(3)
Uint8List? data;
@HiveField(4)
int? length;
Encode();
Encode.fromEncodeResult(EncodeResult result) {
isValid = result.isValidBool;
format = result.format;
text = result.textString;
data = result.bytes as Uint8List?;
length = result.length;
}
}

52
example/lib/models/encode.g.dart

@ -0,0 +1,52 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'encode.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class EncodeAdapter extends TypeAdapter<Encode> {
@override
final int typeId = 1;
@override
Encode read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return Encode()
..isValid = fields[0] as bool?
..format = fields[1] as int?
..text = fields[2] as String?
..data = fields[3] as Uint8List?
..length = fields[4] as int?;
}
@override
void write(BinaryWriter writer, Encode obj) {
writer
..writeByte(5)
..writeByte(0)
..write(obj.isValid)
..writeByte(1)
..write(obj.format)
..writeByte(2)
..write(obj.text)
..writeByte(3)
..write(obj.data)
..writeByte(4)
..write(obj.length);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is EncodeAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

2
example/lib/models/models.dart

@ -0,0 +1,2 @@
export 'code.dart';
export 'encode.dart';

85
example/lib/pages/history_page.dart

@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_zxing/flutter_zxing.dart';
import 'package:flutter_zxing_example/models/code.dart';
import 'package:flutter_zxing_example/utils/db_service.dart';
import 'package:hive_flutter/hive_flutter.dart';
class HistoryPage extends StatefulWidget {
const HistoryPage({
@ -12,8 +14,6 @@ class HistoryPage extends StatefulWidget {
}
class _HistoryPageState extends State<HistoryPage> {
final _resultQueue = <CodeResult>[];
@override
Widget build(BuildContext context) {
return Scaffold(
@ -25,42 +25,47 @@ class _HistoryPageState extends State<HistoryPage> {
}
_buildResultList() {
return _resultQueue.isEmpty
? const Center(
child: Text(
'No Results',
style: TextStyle(fontSize: 24),
))
: ListView.builder(
itemCount: _resultQueue.length,
itemBuilder: (context, index) {
final result = _resultQueue[index];
return ListTile(
title: Text(result.textString ?? ''),
subtitle: Text(result.formatString),
trailing: ButtonBar(
mainAxisSize: MainAxisSize.min,
children: [
// Copy button
TextButton(
child: const Text('Copy'),
onPressed: () {
Clipboard.setData(
ClipboardData(text: result.textString));
},
),
// Remove button
IconButton(
icon: const Icon(Icons.delete, color: Colors.red),
onPressed: () {
_resultQueue.removeAt(index);
setState(() {});
},
),
],
),
);
},
);
return ValueListenableBuilder<Box<Code>>(
valueListenable: DbService.instance.getCodes().listenable(),
builder: (context, box, _) {
final results = box.values.toList().cast<Code>();
return results.isEmpty
? const Center(
child: Text(
'No Results',
style: TextStyle(fontSize: 24),
))
: ListView.builder(
itemCount: results.length,
itemBuilder: (context, index) {
final result = results[index];
return ListTile(
title: Text(result.text ?? ''),
subtitle: Text(result.format.toString()),
trailing: ButtonBar(
mainAxisSize: MainAxisSize.min,
children: [
// Copy button
TextButton(
child: const Text('Copy'),
onPressed: () {
Clipboard.setData(
ClipboardData(text: result.text));
},
),
// Remove button
IconButton(
icon: const Icon(Icons.delete, color: Colors.red),
onPressed: () {
// DbService.instance.deleteCode(result);
// setState(() {});
},
),
],
),
);
},
);
});
}
}

6
example/lib/pages/home_page.dart

@ -19,14 +19,14 @@ class _HomePageState extends State<HomePage> {
final creatorPage = const CreatorPage();
final historyPage = const HistoryPage();
final scannerPage = const ScannerPage();
final notificationsPage = const ScannerPage();
final helpPage = Container();
final settingsPage = const SettingsPage();
dynamic pages() => [
creatorPage,
historyPage,
scannerPage,
notificationsPage,
helpPage,
settingsPage,
];
@ -34,7 +34,7 @@ class _HomePageState extends State<HomePage> {
const TabItem(icon: FontAwesomeIcons.barcode),
const TabItem(icon: FontAwesomeIcons.clockRotateLeft),
const TabItem(icon: Icons.qr_code_scanner),
const TabItem(icon: FontAwesomeIcons.solidBell),
const TabItem(icon: FontAwesomeIcons.circleQuestion),
const TabItem(icon: FontAwesomeIcons.gear),
];

27
example/lib/pages/scanner_page.dart

@ -2,6 +2,8 @@ import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_zxing/flutter_zxing.dart';
import 'package:flutter_zxing_example/models/models.dart';
import 'package:flutter_zxing_example/utils/db_service.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:image_picker/image_picker.dart';
import 'package:image/image.dart' as imglib;
@ -26,9 +28,7 @@ class _ScannerPageState extends State<ScannerPage> {
),
body: ZxingReaderWidget(
onScan: (result) async {
// _resultQueue.insert(0, result);
// await Future.delayed(const Duration(milliseconds: 500));
// setState(() {});
addCode(result);
},
),
floatingActionButton: FloatingActionButton(
@ -49,7 +49,7 @@ class _ScannerPageState extends State<ScannerPage> {
0,
);
if (result.isValidBool) {
debugPrint(result.textString);
addCode(result);
}
}
}
@ -57,4 +57,23 @@ class _ScannerPageState extends State<ScannerPage> {
),
);
}
void addCode(CodeResult result) {
Code code = Code.fromCodeResult(result);
DbService.instance.addCode(code);
// show snackbar
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Padding(
padding: const EdgeInsets.only(bottom: 30.0),
child: Text(
code.text ?? '',
textAlign: TextAlign.center,
),
),
),
);
}
}

50
example/lib/utils/db_service.dart

@ -0,0 +1,50 @@
import 'package:flutter_zxing_example/models/models.dart';
import 'package:hive_flutter/hive_flutter.dart';
class DbService {
DbService._privateConstructor();
static final DbService instance = DbService._privateConstructor();
Future<void> initializeApp() async {
await Hive.initFlutter();
Hive.registerAdapter(CodeAdapter());
await Hive.openBox<Code>('codes');
await Hive.openBox<Encode>('encodes');
// Hive.box('codes').close();
}
Box<Code> getCodes() => Hive.box<Code>('codes');
Future deleteCodes() async {
var codes = getCodes();
await codes.deleteAll(codes.keys);
return;
}
Future addCode(Code value) async {
var codes = getCodes();
if (!codes.values.contains(value)) {
return codes.add(value);
}
return;
}
Box<Encode> getEncodes() => Hive.box<Encode>('encodes');
Future deleteEncodes() async {
var encodes = getEncodes();
await encodes.deleteAll(encodes.keys);
return;
}
Future addEncode(Encode value) async {
var encodes = getEncodes();
if (!encodes.values.contains(value)) {
return encodes.add(value);
}
return;
}
}

28
example/pubspec.lock

@ -378,6 +378,27 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
hive:
dependency: "direct main"
description:
name: hive
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
hive_flutter:
dependency: "direct main"
description:
name: hive_flutter
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
hive_generator:
dependency: "direct dev"
description:
name: hive_generator
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.2"
http:
dependency: transitive
description:
@ -782,6 +803,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.2"
source_helper:
dependency: transitive
description:
name: source_helper
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.2"
source_span:
dependency: transitive
description:

3
example/pubspec.yaml

@ -18,6 +18,8 @@ dependencies:
flutter_zxing:
path: ../
font_awesome_flutter: ^10.1.0
hive: ^2.1.0
hive_flutter: ^1.1.0
image_picker: ^0.8.5
nb_utils: ^4.5.0
path_provider: ^2.0.9
@ -32,6 +34,7 @@ dev_dependencies:
flutter_lints: ^1.0.0
flutter_test:
sdk: flutter
hive_generator:
mobx_codegen:
flutter:

2
ios/Classes/src/native_zxing.cpp

@ -99,7 +99,7 @@ extern "C"
{
long long start = get_now();
struct EncodeResult result = {nullptr, 0, false, nullptr};
struct EncodeResult result = {0, contents, Format(format), nullptr, 0, nullptr};
try
{
auto writer = MultiFormatWriter(BarcodeFormat(format)).setMargin(margin).setEccLevel(eccLevel);

4
ios/Classes/src/native_zxing.h

@ -37,9 +37,11 @@ extern "C"
struct EncodeResult
{
int isValid;
char *text;
enum Format format;
const unsigned int *data;
int length;
int isValid;
char *error;
};

16
lib/flutter_zxing.dart

@ -75,20 +75,20 @@ extension Uint8ListBlobConversion on Uint8List {
}
}
extension Encode on EncodeResult {
extension CodeExt on CodeResult {
bool get isValidBool => isValid == 1;
Uint32List get bytes => data.asTypedList(length);
String get errorMessage => error.cast<Utf8>().toDartString();
String? get textString =>
text == nullptr ? null : text.cast<Utf8>().toDartString();
String get formatString => CodeFormat.formatName(format);
}
extension Code on CodeResult {
extension EncodeExt on EncodeResult {
bool get isValidBool => isValid == 1;
String? get textString =>
text == nullptr ? null : text.cast<Utf8>().toDartString();
String get formatString {
return CodeFormat.formatName(format);
}
String get formatString => CodeFormat.formatName(format);
Uint32List get bytes => data.asTypedList(length);
String get errorMessage => error.cast<Utf8>().toDartString();
}
extension CodeFormat on Format {

11
lib/generated_bindings.dart

@ -216,13 +216,18 @@ class CodeResult extends ffi.Struct {
}
class EncodeResult extends ffi.Struct {
external ffi.Pointer<ffi.Uint32> data;
@ffi.Int32()
external int isValid;
external ffi.Pointer<ffi.Int8> text;
@ffi.Int32()
external int length;
external int format;
external ffi.Pointer<ffi.Uint32> data;
@ffi.Int32()
external int isValid;
external int length;
external ffi.Pointer<ffi.Int8> error;
}

Loading…
Cancel
Save