1 Commits
Author SHA1 Message Date
fbachus 0a3efa61be Revert "build(mobile): deactivate sqlite debugging lib used for desktop"
keep development branch in a state to run on desktop

This reverts commit 5ead82b9c6.
2026-07-31 04:11:57 +02:00
10 changed files with 132 additions and 291 deletions
+10 -37
View File
@@ -1,44 +1,17 @@
# oeffimaster # oeffimaster
Aggregating information to create your own routes in public transit effortlessly. A new Flutter project.
## Getting Started
## Goal of this project This project is a starting point for a Flutter application.
Do you ever get a route from google maps and see a 13 minute switch time, for a train that comes every ten minutes? Do you then prompt another app with better results. What if you'd normally have to wait 9 minutes for your train, but the previous train is late, so in reality you can switch with only a minutes worth of waiting? Now you can get an earlier train for the next connection, and suddenly the 3rd-fastest connection in google's algorithm becomes the fastest, and you saved 10 minutes - or could have, if you knew.
My app will not solve this issue.
As someone who is familiar with good chunks of the cities public transport network, I often enough *think* I can get faster to my target than the routing served by commonplace apps, but I have a hard time of knowing that for sure. Other apps allow some degree of comparing routes to one another, but it's not a priority, and editing any part of it is not supported at all.
Oeffimaster aims to make that type of information easily accessible and aggregate it in the most helpful way, allowing comparison and editing of routes.
## Usage A few resources to get you started if this is your first Flutter project:
I am currently providing artifacts for linux and android. To make your own builds, you will need an api key for your network.
## Build the project - [Learn Flutter](https://docs.flutter.dev/get-started/learn-flutter)
- [Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Flutter learning resources](https://docs.flutter.dev/reference/learning-resources)
### Get the API key For help getting started with Flutter development, view the
For the VBB network in Berlin/Brandenburg [online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
1. Installing flutter: https://docs.flutter.dev/install/quick
2. Get an API key for VBB: https://unternehmen.vbb.de/digitale-services/api/
It will take some time, but they will send you an API key and the url to access it.
this should work for other public transit networks using the HAFAS api, but you will have to test this yourself
### The build part
Create a `.env` in the project root and add the following to it
```env
VBB_API_KEY={YOUR_API_KEY}
VBB_API_URL={YOUR_API_URL}
```
For local builds and connected devices simply run `flutter run` in your terminal.
To build for linux:
```bash
flutter build linux -DVBB_API_KEY={API_KEY} -DVBB_API_URL={API_URL}
```
To build for android:
```
flutter build apk -DVBB_API_KEY={API_KEY} -DVBB_API_URL={API_URL}
```
+1 -2
View File
@@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<application <application
android:label="oeffimaster" android:label="oeffimaster"
android:name="${applicationName}" android:name="${applicationName}"
@@ -43,4 +42,4 @@
<data android:mimeType="text/plain"/> <data android:mimeType="text/plain"/>
</intent> </intent>
</queries> </queries>
</manifest> </manifest>
+10 -4
View File
@@ -5,7 +5,14 @@ import 'dart:core';
import 'dart:convert'; import 'dart:convert';
import 'transport_helper.dart'; import 'transport_helper.dart';
import 'utilities.dart';
String timeOf(DateTime fullDT) {
// doing it this way so we always get two digits on the hour
String full = fullDT.toString();
List<String> splits = full.split(" ")[1].split(":");
String time = '${splits[0]}:${splits[1]}';
return time;
}
class ApiHandler { class ApiHandler {
// TODO: Split next line for better Error Handling // TODO: Split next line for better Error Handling
@@ -72,7 +79,7 @@ class ApiHandler {
static Future<List<Departure>> departures( static Future<List<Departure>> departures(
String stationId, { String stationId, {
int? maxDepartures = -1, int? maxDepartures = -1,
DateTime? datetime, DateTime? time,
int? duration = 0, int? duration = 0,
}) async { }) async {
String urlPath = '/api/fahrinfo/latest/departureBoard'; String urlPath = '/api/fahrinfo/latest/departureBoard';
@@ -81,9 +88,8 @@ class ApiHandler {
Uri url = Uri.https(baseUrl, urlPath, { Uri url = Uri.https(baseUrl, urlPath, {
'accessId': accessID, 'accessId': accessID,
'id': stationString, 'id': stationString,
'date': dateOf(datetime ?? DateTime.now()),
'time': timeOf( 'time': timeOf(
datetime ?? DateTime.now(), time ?? DateTime.now(),
), //time from which departures will be shown ), //time from which departures will be shown
'duration': duration.toString(), //interval time in minutes 'duration': duration.toString(), //interval time in minutes
'maxJourneys': maxDepartures.toString(), 'maxJourneys': maxDepartures.toString(),
+92 -193
View File
@@ -1,53 +1,36 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:dynamic_color/dynamic_color.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart'; //for testing on desktop
import 'dart:async';
import 'dart:io';
import 'api_handler.dart'; import 'api_handler.dart';
import 'transport_helper.dart'; import 'transport_helper.dart';
import 'utilities.dart'; import 'dart:async';
import 'package:sqflite_common_ffi/sqflite_ffi.dart'; //for testing on desktop
void main() async { void main() async {
await dotenv.load(); await dotenv.load();
const String dbName = "oeffimasterTransportDb"; const String dbName = "oeffimasterTransportDb";
databaseFactory = databaseFactoryFfi; // for debugging and desktop test
if (Platform.isLinux) {
databaseFactory = databaseFactoryFfi; // for debugging and desktop test
}
DbHelper.initDb(dbName); DbHelper.initDb(dbName);
runApp(const MyApp()); runApp(const MyApp());
} }
final _defaultLightScheme = ColorScheme.fromSeed(seedColor: Colors.yellow);
final _defaultDarkScheme = ColorScheme.fromSeed(
seedColor: Colors.yellow,
brightness: Brightness.dark,
);
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
const MyApp({super.key}); const MyApp({super.key});
// This widget is the root of your application.
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DynamicColorBuilder( return MaterialApp(
builder: (ColorScheme? lightDynamic, ColorScheme? darkDynamic) { title: 'Oeffimaster',
return MaterialApp( theme: ThemeData(
theme: ThemeData( colorScheme: .fromSeed(seedColor: Colors.yellow),
useMaterial3: true, ),
colorScheme: lightDynamic ?? _defaultLightScheme, // home: const MyHomePage(title: 'Oeffimaster'), //this is what matters
), home: const JourneyOverviewPage(),
darkTheme: ThemeData( // routes: {
useMaterial3: true, // //'/': (context) => const MyHomePage(title: 'Oeffimaster'),
colorScheme: darkDynamic ?? _defaultDarkScheme, // '/stations': (context) => const ChooseStationPage(),
), // },
themeMode: ThemeMode.system,
home: const JourneyOverviewPage(),
title: 'Oeffimaster',
);
},
); );
} }
} }
@@ -62,7 +45,9 @@ class MyHomePage extends StatefulWidget {
class _MyHomePageState extends State<MyHomePage> { class _MyHomePageState extends State<MyHomePage> {
int _counter = 0; int _counter = 0;
//String API_KEY = ApiHandler.accessID;
String API_KEY = "no telly"; String API_KEY = "no telly";
//Future<Map<String, dynamic>> ?id;
List<Station> stationList = []; List<Station> stationList = [];
String id = ''; String id = '';
@@ -75,14 +60,37 @@ class _MyHomePageState extends State<MyHomePage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
//backgroundColor: Theme.of(context).colorScheme.inversePrimary,
//backgroundColor: Colors.amber,
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title), title: Text(widget.title),
), ),
body: Center( body: Center(
child: Column( child: Column(
mainAxisAlignment: .center, mainAxisAlignment: .center,
children: [ children: [
// const Text('You have pushed the button this many times:'),
// Text(
// '$_counter',
// style: Theme.of(context).textTheme.headlineMedium,
// ),
// Text('API key from ENV is $API_KEY'),
// MaterialButton(
// onPressed: () {
// showResult(ApiHandler.findStations('S Biesdorf'));
// },
// child: Text('Search for \'S Biesdorf\''),
// ),
// Text(id),
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
Navigator.push( Navigator.push(
@@ -96,8 +104,6 @@ class _MyHomePageState extends State<MyHomePage> {
), ),
), ),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
foregroundColor: Theme.of(context).colorScheme.onPrimaryContainer,
onPressed: () { onPressed: () {
Navigator.push( Navigator.push(
context, context,
@@ -156,6 +162,7 @@ class _ChooseStationPageState extends State<ChooseStationPage> {
void _search(String? query) { void _search(String? query) {
if (query?.isEmpty ?? true) return; if (query?.isEmpty ?? true) return;
// do something with query
setState(() { setState(() {
findStationsByName(query!); findStationsByName(query!);
}); });
@@ -170,18 +177,27 @@ class _ChooseStationPageState extends State<ChooseStationPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar(title: const Text('Start a Journey')), appBar: AppBar(title: const Text('RoutePicker')),
body: Center( body: Center(
child: Column( child: Column(
children: [ children: [
// ElevatedButton(
// onPressed: () {
// showResult(ApiHandler.findStations('S Biesdorf'));
// },
// child: Text('Search for \'S Biesdorf\''),
// ),
SearchAnchor( SearchAnchor(
builder: (BuildContext context, SearchController controller) { builder: (BuildContext context, SearchController controller) {
return SearchBar( return SearchBar(
controller: controller, controller: controller,
hintText: 'Search your start Station', hintText: 'Search for a Station',
padding: const WidgetStatePropertyAll<EdgeInsets>( padding: const WidgetStatePropertyAll<EdgeInsets>(
EdgeInsets.symmetric(horizontal: 16.0), EdgeInsets.symmetric(horizontal: 16.0),
), ),
// onTap: () {
// controller.openView();
// },
onChanged: _onSearchChanged, onChanged: _onSearchChanged,
onSubmitted: _search, onSubmitted: _search,
leading: const Icon(Icons.search), leading: const Icon(Icons.search),
@@ -218,6 +234,9 @@ class _ChooseStationPageState extends State<ChooseStationPage> {
} }
void _handleStationTapped(Station station) { void _handleStationTapped(Station station) {
// setState(() {
// _selectedStation = station;
// });
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
@@ -273,7 +292,7 @@ class _ChooseDeparturePageState extends State<ChooseDeparturePage> {
void loadDepartures(Station startStation) async { void loadDepartures(Station startStation) async {
departureList = await ApiHandler.departures( departureList = await ApiHandler.departures(
startStation.id, startStation.id,
datetime: widget.arrival?.arrivalTime ?? DateTime.now(), time: widget.arrival?.arrivalTime ?? DateTime.now(),
); );
setState(() {}); setState(() {});
} }
@@ -301,27 +320,12 @@ class _ChooseDeparturePageState extends State<ChooseDeparturePage> {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text( title: Text(
'Departures for ${widget.startStation.name}', 'RoutePicker for ${widget.startStation.name} // ${widget.journeyId}',
), ),
), ),
body: Center( body: Center(
child: Column( child: Column(
children: [ children: [
Builder(
builder: (context) {
if (widget.arrival != null) {
return ListTile(
title: Text(
'arrive at ${widget.arrival?.arrivalTime}',
),
);
} else {
return ListTile(
title: Text(''),
);
}
},
),
Expanded( Expanded(
child: SizedBox( child: SizedBox(
height: 400, height: 400,
@@ -331,24 +335,24 @@ class _ChooseDeparturePageState extends State<ChooseDeparturePage> {
), ),
), ),
), ),
ElevatedButton(
onPressed: () {
if (widget.journeyId != null) {
loadJourney(widget.journeyId as int);
}
},
child: const Text('Finish Route'),
),
], ],
), ),
), ),
floatingActionButton: FloatingActionButton(
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
foregroundColor: Theme.of(context).colorScheme.onPrimaryContainer,
onPressed: () {
if (widget.journeyId != null) {
loadJourney(widget.journeyId as int);
}
},
tooltip: 'Finish route',
child: const Icon(Icons.check),
),
); );
} }
void _handleDepartureTapped(Departure departure) { void _handleDepartureTapped(Departure departure) {
// setState(() {
// _selectedDeparture = departure;
// });
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
@@ -423,7 +427,7 @@ class _ChooseArrivalPageState extends State<ChooseArrivalPage> {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text( title: Text(
'Arrivals for ${widget.departure.vehicleName}', 'Arrivals for ${widget.departure.vehicleName}// ${widget.journeyId}',
), ),
), ),
body: Center( body: Center(
@@ -446,6 +450,9 @@ class _ChooseArrivalPageState extends State<ChooseArrivalPage> {
} }
void _handleArrivalTapped(Departure departure, Departure arrival) async { void _handleArrivalTapped(Departure departure, Departure arrival) async {
// setState(() {
// _selectedDeparture = departure;
// });
departure.dbInsert; departure.dbInsert;
arrival.dbInsert; arrival.dbInsert;
Segment newSegment = await Segment.fromDepartures(departure, arrival); Segment newSegment = await Segment.fromDepartures(departure, arrival);
@@ -525,44 +532,9 @@ class _JourneyDetailPageState extends State<JourneyDetailPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: Text('Connection Details \n$duration')),
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Connection Details'),
Text(
'Duration: ${widget.singleJourney.duration.toString().split(".")[0]}h',
textScaler: TextScaler.linear(0.7),
),
],
),
),
body: Center( body: Center(
child: Column( child: SegmentList(journey: widget.singleJourney),
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: SizedBox(
height: 400,
child: SegmentList(journey: widget.singleJourney),
),
),
Container(
margin: const EdgeInsets.only(bottom: 60.0),
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => JourneyOverviewPage(),
),
);
},
child: const Text('View all Journeys'),
),
),
],
),
), ),
); );
} }
@@ -581,39 +553,9 @@ class SegmentList extends StatelessWidget {
return ListView( return ListView(
children: [ children: [
for (Segment seg in journey.segments) for (Segment seg in journey.segments)
Card( ListTile(
child: Column( title: Text(seg.start.direction),
mainAxisSize: .min, subtitle: Text(seg.start.departureTime.toString()),
children: [
Container(
padding: EdgeInsets.only(left: 10, top: 10),
child: Row(
children: [
Text(
seg.vehicle.name,
textScaler: TextScaler.linear(1.1),
),
Icon(Icons.arrow_right_alt),
Text('${seg.start.direction}'),
],
),
),
ListTile(
leading: Text(
timeOf(seg.start.departureTime),
textScaler: TextScaler.linear(1.4),
),
title: Text(seg.start.stationName),
),
ListTile(
leading: Text(
timeOf(seg.end.arrivalTime),
textScaler: TextScaler.linear(1.4),
),
title: Text(seg.end.stationName),
),
],
),
), ),
], ],
); );
@@ -656,9 +598,6 @@ class _JourneyOverviewPageState extends State<JourneyOverviewPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar(
title: Text("Your Journeys"),
),
body: Center( body: Center(
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@@ -715,12 +654,21 @@ class _JourneyOverviewPageState extends State<JourneyOverviewPage> {
); );
}, },
), ),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChooseStationPage(),
),
);
},
child: const Text('Start a route'),
),
], ],
), ),
), ),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
foregroundColor: Theme.of(context).colorScheme.onPrimaryContainer,
onPressed: () { onPressed: () {
Navigator.push( Navigator.push(
context, context,
@@ -758,58 +706,9 @@ class JourneyList extends StatelessWidget {
return ListView( return ListView(
children: [ children: [
for (Journey jour in journeys) for (Journey jour in journeys)
Card( ListTile(
margin: EdgeInsets.only( title: Text('${jour.startStation} to ${jour.endStation}'),
left: 3.0, onTap: () => onTapped(jour),
top: 3.0,
bottom: 3.0,
right: 3.0,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(0.0),
),
),
elevation: 0.3,
clipBehavior: .hardEdge,
child: InkWell(
child: Column(
mainAxisSize: .min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.only(
left: 15.0,
top: 7.0,
bottom: 7.0,
right: 10.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${jour.startStation}',
textScaler: TextScaler.linear(1.2),
),
Row(
children: [
Icon(
Icons.arrow_right_alt,
size: 25.0,
),
Text(
'${jour.endStation}',
textScaler: TextScaler.linear(1.2),
),
],
),
],
),
),
],
),
onTap: () => onTapped(jour),
),
), ),
], ],
); );
+5 -12
View File
@@ -1,5 +1,4 @@
import 'package:sqflite/sqflite.dart'; import 'package:sqflite/sqflite.dart';
import 'utilities.dart';
// import './state_helper.dart'; // import './state_helper.dart';
// import './db_helper.dart'; // import './db_helper.dart';
@@ -95,15 +94,13 @@ class Journey {
Map<String, Object?> journeyMaps, Map<String, Object?> journeyMaps,
List<Segment> segmentMaps, List<Segment> segmentMaps,
) { ) {
Journey journey = Journey( return Journey(
id: journeyMaps["id"] as int, id: journeyMaps["id"] as int,
startStation: journeyMaps["startstation"] as String?, startStation: journeyMaps["startstation"] as String?,
endStation: journeyMaps["endstation"] as String?, endStation: journeyMaps["endstation"] as String?,
segments: segmentMaps, segments: segmentMaps,
duration: Duration(minutes: 0), duration: Duration(minutes: 0),
); );
journey.sync();
return journey;
} }
// from trip API request // from trip API request
@@ -137,8 +134,8 @@ class Journey {
if (segments.isNotEmpty) { if (segments.isNotEmpty) {
startStation = segments.first.start.stationName; startStation = segments.first.start.stationName;
endStation = segments.last.end.stationName; endStation = segments.last.end.stationName;
duration = segments.last.end.arrivalTime.difference( duration = segments.first.start.departureTime.difference(
segments.first.start.departureTime, segments.last.end.arrivalTime,
); );
} else { } else {
// if the journey has no segments yet, at least the startStation should remain, // if the journey has no segments yet, at least the startStation should remain,
@@ -226,6 +223,7 @@ class Journey {
static Future<Journey> fromMapWrapper(Map<String, Object?> journeyMap) async { static Future<Journey> fromMapWrapper(Map<String, Object?> journeyMap) async {
Future<List<Segment>> segs = _dbGetJourneySegments(journeyMap["id"] as int); Future<List<Segment>> segs = _dbGetJourneySegments(journeyMap["id"] as int);
Journey res = Journey.fromMap(journeyMap, await segs); Journey res = Journey.fromMap(journeyMap, await segs);
res.sync();
return res; return res;
} }
@@ -236,12 +234,7 @@ class Journey {
static Future<List<Journey>> dbGetAll({int num = 40, int offset = 0}) async { static Future<List<Journey>> dbGetAll({int num = 40, int offset = 0}) async {
//final batch = DbHelper.db.batch; // later //final batch = DbHelper.db.batch; // later
Database database = DbHelper.db; Database database = DbHelper.db;
var tmp = await database.query( var tmp = await database.query(tableName, limit: num, offset: offset);
tableName,
limit: num,
offset: offset,
orderBy: 'id DESC',
);
Future<List<Journey>> journeys = Future.wait( Future<List<Journey>> journeys = Future.wait(
tmp.map((jour) => fromMapWrapper(jour)), tmp.map((jour) => fromMapWrapper(jour)),
); );
-13
View File
@@ -1,13 +0,0 @@
String timeOf(DateTime fullDT) {
// doing it this way so we always get two digits on the hour
String full = fullDT.toString();
List<String> splits = full.split(" ")[1].split(":");
String time = '${splits[0]}:${splits[1]}';
return time;
}
String dateOf(DateTime fullDT) {
String full = fullDT.toString();
String date = full.split(" ")[0];
return date;
}
@@ -6,10 +6,6 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <dynamic_color/dynamic_color_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) dynamic_color_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin");
dynamic_color_plugin_register_with_registrar(dynamic_color_registrar);
} }
-1
View File
@@ -3,7 +3,6 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
dynamic_color
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST
+14 -22
View File
@@ -65,14 +65,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.9" version: "1.0.9"
dynamic_color:
dependency: "direct main"
description:
name: dynamic_color
sha256: "4aeb76de323e8eb660bab5557d826ad7ebbf1434a598f0c6aa8a11a9696a6757"
url: "https://pub.dev"
source: hosted
version: "1.9.0"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@@ -223,10 +215,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: native_toolchain_c name: native_toolchain_c
sha256: f9c168717100ae6d9fee9ffb0be379bf1f8b26b0f6bcbd4fdddcd931993a6a72 sha256: f59351d28f49520cd3a74eb1f41c5f19ae15e53c65a3231d14af672e46510a96
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.19.2" version: "0.19.1"
path: path:
dependency: transitive dependency: transitive
description: description:
@@ -300,26 +292,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: sqflite_common name: sqflite_common
sha256: "5bf6a55c166e73bf651ba7ec3ed486e577620e3dc8f3a9c6a258a8031b624590" sha256: cce558075afe2a83f3fd7fc123acd6b090683e4f23910d44fbb31ecd7800b014
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.5.11" version: "2.5.9"
sqflite_common_ffi: sqflite_common_ffi:
dependency: "direct main" dependency: "direct dev"
description: description:
name: sqflite_common_ffi name: sqflite_common_ffi
sha256: "5ccd38136edb9beb3213f6927775d52db70dfdadcdb28dad1f625ca9f2b9824f" sha256: "3ddad0ec96ad411d5fea45b4912c3cd5743436c9e1890c26a6e688a32d901cae"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.2" version: "2.4.1"
sqflite_darwin: sqflite_darwin:
dependency: transitive dependency: transitive
description: description:
name: sqflite_darwin name: sqflite_darwin
sha256: c86ca18b8f666bbf903924687fe21cc16fc385d086005067e26619ca530bef9f sha256: "164a5d73ab87a134566057219988bafde837029a64264e61f1f04376ef3cfcd2"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.3+1" version: "2.4.3"
sqflite_platform_interface: sqflite_platform_interface:
dependency: transitive dependency: transitive
description: description:
@@ -329,13 +321,13 @@ packages:
source: hosted source: hosted
version: "2.4.1" version: "2.4.1"
sqlite3: sqlite3:
dependency: "direct main" dependency: "direct dev"
description: description:
name: sqlite3 name: sqlite3
sha256: "64b2c63c8232dd20d14b34105a81ebfd74320442e8451f836179ec89986aa478" sha256: "9488c7d2cdb1091c91cacf7e207cff81b28bff8e366f042bad3afe7d34afe189"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.5.1" version: "3.3.2"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@@ -364,10 +356,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: synchronized name: synchronized
sha256: "61894a1956de6b4fc1aefd0892e109514a1a706cbece3ac59decd90ff5a7a423" sha256: "93b153dcb6a26dcddee6ca087dd634b53e38c10b5aa163e8e49501a776456153"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.4.1+1" version: "3.4.1"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
-3
View File
@@ -37,9 +37,6 @@ dependencies:
flutter_dotenv: ^6.0.1 flutter_dotenv: ^6.0.1
http: ^1.6.0 http: ^1.6.0
sqflite: ^2.4.2+1 sqflite: ^2.4.2+1
sqlite3: ^3.3.0
sqflite_common_ffi: ^2.4.0+3
dynamic_color: ^1.9.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter