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/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_mobx/flutter_mobx.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:flutter_zxing_example/utils/extensions.dart';
import 'package:nb_utils/nb_utils.dart'; import 'package:nb_utils/nb_utils.dart';
@ -13,6 +14,7 @@ import 'utils/scroll_behavior.dart';
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await _initializeAppStore(); await _initializeAppStore();
await DbService.instance.initializeApp();
runApp(const MyApp()); 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/material.dart';
import 'package:flutter/services.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 { class HistoryPage extends StatefulWidget {
const HistoryPage({ const HistoryPage({
@ -12,8 +14,6 @@ class HistoryPage extends StatefulWidget {
} }
class _HistoryPageState extends State<HistoryPage> { class _HistoryPageState extends State<HistoryPage> {
final _resultQueue = <CodeResult>[];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -25,42 +25,47 @@ class _HistoryPageState extends State<HistoryPage> {
} }
_buildResultList() { _buildResultList() {
return _resultQueue.isEmpty return ValueListenableBuilder<Box<Code>>(
? const Center( valueListenable: DbService.instance.getCodes().listenable(),
child: Text( builder: (context, box, _) {
'No Results', final results = box.values.toList().cast<Code>();
style: TextStyle(fontSize: 24), return results.isEmpty
)) ? const Center(
: ListView.builder( child: Text(
itemCount: _resultQueue.length, 'No Results',
itemBuilder: (context, index) { style: TextStyle(fontSize: 24),
final result = _resultQueue[index]; ))
return ListTile( : ListView.builder(
title: Text(result.textString ?? ''), itemCount: results.length,
subtitle: Text(result.formatString), itemBuilder: (context, index) {
trailing: ButtonBar( final result = results[index];
mainAxisSize: MainAxisSize.min, return ListTile(
children: [ title: Text(result.text ?? ''),
// Copy button subtitle: Text(result.format.toString()),
TextButton( trailing: ButtonBar(
child: const Text('Copy'), mainAxisSize: MainAxisSize.min,
onPressed: () { children: [
Clipboard.setData( // Copy button
ClipboardData(text: result.textString)); TextButton(
}, child: const Text('Copy'),
), onPressed: () {
// Remove button Clipboard.setData(
IconButton( ClipboardData(text: result.text));
icon: const Icon(Icons.delete, color: Colors.red), },
onPressed: () { ),
_resultQueue.removeAt(index); // Remove button
setState(() {}); 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 creatorPage = const CreatorPage();
final historyPage = const HistoryPage(); final historyPage = const HistoryPage();
final scannerPage = const ScannerPage(); final scannerPage = const ScannerPage();
final notificationsPage = const ScannerPage(); final helpPage = Container();
final settingsPage = const SettingsPage(); final settingsPage = const SettingsPage();
dynamic pages() => [ dynamic pages() => [
creatorPage, creatorPage,
historyPage, historyPage,
scannerPage, scannerPage,
notificationsPage, helpPage,
settingsPage, settingsPage,
]; ];
@ -34,7 +34,7 @@ class _HomePageState extends State<HomePage> {
const TabItem(icon: FontAwesomeIcons.barcode), const TabItem(icon: FontAwesomeIcons.barcode),
const TabItem(icon: FontAwesomeIcons.clockRotateLeft), const TabItem(icon: FontAwesomeIcons.clockRotateLeft),
const TabItem(icon: Icons.qr_code_scanner), const TabItem(icon: Icons.qr_code_scanner),
const TabItem(icon: FontAwesomeIcons.solidBell), const TabItem(icon: FontAwesomeIcons.circleQuestion),
const TabItem(icon: FontAwesomeIcons.gear), 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/material.dart';
import 'package:flutter_zxing/flutter_zxing.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:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:image/image.dart' as imglib; import 'package:image/image.dart' as imglib;
@ -26,9 +28,7 @@ class _ScannerPageState extends State<ScannerPage> {
), ),
body: ZxingReaderWidget( body: ZxingReaderWidget(
onScan: (result) async { onScan: (result) async {
// _resultQueue.insert(0, result); addCode(result);
// await Future.delayed(const Duration(milliseconds: 500));
// setState(() {});
}, },
), ),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
@ -49,7 +49,7 @@ class _ScannerPageState extends State<ScannerPage> {
0, 0,
); );
if (result.isValidBool) { 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" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" 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: http:
dependency: transitive dependency: transitive
description: description:
@ -782,6 +803,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.2" 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: source_span:
dependency: transitive dependency: transitive
description: description:

3
example/pubspec.yaml

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

2
ios/Classes/src/native_zxing.cpp

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

4
ios/Classes/src/native_zxing.h

@ -37,9 +37,11 @@ extern "C"
struct EncodeResult struct EncodeResult
{ {
int isValid;
char *text;
enum Format format;
const unsigned int *data; const unsigned int *data;
int length; int length;
int isValid;
char *error; 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; bool get isValidBool => isValid == 1;
Uint32List get bytes => data.asTypedList(length); String? get textString =>
String get errorMessage => error.cast<Utf8>().toDartString(); 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; bool get isValidBool => isValid == 1;
String? get textString => String? get textString =>
text == nullptr ? null : text.cast<Utf8>().toDartString(); text == nullptr ? null : text.cast<Utf8>().toDartString();
String get formatString => CodeFormat.formatName(format);
String get formatString { Uint32List get bytes => data.asTypedList(length);
return CodeFormat.formatName(format); String get errorMessage => error.cast<Utf8>().toDartString();
}
} }
extension CodeFormat on Format { extension CodeFormat on Format {

11
lib/generated_bindings.dart

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

Loading…
Cancel
Save