Compare commits

...
17 Commits
Author SHA1 Message Date
Nizz05 239f399af1 Merge Firebase_aut branch and resolve pubspec.lock conflict 2026-09-13 15:09:31 +02:00
Nizz05 c0ac104840 Fix Android build and update dependencies 2026-09-13 15:08:31 +02:00
Nizz05 4c548b030c gui login state stays right after closing and reopening the app 2023-05-30 17:01:40 +02:00
Nizz05 fe4f1d52ae changed firebase storage folder name. now includes uid's 2023-05-19 17:57:50 +02:00
Nizz05 3f43a016db addet register site 2023-05-19 17:27:40 +02:00
Nizz05 9d41a5f5f1 changed name from ui to author_id and reduced Resolution from images on pdf list to reduce pdf size 2023-05-19 17:06:12 +02:00
Nizz05 c7fe414bc6 first aut 2023-05-19 14:26:09 +02:00
Nizz05 cf836ada32 merge successfully done 2023-05-16 08:59:04 +02:00
Nizz05 4020dc4d90 Merge branch 'LogIn_Page_Layout' into 'main'
Log in page layout

See merge request Gruber.Nicolas/oggauer_gemeindetrommler!9
2023-05-16 06:53:03 +00:00
Nizz05 32670219d3 Merge branch 'main' into 'LogIn_Page_Layout'
# Conflicts:
#   lib/home.dart
2023-05-16 06:50:49 +00:00
Nizz05 dbec2c6244 Merge branch 'print_pdf' into 'main'
implemented item selection + button to print a list of issues/news etc(Button...

See merge request Gruber.Nicolas/oggauer_gemeindetrommler!8
2023-05-15 09:26:33 +00:00
Nizz05 7062aef03b call clear funktion everywhere where it is useful, moved add button from home to user defined list (helpful for using the clearSelectedItems function) 2023-05-15 11:24:20 +02:00
Nizz05 3a50d7f1bc call clear function when selected index is changed and reduced pdf size by decoded the images before adding it to the pdf 2023-05-15 09:21:43 +02:00
Nizz05 893d095f75 implemented that a list of issues/news can be exported as pdf. 2023-05-14 15:36:29 +02:00
Nizz05 5687670e36 implemented item selection + button to print a list of issues/news etc(Button has no functionality yet). 2023-05-13 19:39:10 +02:00
Nizz05 5d1c30ce9f skipped image cropper funktion if it is already a 1:1 image, plugin for logging 2023-05-13 13:06:37 +02:00
Nizz05 423aae59b1 implemented making a pdf from DetailPage.dart and croping image to 1:1 format 2023-05-11 16:57:17 +02:00
14 changed files with 1109 additions and 384 deletions
+5 -4
View File
@@ -29,16 +29,17 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
namespace "com.oggauergemeindetrommler.app"
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '1.8'
jvmTarget = '17'
}
sourceSets {
@@ -50,7 +51,7 @@ android {
applicationId "com.oggauergemeindetrommler.app"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
minSdkVersion 19
minSdkVersion 23
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
+15 -4
View File
@@ -1,14 +1,14 @@
buildscript {
ext.kotlin_version = '1.6.10'
ext.kotlin_version = '1.9.22'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.1.2'
classpath 'com.android.tools.build:gradle:8.5.2'
// START: FlutterFire Configuration
classpath 'com.google.gms:google-services:4.3.10'
classpath 'com.google.gms:google-services:4.4.1'
// END: FlutterFire Configuration
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
@@ -24,11 +24,22 @@ allprojects {
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
// Inject namespace into plugins that don't have it (required for AGP 8+)
afterEvaluate { project ->
if (project.hasProperty('android')) {
project.android {
if (namespace == null) {
namespace project.group
}
}
}
}
}
subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
+3 -1
View File
@@ -1,3 +1,5 @@
org.gradle.jvmargs=-Xmx1536M
org.gradle.jvmargs=-Xmx1536M -Dandroid.prefs.root=C:/Users/nicol/.android
android.useAndroidX=true
android.enableJetifier=true
android.defaults.buildfeatures.buildconfig=true
org.gradle.java.home=C:/Program Files/Zulu/zulu-20
+1 -1
View File
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
+105 -32
View File
@@ -1,17 +1,19 @@
import 'dart:io';
import 'dart:math';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:image/image.dart' as img;
class AddScreen extends StatefulWidget {
final int initialIndex;
const AddScreen({super.key, required this.initialIndex});
const AddScreen({Key? key, required this.initialIndex}) : super(key: key);
@override
_AddScreenState createState() => _AddScreenState();
}
class _AddScreenState extends State<AddScreen> {
@@ -22,7 +24,6 @@ class _AddScreenState extends State<AddScreen> {
bool _uploading = false;
int _selectedIndex = 0;
@override
void initState() {
super.initState();
@@ -35,6 +36,26 @@ class _AddScreenState extends State<AddScreen> {
return fileSize <= maxSizeInBytes;
}
Future<File> _cropImage(File imageFile) async {
final originalImage = img.decodeImage(await imageFile.readAsBytes());
if (originalImage != null) {
int originSize = min(originalImage.width, originalImage.height);
final croppedImage = img.copyCrop(originalImage,
x: (originalImage.width - originSize) ~/ 2,
y: (originalImage.height - originSize) ~/ 2,
width: originSize,
height: originSize);
final newPath =
imageFile.path.substring(0, imageFile.path.lastIndexOf('/'));
final newFile = File('$newPath/cropped.jpg');
await newFile.writeAsBytes(img.encodePng(croppedImage));
return newFile;
} else {
throw Exception('Unable to decode image file.');
}
}
Future<void> _getImage(ImageSource source) async {
final pickedFile = await ImagePicker().pickImage(source: source);
@@ -42,18 +63,43 @@ class _AddScreenState extends State<AddScreen> {
final tempFile = File(pickedFile.path);
final bool isValid = await isFileSizeValid(tempFile, 10);
if (isValid) {
// Bildinformationen lesen
final originalImage = img.decodeImage(await tempFile.readAsBytes());
if (originalImage != null) {
if (originalImage.width == originalImage.height) {
// Wenn das Bild bereits im 1:1-Format ist, überspringen Sie das Zuschneiden
if (mounted) {
setState(() {
_imageFile = tempFile;
print("1:1");
});
}
} else {
// Wenn das Bild nicht im 1:1-Format ist, schneiden Sie es zu
File croppedFile = await _cropImage(tempFile);
if (mounted) {
setState(() {
_imageFile = croppedFile;
});
print("decode");
}
}
} else {
throw Exception('Unable to decode image file.');
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Die Dateigröße darf maximal 10 MB betragen.')),
const SnackBar(
content: Text('Die Dateigröße darf maximal 10 MB betragen.')),
);
}
}
}
Future<void> addNewElementToFirestore(String title, String description, File imageFile, {required Function(bool) onComplete}) async {
Future<void> addNewElementToFirestore(
String title, String description, File imageFile,
{required Function(bool) onComplete}) async {
String collectionName;
if (_selectedIndex == 0) {
collectionName = "CitizensForum";
@@ -63,36 +109,45 @@ class _AddScreenState extends State<AddScreen> {
collectionName = "Issues";
}
String imageUrl = await uploadImageToFirebaseStorage(imageFile, collectionName);
try
{
String imageUrl =
await uploadImageToFirebaseStorage(imageFile, collectionName);
String? userId = FirebaseAuth.instance.currentUser?.uid; // get the user ID
try {
await FirebaseFirestore.instance.collection(collectionName).add({
"title": title,
"description": description,
"imageUrl": imageUrl,
"createdDate": DateTime.now(),
"author_uid": userId, // add the user ID to the document
});
onComplete(true);
}
catch(e)
{
} catch (e) {
onComplete(false);
}
}
Future<String> uploadImageToFirebaseStorage(File imageFile, String collectionName) async {
Reference ref = FirebaseStorage.instance.ref().child("$collectionName/${DateTime.now().toString()}");
Future<String> uploadImageToFirebaseStorage(
File imageFile, String collectionName) async {
String? userId = FirebaseAuth.instance.currentUser?.uid;
if (userId != null) {
Reference ref = FirebaseStorage.instance
.ref()
.child("$collectionName/$userId/${DateTime.now().toString()}");
UploadTask uploadTask = ref.putFile(imageFile);
return await (await uploadTask).ref.getDownloadURL();
} else {
throw Exception('Cannot upload without user ID');
}
}
@override
Widget build(BuildContext context) {
String appBarTitle = '';
double keyboardHeight = MediaQuery.of(context).viewInsets.bottom;
if (_selectedIndex == 0) {
appBarTitle = 'Neue BürgerForum Information';
} else if (_selectedIndex == 1) {
@@ -122,20 +177,30 @@ class _AddScreenState extends State<AddScreen> {
child: IconButton(
icon: const Icon(Icons.check),
onPressed: () async {
if (_formKey.currentState!.validate() && _imageFile != null && !_uploading) {
if (_formKey.currentState!.validate() &&
_imageFile != null &&
!_uploading) {
setState(() {
_uploading = true;
});
Navigator.pop(context); // Fenster direkt schließen, nachdem der Upload-Button gedrückt wurde.
await addNewElementToFirestore(_titleController.text, _descriptionController.text, _imageFile!, onComplete: (bool success) {
Navigator.pop(
context); // Fenster direkt schließen, nachdem der Upload-Button gedrückt wurde.
await addNewElementToFirestore(
_titleController.text,
_descriptionController.text,
_imageFile!, onComplete: (bool success) {
if (mounted) {
setState(() {
_uploading = false;
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(success ? 'Upload erfolgreich.' : 'Upload fehlgeschlagen.'),
content: Text(success
? 'Upload erfolgreich.'
: 'Upload fehlgeschlagen.'),
),
);
}
});
}
},
@@ -186,7 +251,18 @@ class _AddScreenState extends State<AddScreen> {
),
const SizedBox(height: 16.0),
_imageFile != null
? Image.file(_imageFile!)
? Expanded(
child: LayoutBuilder(
builder: (context, constraints) {
double imageHeight =
max(0, constraints.maxHeight - keyboardHeight);
return Container(
height: imageHeight,
child: Image.file(_imageFile!),
);
},
),
)
: Container(
height: 200.0,
decoration: BoxDecoration(
@@ -198,8 +274,7 @@ class _AddScreenState extends State<AddScreen> {
onPressed: () {
showModalBottomSheet(
context: context,
builder: (context) =>
Column(
builder: (context) => Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
@@ -207,8 +282,8 @@ class _AddScreenState extends State<AddScreen> {
padding: const EdgeInsets.symmetric(
horizontal: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment
.spaceBetween,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
const Text(
'Bild hinzufügen',
@@ -230,8 +305,8 @@ class _AddScreenState extends State<AddScreen> {
child: SizedBox(
height: 80,
child: ListTile(
leading: const Icon(
Icons.photo_library, size: 40),
leading: const Icon(Icons.photo_library,
size: 40),
title: const Text(
'Galerie auswählen',
style: TextStyle(fontSize: 20),
@@ -247,8 +322,8 @@ class _AddScreenState extends State<AddScreen> {
child: SizedBox(
height: 80,
child: ListTile(
leading: const Icon(
Icons.camera_alt, size: 40),
leading: const Icon(Icons.camera_alt,
size: 40),
title: const Text(
'Kamera verwenden',
style: TextStyle(fontSize: 20),
@@ -267,9 +342,7 @@ class _AddScreenState extends State<AddScreen> {
child: Text(
'Bild hinzufügen',
style: TextStyle(
color: Theme
.of(context)
.primaryColor,
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.bold,
),
),
+56 -1
View File
@@ -1,5 +1,9 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'dart:typed_data';
import 'package:pdf/widgets.dart' as pdfWidgets;
import 'package:printing/printing.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:cached_network_image/cached_network_image.dart';
class DetailPage extends StatelessWidget {
final String title;
@@ -15,11 +19,62 @@ class DetailPage extends StatelessWidget {
required this.imageUrl,
}) : super(key: key);
Future<void> _printPdf() async {
final pdf = pdfWidgets.Document();
final image = await _loadNetworkImage(imageUrl);
pdf.addPage(
pdfWidgets.MultiPage(
build: (context) => [
pdfWidgets.Center(
child: pdfWidgets.SizedBox(
width: double.infinity, // Die Breite auf die maximal mögliche Breite setzen
child: pdfWidgets.AspectRatio(
aspectRatio: 1, // Sie können das Seitenverhältnis entsprechend Ihrem Bild anpassen
child: pdfWidgets.Image(image),
),
),
),
pdfWidgets.Text(
title,
style: pdfWidgets.TextStyle(
fontSize: 20,
fontWeight: pdfWidgets.FontWeight.bold // Titel fett
)
),
pdfWidgets.Text(datum, style: const pdfWidgets.TextStyle(fontSize: 14, )),
pdfWidgets.Paragraph(text: description, style: const pdfWidgets.TextStyle(fontSize: 12)),
],
),
);
await Printing.sharePdf(bytes: await pdf.save(), filename: '$title.pdf');
}
Future<pdfWidgets.ImageProvider> _loadNetworkImage(String url) async {
final response = await http.get(Uri.parse(url));
if (response.statusCode != 200) {
throw Exception('Failed to load network image.');
}
final Uint8List bytes = response.bodyBytes;
final imageProvider = pdfWidgets.MemoryImage(bytes);
return imageProvider;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.picture_as_pdf),
onPressed: _printPdf,
),
],
),
body: SingleChildScrollView(
child: Column(
+6 -1
View File
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:oggauergemeindetrommler/register.dart';
class LoginPage extends StatefulWidget {
LoginPage({Key? key}) : super(key: key);
@@ -79,6 +80,11 @@ class _LoginPageState extends State<LoginPage> {
TextButton(
onPressed: () {
// Navigiere zur Registrierungsseite
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const RegisterPage()),
);
},
child: const Text('Registrieren'),
),
@@ -92,4 +98,3 @@ class _LoginPageState extends State<LoginPage> {
);
}
}
+290 -22
View File
@@ -1,16 +1,28 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:printing/printing.dart';
import 'package:provider/provider.dart';
import 'AddPage.dart';
import 'DetailPage.dart';
import 'package:intl/intl.dart';
import 'package:pdf/widgets.dart' as pdfWidgets;
import 'package:http/http.dart' as http;
import 'package:image/image.dart' as img;
import 'anonym_aut.dart';
class UserDefinedItem extends StatelessWidget {
final String title;
final String datum;
final String description;
final String imageUrl;
final Function onLongPress;
final bool isSelected;
final VoidCallback onTap;
const UserDefinedItem({
Key? key,
@@ -18,28 +30,22 @@ class UserDefinedItem extends StatelessWidget {
required this.description,
required this.datum,
required this.imageUrl,
required this.onLongPress,
required this.isSelected,
required this.onTap,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Card(
child: InkWell(
onTap: () {
// Open a new screen when the user taps on the list item
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPage(
title: title,
datum: datum,
description: description,
imageUrl: imageUrl,
),
),
);
},
return InkWell(
onTap:onTap,
onLongPress: onLongPress as void Function()?,
child: Card(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
children: [
SizedBox(
width: 120,
@@ -56,6 +62,19 @@ class UserDefinedItem extends StatelessWidget {
errorWidget: (context, url, error) => const Icon(Icons.error),
),
),
if (isSelected) // Wenn das Element ausgewählt ist, zeigen Sie die Checkbox an
Positioned(
top: 0,
left: 0,
child: Checkbox(
value: isSelected,
onChanged: (bool? value) {
onLongPress(); // Wenn die Checkbox angeklickt wird, rufen Sie die onLongPress-Funktion auf
},
),
),
],
),
Flexible(
flex: 1,
child: Column(
@@ -104,9 +123,13 @@ class UserDefinedItem extends StatelessWidget {
}
}
class GenericList extends StatefulWidget {
final String collectionName;
const GenericList({Key? key, required this.collectionName}) : super(key: key);
final int selectedIndex;
const GenericList({required this.collectionName, required this.selectedIndex});
@override
_GenericListState createState() => _GenericListState();
@@ -114,6 +137,7 @@ class GenericList extends StatefulWidget {
class _GenericListState extends State<GenericList> {
final FirebaseFirestore firestore = FirebaseFirestore.instance;
Map<String, Map<String, dynamic>> selectedItems = {};
@override
void initState() {
@@ -124,6 +148,18 @@ class _GenericListState extends State<GenericList> {
firestore.settings =
const Settings(cacheSizeBytes: Settings.CACHE_SIZE_UNLIMITED);
}
@override
void didUpdateWidget(GenericList oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.selectedIndex != oldWidget.selectedIndex) {
selectedItems.clear();
}
}
void clearSelectedItems() {
setState(() {
selectedItems.clear();
});
}
Stream<QuerySnapshot> getDocumentStream() {
return firestore
@@ -139,7 +175,9 @@ class _GenericListState extends State<GenericList> {
await FirebaseStorage.instance.refFromURL(imageUrl).delete();
}
// Löschen Sie das Dokument von der Firestore-Kollektion
await firestore.collection(widget.collectionName).doc(documentId).delete();
await firestore.collection(widget.collectionName)
.doc(documentId)
.delete();
} catch (e) {
if (kDebugMode) {
print('Error deleting document: $e');
@@ -149,9 +187,13 @@ class _GenericListState extends State<GenericList> {
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
return Scaffold(
body: Stack(
children: [
StreamBuilder<QuerySnapshot>(
stream: getDocumentStream(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
@@ -159,7 +201,8 @@ class _GenericListState extends State<GenericList> {
case ConnectionState.waiting:
return const Text('Loading...');
default:
final List<QueryDocumentSnapshot> documents = snapshot.data!.docs;
final List<QueryDocumentSnapshot> documents = snapshot.data!
.docs;
return ListView.builder(
itemCount: documents.length,
itemBuilder: (BuildContext context, int index) {
@@ -169,6 +212,9 @@ class _GenericListState extends State<GenericList> {
final DateTime createdDate = data['createdDate'].toDate();
final formattedDate =
DateFormat('dd.MM.yyyy').format(createdDate);
final currentUser = FirebaseAuth.instance.currentUser;
if (currentUser != null && data['author_uid'] == currentUser.uid) {
return Dismissible(
key: UniqueKey(),
direction: DismissDirection.endToStart,
@@ -190,12 +236,234 @@ class _GenericListState extends State<GenericList> {
datum: formattedDate,
description: data['description'] ?? '',
imageUrl: data['imageUrl'] ?? '',
isSelected: selectedItems.containsKey(documentId),
onTap: () {
clearSelectedItems();
// Open a new screen when the user taps on the list item
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPage(
title: data['title'],
datum: formattedDate,
description: data['description'],
imageUrl: data['imageUrl'],
),
),
);
},
);
onLongPress: () {
setState(() {
if (selectedItems.containsKey(documentId)) {
selectedItems.remove(documentId);
} else {
selectedItems[documentId] = data;
}
});
},
),
);
} else {
return UserDefinedItem(
title: data['title'] ?? '',
datum: formattedDate,
description: data['description'] ?? '',
imageUrl: data['imageUrl'] ?? '',
isSelected: selectedItems.containsKey(documentId),
onTap: () {
clearSelectedItems();
// Open a new screen when the user taps on the list item
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPage(
title: data['title'],
datum: formattedDate,
description: data['description'],
imageUrl: data['imageUrl'],
),
),
);
},
onLongPress: () {
setState(() {
if (selectedItems.containsKey(documentId)) {
selectedItems.remove(documentId);
} else {
selectedItems[documentId] = data;
}
});
},
);
}
},
);
}
},
),
if (selectedItems.isNotEmpty)
Stack(
children: [
Align(
alignment: Alignment.topRight,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: FloatingActionButton(
backgroundColor: Colors.blue,
onPressed: () {
clearSelectedItems();
},
tooltip: "Auswahl zurücksetzen",
child: const Icon(Icons.refresh),
),
),
),
Align(
alignment: Alignment.bottomLeft,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: FloatingActionButton(
backgroundColor: Colors.red,
onPressed: () => _printSelectedItemsAsPdf(widget.selectedIndex),
tooltip: "Ausgewählte Elemente als pdf speichern",
child: const Icon(Icons.picture_as_pdf),
),
),
),
],
),
],
),
floatingActionButton: Consumer<AuthState>(
builder: (context, authState, child) {
if (authState.user != null) {
return FloatingActionButton(
onPressed: () {
clearSelectedItems();
Navigator.push(
context,
MaterialPageRoute(builder: (context) => AddScreen(initialIndex: widget.selectedIndex)),
);
},
tooltip: "Neues Element hinzufügen",
child: const Icon(Icons.add),
);
} else {
return Container(); // Return an empty container when the user is not signed in
}
},
),
);
}
Future<pdfWidgets.ImageProvider> _loadNetworkImage(String url) async {
final response = await http.get(Uri.parse(url));
if (response.statusCode != 200) {
throw Exception('Failed to load network image.');
}
final Uint8List bytes = response.bodyBytes;
final img.Image? image = img.decodeImage(bytes);
final img.Image resizedImage = img.copyResize(image!, width: 290); // Beispielwert für die Breite
final Uint8List resizedBytes = Uint8List.fromList(img.encodeJpg(resizedImage));
final imageProvider = pdfWidgets.MemoryImage(resizedBytes);
return imageProvider;
}
Future<void> _printSelectedItemsAsPdf(int selectedIndex) async {
final pdfWidgets.Document pdf = pdfWidgets.Document();
final List<pdfWidgets.Widget> items = [];
for (final entry in selectedItems.entries) {
final String title = entry.value['title'] ?? '';
final String description = (entry.value['description'] ?? '').length > 165 ? (entry.value['description'] ?? '').substring(0, 165) + '...' : (entry.value['description'] ?? '');
final String imageUrl = entry.value['imageUrl'] ?? '';
final DateTime date = entry.value['createdDate'].toDate();
final String formattedDate = DateFormat('dd.MM.yyyy').format(date);
final pdfWidgets.ImageProvider imageProvider = await _loadNetworkImage(imageUrl);
items.add(
pdfWidgets.Container(
height: 145, // Begrenzt die Höhe des Containers
padding: const pdfWidgets.EdgeInsets.all(5.0), // Reduziert den Abstand
child: pdfWidgets.Row(
children: [
pdfWidgets.Container(
width: 145, // Reduziert die Breite des Bildes
height: 145, // Reduziert die Höhe des Bildes
child: pdfWidgets.Image(imageProvider),
),
pdfWidgets.Flexible(
child: pdfWidgets.Padding(
padding: const pdfWidgets.EdgeInsets.all(5.0), // Reduziert den Abstand
child: pdfWidgets.Column(
crossAxisAlignment: pdfWidgets.CrossAxisAlignment.start,
children: [
pdfWidgets.Row(
mainAxisAlignment: pdfWidgets.MainAxisAlignment.spaceBetween,
children: [
pdfWidgets.Flexible(
child: pdfWidgets.Text(
title,
style: pdfWidgets.TextStyle(
fontSize: 20, fontWeight: pdfWidgets.FontWeight.bold),
),
),
pdfWidgets.Text(
formattedDate,
style: const pdfWidgets.TextStyle(
fontSize: 15,
),
),
],
),
pdfWidgets.Padding(
padding: const pdfWidgets.EdgeInsets.all(5.0), // Reduziert den Abstand
child: pdfWidgets.Text(
description,
style: const pdfWidgets.TextStyle(
fontSize: 15,
),
),
),
],
),
),
),
],
),
),
);
}
pdf.addPage(
pdfWidgets.MultiPage(
build: (pdfWidgets.Context context) => items,
),
);
String filename;
switch(selectedIndex) {
case 0:
filename = 'Bürgerforum_items.pdf';
break;
case 1:
filename = 'Neuigkeiten_items.pdf';
break;
case 2:
filename = 'Mängel_items.pdf';
break;
default:
filename = 'selected_items.pdf';
}
await Printing.sharePdf(bytes: await pdf.save(), filename: filename);
clearSelectedItems();
}
}
+55
View File
@@ -0,0 +1,55 @@
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:provider/provider.dart';
class AuthState extends ChangeNotifier {
FirebaseAuth auth = FirebaseAuth.instance;
User? _user;
User? get user => _user;
AuthState() {
auth.authStateChanges().listen((User? user) {
if (user == null) {
print('User is currently signed out!');
_user = null;
} else {
print('User is signed in!');
_user = user;
}
notifyListeners();
});
}
Future<void> signInAnonymously() async {
try {
await auth.signInAnonymously();
} catch (e) {
print(e);
}
}
Future<void> signOut() async {
await auth.signOut();
}
}
class AnonymAuthScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Consumer<AuthState>(
builder: (context, authState, child) {
return ElevatedButton(
onPressed: authState.user == null
? authState.signInAnonymously
: authState.signOut,
child: Text(authState.user == null ? 'Anonym anmelden' : 'Abmelden'),
);
},
),
),
);
}
}
+5 -20
View File
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:oggauergemeindetrommler/LoginPage.dart';
import 'AddPage.dart';
import 'UserDefinedList.dart';
import 'anonym_aut.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title});
@@ -21,10 +21,10 @@ class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
final List<Widget> widgetOptions = <Widget>[
const GenericList(collectionName: 'CitizensForum'),
const GenericList(collectionName: 'News'),
const GenericList(collectionName: 'Issues'),
LoginPage()
const GenericList(collectionName: 'CitizensForum', selectedIndex: 0,),
const GenericList(collectionName: 'News', selectedIndex: 1,),
const GenericList(collectionName: 'Issues', selectedIndex: 2,),
AnonymAuthScreen()
];
return Scaffold(
@@ -34,21 +34,6 @@ class _MyHomePageState extends State<MyHomePage> {
body: Center(
child: widgetOptions.elementAt(_selectedIndex),
),
floatingActionButton: _selectedIndex == 3
? null
: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
AddScreen(initialIndex: _selectedIndex),
),
);
},
tooltip: 'Add',
child: const Icon(Icons.add),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
+9 -2
View File
@@ -1,4 +1,6 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'anonym_aut.dart';
import 'home.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
@@ -8,10 +10,15 @@ void main() async {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(const MyApp());
runApp(
ChangeNotifierProvider(
create: (context) => AuthState(),
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
+98
View File
@@ -0,0 +1,98 @@
import 'package:flutter/material.dart';
class RegisterPage extends StatefulWidget {
const RegisterPage({Key? key}) : super(key: key);
@override
_RegisterPageState createState() => _RegisterPageState();
}
class _RegisterPageState extends State<RegisterPage> {
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
final _confirmPasswordController = TextEditingController();
@override
void dispose() {
_emailController.dispose();
_passwordController.dispose();
_confirmPasswordController.dispose();
super.dispose();
}
bool isValidEmail(String email) {
// Die gleiche Validierung wie in Ihrer LoginPage
return RegExp(r'^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$').hasMatch(email);
}
bool arePasswordsMatching(String password, String confirmPassword) {
return password == confirmPassword;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const SizedBox(height: 16),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 32),
child: Column(
children: [
TextFormField(
controller: _emailController,
decoration: const InputDecoration(
labelText: 'E-Mail',
),
validator: (value) {
if (value!.isEmpty) {
return 'Bitte geben Sie eine E-Mail-Adresse ein.';
} else if (!isValidEmail(value)) {
return 'Bitte geben Sie eine gültige E-Mail-Adresse ein.';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
controller: _passwordController,
obscureText: true,
decoration: const InputDecoration(
labelText: 'Passwort',
),
),
const SizedBox(height: 16),
TextFormField(
controller: _confirmPasswordController,
obscureText: true,
decoration: const InputDecoration(
labelText: 'Passwort bestätigen',
),
),
ElevatedButton(
onPressed: () {
String email = _emailController.text;
String password = _passwordController.text;
String confirmPassword = _confirmPasswordController.text;
if (isValidEmail(email) && arePasswordsMatching(password, confirmPassword)) {
// E-Mail und Passwörter sind gültig, führe die entsprechende Aktion aus
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Ungültige Eingaben'),
duration: Duration(seconds: 2),
),
);
}
},
child: const Text('Registrieren'),
),
],
),
),
],
),
);
}
}
+322 -162
View File
@@ -5,26 +5,42 @@ packages:
dependency: transitive
description:
name: _flutterfire_internals
sha256: "867b77e2367bc502dcd4d5a66302615409f04eb20ed82ba1c0ba073f9107e018"
sha256: "9371d13b8ee442e3bfc08a24e3a1b3742c839abbfaf5eef11b79c4b862c89bf7"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
version: "1.3.41"
archive:
dependency: transitive
description:
name: archive
sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a"
sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff
url: "https://pub.dev"
source: hosted
version: "3.3.7"
version: "4.0.9"
async:
dependency: transitive
description:
name: async
sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.10.0"
version: "2.11.0"
barcode:
dependency: transitive
description:
name: barcode
sha256: "7b6729c37e3b7f34233e2318d866e8c48ddb46c1f7ad01ff7bb2a8de1da2b9f4"
url: "https://pub.dev"
source: hosted
version: "2.2.9"
bidi:
dependency: transitive
description:
name: bidi
sha256: "77f475165e94b261745cf1032c751e2032b8ed92ccb2bf5716036db79320637d"
url: "https://pub.dev"
source: hosted
version: "2.0.13"
boolean_selector:
dependency: transitive
description:
@@ -37,42 +53,42 @@ packages:
dependency: "direct main"
description:
name: cached_network_image
sha256: fd3d0dc1d451f9a252b32d95d3f0c3c487bc41a75eba2e6097cb0b9c71491b15
sha256: "4a5d8d2c728b0f3d0245f69f921d7be90cae4c2fd5288f773088672c0893f819"
url: "https://pub.dev"
source: hosted
version: "3.2.3"
version: "3.4.0"
cached_network_image_platform_interface:
dependency: transitive
description:
name: cached_network_image_platform_interface
sha256: bb2b8403b4ccdc60ef5f25c70dead1f3d32d24b9d6117cfc087f496b178594a7
sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
version: "4.1.1"
cached_network_image_web:
dependency: transitive
description:
name: cached_network_image_web
sha256: b8eb814ebfcb4dea049680f8c1ffb2df399e4d03bf7a352c775e26fa06e02fa0
sha256: "6322dde7a5ad92202e64df659241104a43db20ed594c41ca18de1014598d7996"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
version: "1.3.0"
change_app_package_name:
dependency: "direct main"
description:
name: change_app_package_name
sha256: f9ebaf68a4b5a68c581492579bb68273c523ef325fbf9ce2f1b57fb136ad023b
sha256: "8e43b754fe960426904d77ed4c62fa8c9834deaf6e293ae40963fa447482c4c5"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
version: "1.5.0"
characters:
dependency: transitive
description:
name: characters
sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "1.3.0"
clock:
dependency: transitive
description:
@@ -85,50 +101,42 @@ packages:
dependency: "direct main"
description:
name: cloud_firestore
sha256: "1ba6da0f5c07323b62c3843da98d18f49020b0a337a2b3faf66e207609fa4742"
sha256: "0af4f1e0b7f82a2082ad2c886b042595d85c7641616688609dd999d33aeef850"
url: "https://pub.dev"
source: hosted
version: "4.6.0"
version: "5.4.0"
cloud_firestore_platform_interface:
dependency: transitive
description:
name: cloud_firestore_platform_interface
sha256: "804e212c180abb50d861e5cf18e86cd621806f7cf6ebf926e8871db7a7a7efe5"
sha256: "6e82bcaf2b8e33f312dfc7c5e5855376fee538467dd6e58dc41bd13996ff5d64"
url: "https://pub.dev"
source: hosted
version: "5.13.0"
version: "6.4.0"
cloud_firestore_web:
dependency: transitive
description:
name: cloud_firestore_web
sha256: "4ecd040aaaa475096f2565e556e7b515b368a2cb893add50da31019fa8102d35"
sha256: "38aec6ed732980dea6eec192a25fb55665137edc5c356603d8dc26ff5971f4d8"
url: "https://pub.dev"
source: hosted
version: "3.4.3"
version: "4.2.0"
collection:
dependency: transitive
description:
name: collection
sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.17.0"
convert:
dependency: transitive
description:
name: convert
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
version: "1.18.0"
cross_file:
dependency: transitive
description:
name: cross_file
sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9"
sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
url: "https://pub.dev"
source: hosted
version: "0.3.3+4"
version: "0.3.4+2"
crypto:
dependency: transitive
description:
@@ -141,10 +149,10 @@ packages:
dependency: "direct main"
description:
name: cupertino_icons
sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
url: "https://pub.dev"
source: hosted
version: "1.0.5"
version: "1.0.8"
fake_async:
dependency: transitive
description:
@@ -157,127 +165,159 @@ packages:
dependency: transitive
description:
name: ffi
sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978
sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "2.1.3"
file:
dependency: transitive
description:
name: file
sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
url: "https://pub.dev"
source: hosted
version: "6.1.4"
version: "7.0.1"
file_selector_linux:
dependency: transitive
description:
name: file_selector_linux
sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33"
url: "https://pub.dev"
source: hosted
version: "0.9.3+2"
file_selector_macos:
dependency: transitive
description:
name: file_selector_macos
sha256: "271ab9986df0c135d45c3cdb6bd0faa5db6f4976d3e4b437cf7d0f258d941bfc"
url: "https://pub.dev"
source: hosted
version: "0.9.4+2"
file_selector_platform_interface:
dependency: transitive
description:
name: file_selector_platform_interface
sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b
url: "https://pub.dev"
source: hosted
version: "2.6.2"
file_selector_windows:
dependency: transitive
description:
name: file_selector_windows
sha256: "8f5d2f6590d51ecd9179ba39c64f722edc15226cc93dcc8698466ad36a4a85a4"
url: "https://pub.dev"
source: hosted
version: "0.9.3+3"
firebase_auth:
dependency: "direct main"
description:
name: firebase_auth
sha256: "76da24b6c2aee88694d42c1a8896bc84d85adbd4a7801f376f1cce6dc8b09a15"
sha256: "6f5792bdc208416bfdfbfe3363b78ce01667b6ebc4c5cb47cfa891f2fca45ab7"
url: "https://pub.dev"
source: hosted
version: "4.5.0"
version: "5.2.0"
firebase_auth_platform_interface:
dependency: transitive
description:
name: firebase_auth_platform_interface
sha256: "4d30c51a60df38e7ba2240fe9dbf8d5c17f7e51b8699f66ae3b263927a0ab586"
sha256: "80237bb8a92bb0a5e3b40de1c8dbc80254e49ac9e3907b4b47b8e95ac3dd3fad"
url: "https://pub.dev"
source: hosted
version: "6.14.0"
version: "7.4.4"
firebase_auth_web:
dependency: transitive
description:
name: firebase_auth_web
sha256: de446cda07814ce690688830748fd9857fc4027e8434f8a8af11c8d4619c2197
sha256: "9d315491a6be65ea83511cb0e078544a309c39dd54c0ee355c51dbd6d8c03cc8"
url: "https://pub.dev"
source: hosted
version: "5.4.0"
version: "5.12.6"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
sha256: dcf54c170c5371ad0e79229d0fb372c58262ae0968b7de222bf28e51dd236be0
sha256: "06537da27db981947fa535bb91ca120b4e9cb59cb87278dbdde718558cafc9ff"
url: "https://pub.dev"
source: hosted
version: "2.11.0"
version: "3.4.0"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
sha256: ae79f335f6c7f2dadb00c98c429da2ca905d265e0225fb5e7dfa62ac3accad48
sha256: "8bcfad6d7033f5ea951d15b867622a824b13812178bfec0c779b9d81de011bbb"
url: "https://pub.dev"
source: hosted
version: "4.7.0"
version: "5.4.2"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
sha256: e57ef862257a0d977c1308d02e2fbb9b68525e6d85711b08f3df8cec836fb444
sha256: "362e52457ed2b7b180964769c1e04d1e0ea0259fdf7025fdfedd019d4ae2bd88"
url: "https://pub.dev"
source: hosted
version: "2.4.0"
version: "2.17.5"
firebase_storage:
dependency: "direct main"
description:
name: firebase_storage
sha256: "1861a9ecf3ec0f62745a6e3145b80d619cc3ed8ff41e1cd43529b52ba0ecff6a"
sha256: dfc06d783dbc0b6200a4b936d8cdbd826bd1571c959854d14a70259188d96e85
url: "https://pub.dev"
source: hosted
version: "11.1.2"
version: "12.2.0"
firebase_storage_platform_interface:
dependency: transitive
description:
name: firebase_storage_platform_interface
sha256: "88080a166ae062a0a57ace8a86294ee6a9c60fe377d4a93bab725a243380a887"
sha256: "3da511301b77514dee5370281923fbbc6d5725c2a0b96004c5c45415e067f234"
url: "https://pub.dev"
source: hosted
version: "4.3.0"
version: "5.1.28"
firebase_storage_web:
dependency: transitive
description:
name: firebase_storage_web
sha256: bd89a28c58d4f18ff5d9b4e3358520a5540800d933709bb2c1ff36b83e396f09
sha256: "7ad67b1c1c46c995a6bd4f225d240fc9a5fb277fade583631ae38750ffd9be17"
url: "https://pub.dev"
source: hosted
version: "3.5.0"
version: "3.9.13"
fixnum:
dependency: transitive
description:
name: fixnum
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
url: "https://pub.dev"
source: hosted
version: "1.1.1"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_blurhash:
dependency: transitive
description:
name: flutter_blurhash
sha256: "05001537bd3fac7644fa6558b09ec8c0a3f2eba78c0765f88912882b1331a5c6"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
flutter_cache_manager:
dependency: transitive
description:
name: flutter_cache_manager
sha256: "32cd900555219333326a2d0653aaaf8671264c29befa65bbd9856d204a4c9fb3"
sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386"
url: "https://pub.dev"
source: hosted
version: "3.3.0"
version: "3.4.1"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "4.0.0"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "8ffe990dac54a4a5492747added38571a5ab474c8e5d196809ea08849c69b1bb"
sha256: "8cf40eebf5dec866a6d1956ad7b4f7016e6c0cc69847ab946833b7d43743809f"
url: "https://pub.dev"
source: hosted
version: "2.0.13"
version: "2.0.19"
flutter_test:
dependency: "direct dev"
description: flutter
@@ -292,10 +332,10 @@ packages:
dependency: transitive
description:
name: http
sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2"
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
url: "https://pub.dev"
source: hosted
version: "0.13.6"
version: "1.2.2"
http_parser:
dependency: transitive
description:
@@ -308,218 +348,330 @@ packages:
dependency: "direct main"
description:
name: image
sha256: "73964e3609fb96e01e69b0924b939967c556e46c7ff05db2ea9e31019000f4ef"
sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928"
url: "https://pub.dev"
source: hosted
version: "4.0.16"
version: "4.5.4"
image_cropper:
dependency: "direct main"
description:
name: image_cropper
sha256: "7c3a85e54ec591738ee68f3cc9b8849bab0ec8e908bf8970645be959a079e17f"
url: "https://pub.dev"
source: hosted
version: "8.0.1"
image_cropper_for_web:
dependency: transitive
description:
name: image_cropper_for_web
sha256: "65f3f23fb82ff153601f22864e07e2ec14a7859db9e6ee5f643f0cde5243e9f2"
url: "https://pub.dev"
source: hosted
version: "6.0.1"
image_cropper_platform_interface:
dependency: transitive
description:
name: image_cropper_platform_interface
sha256: "2d8db8f4b638e448fa89a1e77cd8f053b4547472bd3ae073169e86626d03afef"
url: "https://pub.dev"
source: hosted
version: "7.2.0"
image_picker:
dependency: "direct main"
description:
name: image_picker
sha256: "3da954c3b8906d82ecb50fd5e2b5401758f06d5678904eed6cbc06172283a263"
sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a"
url: "https://pub.dev"
source: hosted
version: "0.8.7+4"
version: "1.1.2"
image_picker_android:
dependency: transitive
description:
name: image_picker_android
sha256: "271e0448e82268b3fa1cb2a48e4a911cbc2135587123d7df8e7ca703c5b10da2"
sha256: "0f57fee1e8bfadf8cc41818bbcd7f72e53bb768a54d9496355d5e8a5681a19f1"
url: "https://pub.dev"
source: hosted
version: "0.8.6+11"
version: "0.8.12+1"
image_picker_for_web:
dependency: transitive
description:
name: image_picker_for_web
sha256: "98f50d6b9f294c8ba35e25cc0d13b04bfddd25dbc8d32fa9d566a6572f2c081c"
sha256: "65d94623e15372c5c51bebbcb820848d7bcb323836e12dfdba60b5d3a8b39e50"
url: "https://pub.dev"
source: hosted
version: "2.1.12"
version: "3.0.5"
image_picker_ios:
dependency: transitive
description:
name: image_picker_ios
sha256: a1546ff5861fc15812953d4733b520c3d371cec3d2859a001ff04c46c4d81883
sha256: "4f0568120c6fcc0aaa04511cb9f9f4d29fc3d0139884b1d06be88dcec7641d6b"
url: "https://pub.dev"
source: hosted
version: "0.8.7+3"
version: "0.8.12+1"
image_picker_linux:
dependency: transitive
description:
name: image_picker_linux
sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa"
url: "https://pub.dev"
source: hosted
version: "0.2.1+1"
image_picker_macos:
dependency: transitive
description:
name: image_picker_macos
sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62"
url: "https://pub.dev"
source: hosted
version: "0.2.1+1"
image_picker_platform_interface:
dependency: transitive
description:
name: image_picker_platform_interface
sha256: "1991219d9dbc42a99aff77e663af8ca51ced592cd6685c9485e3458302d3d4f8"
sha256: "9ec26d410ff46f483c5519c29c02ef0e02e13a543f882b152d4bfd2f06802f80"
url: "https://pub.dev"
source: hosted
version: "2.6.3"
version: "2.10.0"
image_picker_windows:
dependency: transitive
description:
name: image_picker_windows
sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb"
url: "https://pub.dev"
source: hosted
version: "0.2.1+1"
intl:
dependency: "direct main"
description:
name: intl
sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
url: "https://pub.dev"
source: hosted
version: "0.17.0"
version: "0.20.2"
js:
dependency: transitive
description:
name: js
sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
url: "https://pub.dev"
source: hosted
version: "0.6.5"
version: "0.7.1"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
url: "https://pub.dev"
source: hosted
version: "10.0.0"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
url: "https://pub.dev"
source: hosted
version: "2.0.1"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
url: "https://pub.dev"
source: hosted
version: "2.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593"
sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "4.0.0"
logging:
dependency: "direct main"
description:
name: logging
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
matcher:
dependency: transitive
description:
name: matcher
sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
url: "https://pub.dev"
source: hosted
version: "0.12.13"
version: "0.12.16+1"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
url: "https://pub.dev"
source: hosted
version: "0.2.0"
version: "0.8.0"
meta:
dependency: transitive
description:
name: meta
sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
url: "https://pub.dev"
source: hosted
version: "1.8.0"
version: "1.11.0"
mime:
dependency: transitive
description:
name: mime
sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a"
url: "https://pub.dev"
source: hosted
version: "1.0.6"
octo_image:
dependency: transitive
description:
name: octo_image
sha256: "107f3ed1330006a3bea63615e81cf637433f5135a52466c7caa0e7152bca9143"
sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
version: "2.1.0"
path:
dependency: transitive
description:
name: path
sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.dev"
source: hosted
version: "1.8.2"
version: "1.9.0"
path_parsing:
dependency: transitive
description:
name: path_parsing
sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
path_provider:
dependency: transitive
description:
name: path_provider
sha256: c7edf82217d4b2952b2129a61d3ad60f1075b9299e629e149a8d2e39c2e6aad4
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
url: "https://pub.dev"
source: hosted
version: "2.0.14"
version: "2.1.4"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86"
sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
url: "https://pub.dev"
source: hosted
version: "2.0.27"
version: "2.2.4"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: ad4c4d011830462633f03eb34445a45345673dfd4faf1ab0b4735fbd93b19183
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
url: "https://pub.dev"
source: hosted
version: "2.2.2"
version: "2.4.1"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: "2ae08f2216225427e64ad224a24354221c2c7907e448e6e0e8b57b1eb9f10ad1"
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev"
source: hosted
version: "2.1.10"
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec"
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
url: "https://pub.dev"
source: hosted
version: "2.0.6"
version: "2.1.2"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: d3f80b32e83ec208ac95253e0cd4d298e104fbc63cb29c5c69edaed43b0c69d6
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
url: "https://pub.dev"
source: hosted
version: "2.1.6"
pedantic:
version: "2.3.0"
pdf:
dependency: "direct main"
description:
name: pdf
sha256: "28eacad99bffcce2e05bba24e50153890ad0255294f4dd78a17075a2ba5c8416"
url: "https://pub.dev"
source: hosted
version: "3.11.3"
pdf_widget_wrapper:
dependency: transitive
description:
name: pedantic
sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602"
name: pdf_widget_wrapper
sha256: "9c3ca36e5000c9682d52bbdc486867ba7c5ee4403d1a5d6d03ed72157753377b"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
version: "1.0.3"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4"
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
url: "https://pub.dev"
source: hosted
version: "5.1.0"
version: "6.0.2"
platform:
dependency: transitive
description:
name: platform
sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
version: "3.1.6"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc"
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
pointycastle:
version: "2.1.8"
posix:
dependency: transitive
description:
name: pointycastle
sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
name: posix
sha256: bc1bad54ad2b735816e31f8d4600cfde6c7839975085ddfbca48b6c9f7c4044e
url: "https://pub.dev"
source: hosted
version: "3.7.3"
process:
version: "6.5.2"
printing:
dependency: "direct main"
description:
name: printing
sha256: "1c99cab90ebcc1fff65831d264627d5b529359d563e53f33ab9b8117f2d280bc"
url: "https://pub.dev"
source: hosted
version: "5.12.0"
qr:
dependency: transitive
description:
name: process
sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
name: qr
sha256: "64957a3930367bf97cc211a5af99551d630f2f4625e38af10edd6b19131b64b3"
url: "https://pub.dev"
source: hosted
version: "4.2.4"
version: "3.0.1"
rxdart:
dependency: transitive
description:
name: rxdart
sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb"
sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962"
url: "https://pub.dev"
source: hosted
version: "0.27.7"
version: "0.28.0"
sky_engine:
dependency: transitive
description: flutter
@@ -529,42 +681,42 @@ packages:
dependency: transitive
description:
name: source_span
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
sqflite:
dependency: transitive
description:
name: sqflite
sha256: acf091c6e55c50d00b30b8532b2dd23e393cf775861665ebd0f15cdd6ebfb079
sha256: a43e5a27235518c03ca238e7b4732cf35eabe863a369ceba6cbefa537a66f16d
url: "https://pub.dev"
source: hosted
version: "2.2.8+1"
version: "2.3.3+1"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
sha256: e77abf6ff961d69dfef41daccbb66b51e9983cdd5cb35bf30733598057401555
sha256: "3da423ce7baf868be70e2c0976c28a1bb2f73644268b7ffa7d2e08eab71f16a4"
url: "https://pub.dev"
source: hosted
version: "2.4.5"
version: "2.5.4"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.0"
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
string_scanner:
dependency: transitive
description:
@@ -577,10 +729,10 @@ packages:
dependency: transitive
description:
name: synchronized
sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60"
sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
version: "3.1.0+1"
term_glyph:
dependency: transitive
description:
@@ -593,26 +745,26 @@ packages:
dependency: transitive
description:
name: test_api
sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.4.16"
version: "0.6.1"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.1"
version: "1.3.2"
uuid:
dependency: transitive
description:
name: uuid
sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
sha256: "9b129329f58692f6e6578329498a8fe9fbe98f090beb764ffbb8ee2eadd01dcd"
url: "https://pub.dev"
source: hosted
version: "3.0.7"
version: "4.6.0"
vector_math:
dependency: transitive
description:
@@ -621,30 +773,38 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
win32:
vm_service:
dependency: transitive
description:
name: win32
sha256: dd8f9344bc305ae2923e3d11a2a911d9a4e2c7dd6fe0ed10626d63211a69676e
name: vm_service
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
url: "https://pub.dev"
source: hosted
version: "4.1.3"
version: "13.0.0"
web:
dependency: transitive
description:
name: web
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
url: "https://pub.dev"
source: hosted
version: "0.5.1"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
version: "1.1.0"
xml:
dependency: transitive
description:
name: xml
sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5"
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
url: "https://pub.dev"
source: hosted
version: "6.2.2"
version: "6.5.0"
sdks:
dart: ">=2.19.0 <3.0.0"
flutter: ">=3.3.0"
dart: ">=3.3.0 <4.0.0"
flutter: ">=3.19.0"
+12 -7
View File
@@ -32,21 +32,26 @@ environment:
dependencies:
flutter:
sdk: flutter
intl: ^0.17.0
intl: ^0.20.2
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
image_picker: ^0.8.6+3
firebase_core: ^2.11.0
firebase_auth: ^4.5.0
firebase_storage: ^11.1.0
cloud_firestore: ^4.6.0
image_picker: ^1.1.2
firebase_core: ^3.4.0
firebase_auth: ^5.2.0
firebase_storage: ^12.2.0
cloud_firestore: ^5.4.0
change_app_package_name: ^1.1.0
cached_network_image: ^3.2.3
image: ^4.0.16
pdf: ^3.10.1
printing: ^5.10.4
image_cropper: ^8.0.1
logging: ^1.1.1
provider: ^6.0.5
dev_dependencies:
@@ -58,7 +63,7 @@ dev_dependencies:
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0
flutter_lints: ^4.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec