2023-12-04 12:45:44 +01:00
|
|
|
import 'dart:convert';
|
|
|
|
import 'dart:io';
|
|
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import 'package:lastorado_shared/lastorado_shared.dart';
|
|
|
|
import 'package:mini_server/mini_server.dart';
|
|
|
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
|
|
|
|
|
|
part 'main.g.dart';
|
|
|
|
|
|
|
|
final container = ProviderContainer();
|
|
|
|
|
|
|
|
@riverpod
|
|
|
|
Future<String> getIpAddress(final ref) async {
|
|
|
|
var ipAddress = '';
|
|
|
|
await NetworkInterface.list(type: InternetAddressType.IPv4)
|
|
|
|
.then((interfaces) {
|
|
|
|
interfaces.forEach((interface) {
|
|
|
|
interface.addresses.forEach((address) {
|
|
|
|
if (address.address.isNotEmpty) {
|
|
|
|
ipAddress = address.address;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
return ipAddress;
|
|
|
|
}
|
|
|
|
|
|
|
|
@riverpod
|
|
|
|
class Taxameter extends _$Taxameter {
|
|
|
|
@override
|
|
|
|
TaxameterStatus build() {
|
|
|
|
return TaxameterStatus(
|
2024-02-01 08:47:17 +01:00
|
|
|
eventList: [
|
|
|
|
TripStatus(dateTime: DateTime.now(), type: TripStatusType.driving)
|
|
|
|
],
|
2023-12-04 12:45:44 +01:00
|
|
|
hasTrailer: false,
|
|
|
|
hasBigLuggage: false,
|
|
|
|
isFarAway: false,
|
|
|
|
isCharity: false);
|
|
|
|
}
|
|
|
|
|
2024-02-01 08:47:17 +01:00
|
|
|
void setEventList(List<TripStatus> eventList) {
|
|
|
|
state = state.copyWith(eventList: eventList);
|
2023-12-04 12:45:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void setHasTrailer(bool hasTrailer) {
|
|
|
|
state = state.copyWith(hasTrailer: hasTrailer);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setHasBigLuggage(bool hasBigLuggage) {
|
|
|
|
state = state.copyWith(hasBigLuggage: hasBigLuggage);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setIsFarAway(bool isFarAway) {
|
|
|
|
state = state.copyWith(isFarAway: isFarAway);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setIsCharity(bool isCharity) {
|
|
|
|
state = state.copyWith(isCharity: isCharity);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-01 08:47:17 +01:00
|
|
|
final curTripProvider = StateProvider<TripStatus>((ref) =>
|
|
|
|
TripStatus(dateTime: DateTime.now(), type: TripStatusType.driving));
|
|
|
|
|
|
|
|
class TripEventList extends Notifier<List<TripStatus>> {
|
|
|
|
@override
|
|
|
|
List<TripStatus> build() {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
void add(TripStatus tripEvent) {
|
|
|
|
state = [...state, tripEvent];
|
|
|
|
}
|
|
|
|
|
|
|
|
void removeItem(TripStatus event) {
|
|
|
|
state.remove(event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
final tripEventListProvider =
|
|
|
|
NotifierProvider<TripEventList, List<TripStatus>>(TripEventList.new);
|
|
|
|
|
|
|
|
final allEventsProvider = Provider<List<TripStatus>>((ref) {
|
|
|
|
final tripEvents = ref.watch(tripEventListProvider);
|
|
|
|
return tripEvents;
|
|
|
|
});
|
|
|
|
|
|
|
|
final timeProvider = Provider<Map<String, int>>((ref) {
|
|
|
|
final tripEvents = ref.watch(tripEventListProvider);
|
|
|
|
//final times = LocalTaxameterRepository.calculateTimes(tripEvents);
|
|
|
|
return {'test': 1};
|
|
|
|
});
|
|
|
|
|
2023-12-04 12:45:44 +01:00
|
|
|
void main() async {
|
|
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
|
|
|
|
final miniServer = MiniServer(
|
|
|
|
host: '0.0.0.0',
|
|
|
|
port: 8080,
|
|
|
|
);
|
|
|
|
|
|
|
|
miniServer.get('/taxameter', (HttpRequest request) async {
|
|
|
|
request.response.headers.contentType = ContentType.json;
|
|
|
|
var tax = container.read(taxameterProvider);
|
|
|
|
return request.response.write(jsonEncode(tax.toJson()));
|
|
|
|
});
|
|
|
|
|
|
|
|
runApp(const MyApp());
|
|
|
|
}
|
|
|
|
|
|
|
|
class MyApp extends StatefulWidget {
|
|
|
|
const MyApp({super.key});
|
|
|
|
|
|
|
|
@override
|
|
|
|
State<MyApp> createState() => _MyAppState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _MyAppState extends State<MyApp> {
|
|
|
|
@override
|
|
|
|
void dispose() {
|
|
|
|
super.dispose();
|
|
|
|
container.dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return UncontrolledProviderScope(
|
|
|
|
container: container,
|
|
|
|
child: const MaterialApp(
|
|
|
|
home: Scaffold(
|
|
|
|
body: Center(
|
|
|
|
child: ContentWidget(),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class ContentWidget extends ConsumerWidget {
|
|
|
|
const ContentWidget({super.key});
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
|
|
final ipAddress = ref.watch(getIpAddressProvider);
|
|
|
|
final tax = ref.watch(taxameterProvider);
|
2024-02-01 08:47:17 +01:00
|
|
|
final curEvent = ref.watch(curTripProvider);
|
|
|
|
final tripEvents = ref.watch(tripEventListProvider);
|
|
|
|
final times = ref.watch(timeProvider);
|
|
|
|
|
2023-12-04 12:45:44 +01:00
|
|
|
return ListView(
|
|
|
|
children: [
|
|
|
|
switch (ipAddress) {
|
|
|
|
AsyncError(:final error) => ListTile(
|
|
|
|
title: Text('Error: $error'),
|
|
|
|
tileColor: Colors.red[200],
|
|
|
|
),
|
|
|
|
AsyncData(:final value) => ListTile(
|
|
|
|
title: Text('Server is listening on $value'),
|
|
|
|
tileColor: Colors.grey[200],
|
|
|
|
),
|
|
|
|
_ => const CircularProgressIndicator(),
|
|
|
|
},
|
|
|
|
const SizedBox(height: 40),
|
|
|
|
CheckboxListTile(
|
|
|
|
value: tax.hasTrailer,
|
|
|
|
onChanged: (value) => ref
|
|
|
|
.read(taxameterProvider.notifier)
|
|
|
|
.setHasTrailer(value ?? false),
|
|
|
|
title: const Text('has trailer'),
|
|
|
|
),
|
|
|
|
CheckboxListTile(
|
|
|
|
value: tax.hasBigLuggage,
|
|
|
|
onChanged: (value) => ref
|
|
|
|
.read(taxameterProvider.notifier)
|
|
|
|
.setHasBigLuggage(value ?? false),
|
|
|
|
title: const Text('has big luggage'),
|
|
|
|
),
|
|
|
|
CheckboxListTile(
|
|
|
|
value: tax.isFarAway,
|
|
|
|
onChanged: (value) =>
|
|
|
|
ref.read(taxameterProvider.notifier).setIsFarAway(value ?? false),
|
|
|
|
title: const Text('is far away'),
|
|
|
|
),
|
|
|
|
CheckboxListTile(
|
|
|
|
value: tax.isCharity,
|
|
|
|
onChanged: (value) =>
|
|
|
|
ref.read(taxameterProvider.notifier).setIsCharity(value ?? false),
|
|
|
|
title: const Text('is charity'),
|
|
|
|
),
|
2024-02-01 08:47:17 +01:00
|
|
|
const SizedBox(
|
|
|
|
height: 10,
|
|
|
|
),
|
|
|
|
Text('Trip events', style: Theme.of(context).textTheme.displayMedium),
|
|
|
|
Container(
|
|
|
|
decoration: BoxDecoration(color: Colors.grey[200]),
|
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
ElevatedButton(
|
|
|
|
onPressed: () async {
|
|
|
|
final TimeOfDay? time = await showTimePicker(
|
|
|
|
context: context, initialTime: TimeOfDay.now());
|
|
|
|
final now = DateTime.now();
|
|
|
|
if (time != null) {
|
|
|
|
ref.read(curTripProvider.notifier).update((state) =>
|
|
|
|
state = TripStatus(
|
|
|
|
dateTime: DateTime(now.year, now.month, now.day,
|
|
|
|
time.hour, time.minute),
|
|
|
|
type: TripStatusType.driving));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
child: const Text('Select time')),
|
|
|
|
Text('Selected time: ${curEvent.dateTime}'),
|
|
|
|
DropdownMenu(
|
|
|
|
dropdownMenuEntries: const [
|
|
|
|
DropdownMenuEntry(
|
|
|
|
value: TripStatusType.driving,
|
|
|
|
label: 'driving',
|
|
|
|
),
|
|
|
|
DropdownMenuEntry(
|
|
|
|
value: TripStatusType.waiting,
|
|
|
|
label: 'waiting',
|
|
|
|
),
|
|
|
|
DropdownMenuEntry(
|
|
|
|
value: TripStatusType.done,
|
|
|
|
label: 'done',
|
|
|
|
),
|
|
|
|
],
|
|
|
|
onSelected: (value) {
|
|
|
|
ref.read(curTripProvider.notifier).update((state) => state =
|
|
|
|
TripStatus(
|
|
|
|
dateTime: state.dateTime,
|
|
|
|
type: value as TripStatusType));
|
|
|
|
},
|
|
|
|
),
|
|
|
|
ElevatedButton(
|
|
|
|
onPressed: () {
|
|
|
|
ref
|
|
|
|
.read(tripEventListProvider.notifier)
|
|
|
|
.add(ref.read(curTripProvider.notifier).state.copyWith());
|
|
|
|
},
|
|
|
|
child: const Text('Add event'),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
for (final event in tripEvents)
|
|
|
|
ListTile(
|
|
|
|
title: Text(event.dateTime.toString()),
|
|
|
|
subtitle: Text(event.type.toString()),
|
|
|
|
trailing: IconButton(
|
|
|
|
icon: const Icon(Icons.delete),
|
|
|
|
onPressed: () {
|
|
|
|
ref.read(tripEventListProvider.notifier).removeItem(event);
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
|
|
|
Container(
|
|
|
|
decoration: BoxDecoration(color: Colors.grey[200]),
|
|
|
|
child: Column(
|
|
|
|
children: [Text('Times: $times')],
|
|
|
|
),
|
|
|
|
)
|
2023-12-04 12:45:44 +01:00
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|