|
|
|
import 'dart:io';
|
|
|
|
|
|
|
|
import 'package:counters/address.dart';
|
|
|
|
import 'package:counters/counters_page.dart';
|
|
|
|
import 'package:counters/datbase.dart';
|
|
|
|
import 'package:counters/new_address_page.dart';
|
|
|
|
import 'package:counters/record_action_pane.dart';
|
|
|
|
import 'package:counters/update_address_page.dart';
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|
|
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
|
|
|
import 'package:flutter_slidable/flutter_slidable.dart';
|
|
|
|
import 'package:intl/intl_standalone.dart';
|
|
|
|
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
|
|
|
|
|
|
|
void main() async {
|
|
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
await findSystemLocale();
|
|
|
|
if (Platform.isWindows || Platform.isLinux) {
|
|
|
|
sqfliteFfiInit();
|
|
|
|
}
|
|
|
|
databaseFactory = databaseFactoryFfi;
|
|
|
|
runApp(const MyApp());
|
|
|
|
}
|
|
|
|
|
|
|
|
class MyApp extends StatelessWidget {
|
|
|
|
const MyApp({super.key});
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return MaterialApp(
|
|
|
|
title: 'Журнал счетчиков',
|
|
|
|
localizationsDelegates: const [
|
|
|
|
AppLocalizations.delegate,
|
|
|
|
GlobalMaterialLocalizations.delegate,
|
|
|
|
],
|
|
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
|
|
theme: ThemeData(
|
|
|
|
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
|
|
|
useMaterial3: true,
|
|
|
|
),
|
|
|
|
// ignore: prefer_const_constructors
|
|
|
|
home: MyHomePage(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class MyHomePage extends StatefulWidget {
|
|
|
|
const MyHomePage({super.key});
|
|
|
|
|
|
|
|
@override
|
|
|
|
State<MyHomePage> createState() => _MyHomePageState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _MyHomePageState extends State<MyHomePage> {
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
final addresses = DBProvider.db.getAllAddress();
|
|
|
|
return Scaffold(
|
|
|
|
appBar: AppBar(
|
|
|
|
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
|
|
|
title: Text(AppLocalizations.of(context)!.app_title),
|
|
|
|
),
|
|
|
|
body: Center(
|
|
|
|
child: FutureBuilder<List<Address>>(
|
|
|
|
future: addresses,
|
|
|
|
builder: (context, snapshot) {
|
|
|
|
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
|
|
|
|
return AddressesListView(
|
|
|
|
addresses: snapshot.data!,
|
|
|
|
onUpdated: () {
|
|
|
|
setState(() {});
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Text(AppLocalizations.of(context)!.empty_addresses_list);
|
|
|
|
},
|
|
|
|
)),
|
|
|
|
floatingActionButton: FloatingActionButton(
|
|
|
|
onPressed: () {
|
|
|
|
Navigator.push(context,
|
|
|
|
MaterialPageRoute(builder: (context) => NewAddressPage()))
|
|
|
|
.then((_) => setState(() {}));
|
|
|
|
},
|
|
|
|
tooltip: AppLocalizations.of(context)!.add_new_address_tooltip,
|
|
|
|
child: const Icon(Icons.add),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class AddressesListView extends StatefulWidget {
|
|
|
|
const AddressesListView({
|
|
|
|
super.key,
|
|
|
|
required this.addresses,
|
|
|
|
this.onUpdated,
|
|
|
|
});
|
|
|
|
|
|
|
|
final List<Address> addresses;
|
|
|
|
final VoidCallback? onUpdated;
|
|
|
|
|
|
|
|
@override
|
|
|
|
State<AddressesListView> createState() => _AddressesListViewState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _AddressesListViewState extends State<AddressesListView> {
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return ListView.builder(
|
|
|
|
itemCount: widget.addresses.length,
|
|
|
|
itemBuilder: (context, possition) {
|
|
|
|
return Slidable(
|
|
|
|
key: const ValueKey(0),
|
|
|
|
endActionPane: RecordActionPane(
|
|
|
|
onEdit: () {
|
|
|
|
Navigator.push(
|
|
|
|
context,
|
|
|
|
MaterialPageRoute(
|
|
|
|
builder: (context) => UpdateAddressPage(
|
|
|
|
address: widget.addresses[possition],
|
|
|
|
))).then((_) => widget.onUpdated?.call());
|
|
|
|
},
|
|
|
|
onDelete: () {
|
|
|
|
DBProvider.db.deleteAddress(widget.addresses[possition]);
|
|
|
|
widget.onUpdated?.call();
|
|
|
|
},
|
|
|
|
).build(context),
|
|
|
|
child: TextButton(
|
|
|
|
onPressed: () {
|
|
|
|
Navigator.push(
|
|
|
|
context,
|
|
|
|
MaterialPageRoute(
|
|
|
|
builder: (context) => CountersPage(
|
|
|
|
address: widget.addresses[possition],
|
|
|
|
title: widget.addresses[possition].streetName,
|
|
|
|
comments: widget.addresses[possition].comments)));
|
|
|
|
},
|
|
|
|
style:
|
|
|
|
TextButton.styleFrom(shape: const BeveledRectangleBorder()),
|
|
|
|
child: Align(
|
|
|
|
alignment: Alignment.centerLeft,
|
|
|
|
child: Padding(
|
|
|
|
padding: const EdgeInsets.all(16.0),
|
|
|
|
child: Column(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: [
|
|
|
|
Text(
|
|
|
|
widget.addresses[possition].streetName,
|
|
|
|
style: Theme.of(context).textTheme.bodyLarge,
|
|
|
|
),
|
|
|
|
Text(
|
|
|
|
widget.addresses[possition].comments,
|
|
|
|
style: Theme.of(context).textTheme.bodySmall,
|
|
|
|
),
|
|
|
|
],
|
|
|
|
)),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|