updated project style guidelines

This commit is contained in:
2024-04-03 19:18:17 +02:00
parent 27618f4404
commit 4c7f53e309
185 changed files with 505 additions and 873 deletions

View File

@ -20,9 +20,7 @@ class Login extends StatefulWidget {
class _LoginState extends State<Login> {
bool displayDisclaimerText = true;
String? _checkInput(value){
return (value ?? '').length == 0 ? 'Eingabe erforderlich' : null;
}
String? _checkInput(value)=> (value ?? '').length == 0 ? 'Eingabe erforderlich' : null;
Future<String?> _login(LoginData data) async {
await AccountData().removeData();
@ -49,15 +47,10 @@ class _LoginState extends State<Login> {
return null;
}
Future<String> _resetPassword(String name) {
return Future.delayed(Duration.zero).then((_) {
return 'Diese Funktion steht nicht zur Verfügung!';
});
}
Future<String> _resetPassword(String name) => Future.delayed(Duration.zero).then((_) => 'Diese Funktion steht nicht zur Verfügung!');
@override
Widget build(BuildContext context) {
return FlutterLogin(
Widget build(BuildContext context) => FlutterLogin(
logo: Image.asset('assets/logo/icon.png').image,
userValidator: _checkInput,
@ -109,5 +102,4 @@ class _LoginState extends State<Login> {
userType: LoginUserType.name,
);
}
}

View File

@ -26,14 +26,14 @@ class FileElement extends StatefulWidget {
const FileElement(this.file, this.path, this.refetch, {super.key});
static Future<DownloaderCore> download(BuildContext context, String remotePath, String name, Function(double) onProgress, Function(OpenResult) onDone) async {
Directory paths = await getTemporaryDirectory();
var paths = await getTemporaryDirectory();
var encodedPath = Uri.encodeComponent(remotePath);
encodedPath = encodedPath.replaceAll('%2F', '/');
String local = paths.path + Platform.pathSeparator + name;
var local = paths.path + Platform.pathSeparator + name;
DownloaderUtils options = DownloaderUtils(
var options = DownloaderUtils(
progressCallback: (current, total) {
final progress = (current / total) * 100;
onProgress(progress);
@ -52,7 +52,7 @@ class FileElement extends StatefulWidget {
);
return await Flowder.download(
"${await WebdavApi.webdavConnectString}$encodedPath",
'${await WebdavApi.webdavConnectString}$encodedPath',
options,
);
}
@ -89,8 +89,7 @@ class _FileElementState extends State<FileElement> {
}
@override
Widget build(BuildContext context) {
return ListTile(
Widget build(BuildContext context) => ListTile(
leading: CenteredLeading(
Icon(widget.file.isDirectory ? Icons.folder : Icons.description_outlined)
),
@ -100,9 +99,7 @@ class _FileElementState extends State<FileElement> {
onTap: () {
if(widget.file.isDirectory) {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) {
return Files(widget.path.toList()..add(widget.file.name));
},
builder: (context) => Files(widget.path.toList()..add(widget.file.name)),
));
} else {
if(EndpointData().getEndpointMode() == EndpointMode.stage) {
@ -141,12 +138,10 @@ class _FileElementState extends State<FileElement> {
setState(() => percent = progress);
}, (result) {
if(result.type != ResultType.done) {
showDialog(context: context, builder: (context) {
return AlertDialog(
showDialog(context: context, builder: (context) => AlertDialog(
title: const Text('Download'),
content: Text(result.message),
);
});
));
}
setState(() {
@ -158,8 +153,7 @@ class _FileElementState extends State<FileElement> {
}
},
onLongPress: () {
showDialog(context: context, builder: (context) {
return SimpleDialog(
showDialog(context: context, builder: (context) => SimpleDialog(
children: [
ListTile(
leading: const Icon(Icons.delete_outline),
@ -189,9 +183,7 @@ class _FileElementState extends State<FileElement> {
),
),
],
);
});
));
},
);
}
}

View File

@ -32,18 +32,18 @@ class _FileUploadDialogState extends State<FileUploadDialog> {
TextEditingController fileNameController = TextEditingController();
void upload({bool override = false}) async {
Future<void> upload({bool override = false}) async {
setState(() {
state = FileUploadState.upload;
});
WebDavClient webdavClient = await WebdavApi.webdav;
var webdavClient = await WebdavApi.webdav;
if(!override) {
setState(() {
state = FileUploadState.checkConflict;
});
List<WebDavResponse> result = (await webdavClient.propfind(PathUri.parse(widget.remotePath.join('/')))).responses;
var result = (await webdavClient.propfind(PathUri.parse(widget.remotePath.join('/')))).responses;
if(result.any((element) => element.href!.endsWith('/$targetFileName'))) {
setState(() {
state = FileUploadState.conflict;
@ -56,7 +56,7 @@ class _FileUploadDialogState extends State<FileUploadDialog> {
}
}
Future<HttpClientResponse> uploadTask = webdavClient.putFile(File(widget.localPath), FileStat.statSync(widget.localPath), PathUri.parse(fullRemotePath)); // TODO use onProgress from putFile
var uploadTask = webdavClient.putFile(File(widget.localPath), FileStat.statSync(widget.localPath), PathUri.parse(fullRemotePath)); // TODO use onProgress from putFile
uploadTask.then(Future<HttpClientResponse?>.value).catchError((e) {
setState(() {
state = FileUploadState.error;
@ -230,4 +230,4 @@ enum FileUploadState {
upload,
done,
error
}
}

View File

@ -64,9 +64,7 @@ class SortOptions {
)
};
static BetterSortOption getOption(SortOption option) {
return options[option]!;
}
static BetterSortOption getOption(SortOption option) => options[option]!;
}
class _FilesState extends State<Files> {
@ -101,7 +99,7 @@ class _FilesState extends State<Files> {
@override
Widget build(BuildContext context) {
List<CacheableFile> files = data?.sortBy(
var files = data?.sortBy(
sortOption: currentSort,
foldersToTop: Provider.of<SettingsProvider>(context).val().fileSettings.sortFoldersToTop,
reversed: currentSortDirection
@ -119,8 +117,7 @@ class _FilesState extends State<Files> {
// ),
PopupMenuButton<bool>(
icon: Icon(currentSortDirection ? Icons.text_rotate_up : Icons.text_rotation_down),
itemBuilder: (context) {
return [true, false].map((e) => PopupMenuItem<bool>(
itemBuilder: (context) => [true, false].map((e) => PopupMenuItem<bool>(
value: e,
enabled: e != currentSortDirection,
child: Row(
@ -130,8 +127,7 @@ class _FilesState extends State<Files> {
Text(e ? 'Aufsteigend' : 'Absteigend')
],
)
)).toList();
},
)).toList(),
onSelected: (e) {
setState(() {
currentSortDirection = e;
@ -141,8 +137,7 @@ class _FilesState extends State<Files> {
),
PopupMenuButton<SortOption>(
icon: const Icon(Icons.sort),
itemBuilder: (context) {
return SortOptions.options.keys.map((key) => PopupMenuItem<SortOption>(
itemBuilder: (context) => SortOptions.options.keys.map((key) => PopupMenuItem<SortOption>(
value: key,
enabled: key != currentSort,
child: Row(
@ -152,8 +147,7 @@ class _FilesState extends State<Files> {
Text(SortOptions.getOption(key).displayName)
],
)
)).toList();
},
)).toList(),
onSelected: (e) {
setState(() {
currentSort = e;
@ -167,8 +161,7 @@ class _FilesState extends State<Files> {
heroTag: 'uploadFile',
backgroundColor: Theme.of(context).primaryColor,
onPressed: () {
showDialog(context: context, builder: (context) {
return SimpleDialog(
showDialog(context: context, builder: (context) => SimpleDialog(
children: [
ListTile(
leading: const Icon(Icons.create_new_folder_outlined),
@ -224,8 +217,7 @@ class _FilesState extends State<Files> {
),
),
],
);
});
));
},
child: const Icon(Icons.add),
),
@ -239,7 +231,7 @@ class _FilesState extends State<Files> {
padding: EdgeInsets.zero,
itemCount: files.length,
itemBuilder: (context, index) {
CacheableFile file = files.toList()[index];
var file = files.toList()[index];
return FileElement(file, widget.path, _query);
},
),
@ -248,7 +240,7 @@ class _FilesState extends State<Files> {
);
}
void mediaUpload(String? path) async {
Future<void> mediaUpload(String? path) async {
context.loaderOverlay.hide();
if(path == null) {

View File

@ -44,8 +44,7 @@ class _FeedbackDialogState extends State<FeedbackDialog> {
}
@override
Widget build(BuildContext context) {
return Scaffold(
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('Feedback'),
),
@ -125,7 +124,7 @@ class _FeedbackDialogState extends State<FeedbackDialog> {
onPressed: () async {
context.loaderOverlay.show();
var imageData = await (await FilePick.galleryPick())?.readAsBytes();
context.loaderOverlay.hide();
if(context.mounted) context.loaderOverlay.hide();
setState(() {
_image = imageData;
});
@ -170,6 +169,4 @@ class _FeedbackDialogState extends State<FeedbackDialog> {
],
),
);
}
}

View File

@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
import 'package:jiffy/jiffy.dart';
import 'package:provider/provider.dart';
import '../../../../api/holidays/getHolidaysResponse.dart';
import '../../../../model/holidays/holidaysProps.dart';
import '../../../../storage/base/settingsProvider.dart';
import '../../../../widget/centeredLeading.dart';
@ -22,9 +21,7 @@ class Holidays extends StatefulWidget {
}
extension StringExtension on String {
String capitalize() {
return "${this[0].toUpperCase()}${substring(1).toLowerCase()}";
}
String capitalize() => '${this[0].toUpperCase()}${substring(1).toLowerCase()}';
}
class _HolidaysState extends State<Holidays> {
@ -41,13 +38,10 @@ class _HolidaysState extends State<Holidays> {
super.initState();
}
String parseString(String enDate) {
return Jiffy.parse(enDate).format(pattern: 'dd.MM.yyyy');
}
String parseString(String enDate) => Jiffy.parse(enDate).format(pattern: 'dd.MM.yyyy');
void showDisclaimer() {
showDialog(context: context, builder: (context) {
return AlertDialog(
showDialog(context: context, builder: (context) => AlertDialog(
title: const Text('Richtigkeit und Bereitstellung der Daten'),
content: Column(
mainAxisSize: MainAxisSize.min,
@ -70,13 +64,11 @@ class _HolidaysState extends State<Holidays> {
TextButton(child: const Text('ferien-api.de besuchen'), onPressed: () => ConfirmDialog.openBrowser(context, 'https://ferien-api.de/')),
TextButton(child: const Text('Okay'), onPressed: () => Navigator.of(context).pop()),
],
);
});
));
}
@override
Widget build(BuildContext context) {
return Scaffold(
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('Schulferien in Hessen'),
actions: [
@ -87,8 +79,7 @@ class _HolidaysState extends State<Holidays> {
PopupMenuButton<bool>(
initialValue: settings.val().holidaysSettings.showPastEvents,
icon: const Icon(Icons.manage_history_outlined),
itemBuilder: (context) {
return [true, false].map((e) => PopupMenuItem<bool>(
itemBuilder: (context) => [true, false].map((e) => PopupMenuItem<bool>(
value: e,
enabled: e != showPastEvents,
child: Row(
@ -98,8 +89,7 @@ class _HolidaysState extends State<Holidays> {
Text(e ? 'Alle anzeigen' : 'Nur zukünftige anzeigen')
],
)
)).toList();
},
)).toList(),
onSelected: (e) {
setState(() {
showPastEvents = e;
@ -112,7 +102,7 @@ class _HolidaysState extends State<Holidays> {
body: Consumer<HolidaysProps>(builder: (context, value, child) {
if(value.primaryLoading()) return const LoadingSpinner();
List<GetHolidaysResponseObject> holidays = value.getHolidaysResponse.data;
var holidays = value.getHolidaysResponse.data;
if(!showPastEvents) holidays = holidays.where((element) => DateTime.parse(element.end).isAfter(DateTime.now())).toList();
if(holidays.isEmpty) return const PlaceholderView(icon: Icons.search_off, text: 'Es wurden keine Ferieneinträge gefunden!');
@ -120,8 +110,8 @@ class _HolidaysState extends State<Holidays> {
return ListView.builder(
itemCount: holidays.length,
itemBuilder: (context, index) {
GetHolidaysResponseObject holiday = holidays[index];
String holidayType = holiday.name.split(' ').first.capitalize();
var holiday = holidays[index];
var holidayType = holiday.name.split(' ').first.capitalize();
return ListTile(
leading: const CenteredLeading(Icon(Icons.calendar_month)),
title: Text('$holidayType ab ${parseString(holiday.start)}'),
@ -164,5 +154,4 @@ class _HolidaysState extends State<Holidays> {
},
)
);
}
}

View File

@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../../../api/mhsl/message/getMessages/getMessagesResponse.dart';
import '../../../../model/message/messageProps.dart';
import '../../../../widget/loadingSpinner.dart';
import 'messageView.dart';
@ -24,8 +23,7 @@ class _MessageState extends State<Message> {
}
@override
Widget build(BuildContext context) {
return Scaffold(
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('Marianum Message'),
),
@ -36,7 +34,7 @@ class _MessageState extends State<Message> {
child: ListView.builder(
itemCount: value.getMessagesResponse.messages.length,
itemBuilder: (context, index) {
GetMessagesResponseObject message = value.getMessagesResponse.messages.toList()[index];
var message = value.getMessagesResponse.messages.toList()[index];
return ListTile(
leading: const Column(
mainAxisAlignment: MainAxisAlignment.center,
@ -58,5 +56,4 @@ class _MessageState extends State<Message> {
);
}),
);
}
}

View File

@ -17,8 +17,7 @@ class MessageView extends StatefulWidget {
class _MessageViewState extends State<MessageView> {
@override
Widget build(BuildContext context) {
return Scaffold(
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text(widget.message.name),
),
@ -27,8 +26,7 @@ class _MessageViewState extends State<MessageView> {
enableHyperlinkNavigation: true,
onDocumentLoadFailed: (PdfDocumentLoadFailedDetails e) {
Navigator.of(context).pop();
showDialog(context: context, builder: (context) {
return AlertDialog(
showDialog(context: context, builder: (context) => AlertDialog(
title: const Text('Fehler beim öffnen'),
content: Text("Dokument '${widget.message.name}' konnte nicht geladen werden:\n${e.description}"),
actions: [
@ -36,8 +34,7 @@ class _MessageViewState extends State<MessageView> {
Navigator.of(context).pop();
}, child: const Text('Ok'))
],
);
});
));
},
onHyperlinkClicked: (PdfHyperlinkClickedDetails e) {
showDialog(
@ -52,5 +49,4 @@ class _MessageViewState extends State<MessageView> {
},
),
);
}
}

View File

@ -5,8 +5,7 @@ class Roomplan extends StatelessWidget {
const Roomplan({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('Raumplan'),
),
@ -17,5 +16,4 @@ class Roomplan extends StatelessWidget {
backgroundDecoration: BoxDecoration(color: Theme.of(context).colorScheme.background),
),
);
}
}

View File

@ -8,7 +8,7 @@ class AppSharePlatformView extends StatelessWidget {
@override
Widget build(BuildContext context) {
Color foregroundColor = Theme.of(context).colorScheme.onBackground;
var foregroundColor = Theme.of(context).colorScheme.onBackground;
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,

View File

@ -11,8 +11,7 @@ class QrShareView extends StatefulWidget {
class _QrShareViewState extends State<QrShareView> {
@override
Widget build(BuildContext context) {
return DefaultTabController(
Widget build(BuildContext context) => DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
@ -32,5 +31,4 @@ class _QrShareViewState extends State<QrShareView> {
),
),
);
}
}

View File

@ -8,8 +8,7 @@ class SelectShareTypeDialog extends StatelessWidget {
const SelectShareTypeDialog({super.key});
@override
Widget build(BuildContext context) {
return SimpleDialog(
Widget build(BuildContext context) => SimpleDialog(
children: [
ListTile(
leading: const Icon(Icons.qr_code_2_outlined),
@ -36,5 +35,4 @@ class SelectShareTypeDialog extends StatelessWidget {
)
],
);
}
}

View File

@ -21,9 +21,7 @@ class Overhang extends StatelessWidget {
const Overhang({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('Mehr'),
actions: [
@ -79,5 +77,4 @@ class Overhang extends StatelessWidget {
],
),
);
}
}

View File

@ -35,7 +35,7 @@ class _ChatInfoState extends State<ChatInfo> {
@override
Widget build(BuildContext context) {
bool isGroup = widget.room.type != GetRoomResponseObjectConversationType.oneToOne;
var isGroup = widget.room.type != GetRoomResponseObjectConversationType.oneToOne;
return Scaffold(
appBar: AppBar(
title: Text(widget.room.displayName),

View File

@ -13,20 +13,16 @@ class ParticipantsListView extends StatefulWidget {
class _ParticipantsListViewState extends State<ParticipantsListView> {
@override
Widget build(BuildContext context) {
return Scaffold(
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('Teilnehmende'),
),
body: ListView(
children: widget.participantsResponse.data.map((participant) {
return ListTile(
children: widget.participantsResponse.data.map((participant) => ListTile(
leading: UserAvatar(id: participant.actorId),
title: Text(participant.displayName),
subtitle: participant.statusMessage != null ? Text(participant.statusMessage!) : null,
);
}).toList(),
)).toList(),
),
);
}
}

View File

@ -119,14 +119,14 @@ class _ChatListState extends State<ChatList> {
if(data.primaryLoading()) return const LoadingSpinner();
latestData = data;
List<ChatTile> chats = [];
var chats = <ChatTile>[];
for (var chatRoom in data.getRoomsResponse.sortBy(
lastActivity: true,
favoritesToTop: Provider.of<SettingsProvider>(context).val().talkSettings.sortFavoritesToTop,
unreadToTop: Provider.of<SettingsProvider>(context).val().talkSettings.sortUnreadToTop,
)
) {
bool hasDraft = settings.val().talkSettings.drafts.containsKey(chatRoom.token);
var hasDraft = settings.val().talkSettings.drafts.containsKey(chatRoom.token);
chats.add(ChatTile(data: chatRoom, query: _query, hasDraft: hasDraft));
}
@ -146,4 +146,4 @@ class _ChatListState extends State<ChatList> {
),
);
}
}
}

View File

@ -40,19 +40,18 @@ class _ChatViewState extends State<ChatView> {
}
@override
Widget build(BuildContext context) {
return Consumer<ChatProps>(
Widget build(BuildContext context) => Consumer<ChatProps>(
builder: (context, data, child) {
List<Widget> messages = List<Widget>.empty(growable: true);
var messages = List<Widget>.empty(growable: true);
if(!data.primaryLoading()) {
DateTime lastDate = DateTime.now();
var lastDate = DateTime.now();
data.getChatResponse.sortByTimestamp().forEach((element) {
DateTime elementDate = DateTime.fromMillisecondsSinceEpoch(element.timestamp * 1000);
var elementDate = DateTime.fromMillisecondsSinceEpoch(element.timestamp * 1000);
if(element.systemMessage.contains('reaction')) return;
int commonRead = int.parse(data.getChatResponse.headers?['x-chat-last-common-read'] ?? '0');
var commonRead = int.parse(data.getChatResponse.headers?['x-chat-last-common-read'] ?? '0');
if(!elementDate.isSameDay(lastDate)) {
lastDate = elementDate;
@ -140,5 +139,4 @@ class _ChatViewState extends State<ChatView> {
);
},
);
}
}

View File

@ -51,15 +51,13 @@ class ChatBubble extends StatefulWidget {
class _ChatBubbleState extends State<ChatBubble> {
BubbleStyle getSystemStyle() {
return BubbleStyle(
BubbleStyle getSystemStyle() => BubbleStyle(
color: AppTheme.isDarkMode(context) ? const Color(0xff182229) : Colors.white,
borderWidth: 1,
elevation: 2,
margin: const BubbleEdges.only(bottom: 20, top: 10),
alignment: Alignment.center,
);
}
BubbleStyle getRemoteStyle(bool seamless) {
var color = AppTheme.isDarkMode(context) ? const Color(0xff202c33) : Colors.white;
@ -105,17 +103,17 @@ class _ChatBubbleState extends State<ChatBubble> {
@override
Widget build(BuildContext context) {
message = ChatMessage(originalMessage: widget.bubbleData.message, originalData: widget.bubbleData.messageParameters);
bool showActorDisplayName = widget.bubbleData.messageType == GetRoomResponseObjectMessageType.comment && widget.chatData.type != GetRoomResponseObjectConversationType.oneToOne;
bool showBubbleTime = widget.bubbleData.messageType != GetRoomResponseObjectMessageType.system;
var showActorDisplayName = widget.bubbleData.messageType == GetRoomResponseObjectMessageType.comment && widget.chatData.type != GetRoomResponseObjectConversationType.oneToOne;
var showBubbleTime = widget.bubbleData.messageType != GetRoomResponseObjectMessageType.system;
Text actorText = Text(
var actorText = Text(
widget.bubbleData.actorDisplayName,
textAlign: TextAlign.start,
overflow: TextOverflow.ellipsis,
style: TextStyle(color: Theme.of(context).primaryColor, fontWeight: FontWeight.bold),
);
Text timeText = Text(
var timeText = Text(
Jiffy.parseFromMillisecondsSinceEpoch(widget.bubbleData.timestamp * 1000).format(pattern: 'HH:mm'),
textAlign: TextAlign.end,
style: TextStyle(color: widget.timeIconColor, fontSize: widget.timeIconSize),
@ -186,8 +184,8 @@ class _ChatBubbleState extends State<ChatBubble> {
),
onLongPress: () {
showDialog(context: context, builder: (context) {
List<String> commonReactions = ['👍', '👎', '😆', '❤️', '👀'];
bool canReact = widget.bubbleData.messageType == GetRoomResponseObjectMessageType.comment;
var commonReactions = <String>['👍', '👎', '😆', '❤️', '👀'];
var canReact = widget.bubbleData.messageType == GetRoomResponseObjectMessageType.comment;
return SimpleDialog(
children: [
Visibility(
@ -217,8 +215,7 @@ class _ChatBubbleState extends State<ChatBubble> {
),
IconButton(
onPressed: () {
showDialog(context: context, builder: (context) {
return AlertDialog(
showDialog(context: context, builder: (context) => AlertDialog(
contentPadding: const EdgeInsets.all(15),
titlePadding: const EdgeInsets.only(left: 6, top: 15),
title: Row(
@ -278,8 +275,7 @@ class _ChatBubbleState extends State<ChatBubble> {
],
),
),
);
});
));
},
style: IconButton.styleFrom(
padding: EdgeInsets.zero,
@ -350,8 +346,7 @@ class _ChatBubbleState extends State<ChatBubble> {
if(message.file == null) return;
if(downloadProgress > 0) {
showDialog(context: context, builder: (context) {
return AlertDialog(
showDialog(context: context, builder: (context) => AlertDialog(
title: const Text('Download abbrechen?'),
content: const Text('Möchtest du den Download abbrechen?'),
actions: [
@ -369,8 +364,7 @@ class _ChatBubbleState extends State<ChatBubble> {
});
}, child: const Text('Ja, Abbrechen'))
],
);
});
));
return;
}
@ -388,11 +382,9 @@ class _ChatBubbleState extends State<ChatBubble> {
});
if(result.type != ResultType.done) {
showDialog(context: context, builder: (context) {
return AlertDialog(
showDialog(context: context, builder: (context) => AlertDialog(
content: Text(result.message),
);
});
));
}
});
},
@ -408,7 +400,7 @@ class _ChatBubbleState extends State<ChatBubble> {
alignment: widget.isSender ? WrapAlignment.end : WrapAlignment.start,
crossAxisAlignment: WrapCrossAlignment.start,
children: widget.bubbleData.reactions?.entries.map<Widget>((e) {
bool hasSelfReacted = widget.bubbleData.reactionsSelf?.contains(e.key) ?? false;
var hasSelfReacted = widget.bubbleData.reactionsSelf?.contains(e.key) ?? false;
return Container(
margin: const EdgeInsets.only(right: 2.5, left: 2.5),
child: ActionChip(

View File

@ -37,8 +37,7 @@ class ChatMessage {
}
return CachedNetworkImage(
errorWidget: (context, url, error) {
return Padding(padding: const EdgeInsets.only(top: 10), child: Row(
errorWidget: (context, url, error) => Padding(padding: const EdgeInsets.only(top: 10), child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
@ -47,12 +46,9 @@ class ChatMessage {
Flexible(child: Text(file!.name, maxLines: 2, overflow: TextOverflow.ellipsis, style: const TextStyle(fontWeight: FontWeight.bold))),
const SizedBox(width: 10),
],
));
},
)),
alignment: Alignment.center,
placeholder: (context, url) {
return const Padding(padding: EdgeInsets.all(10), child: CircularProgressIndicator());
},
placeholder: (context, url) => const Padding(padding: EdgeInsets.all(10), child: CircularProgressIndicator()),
fadeInDuration: Duration.zero,
fadeOutDuration: Duration.zero,
errorListener: (value) {},
@ -60,9 +56,9 @@ class ChatMessage {
);
}
void onOpen(LinkableElement link) async {
Future<void> onOpen(LinkableElement link) async {
if(await canLaunchUrlString(link.url)) {
await launchUrlString(link.url);
}
}
}
}

View File

@ -34,15 +34,15 @@ class _ChatTextfieldState extends State<ChatTextfield> {
Provider.of<ChatProps>(context, listen: false).run();
}
void mediaUpload(String? path) async {
Future<void> mediaUpload(String? path) async {
context.loaderOverlay.hide();
if(path == null) {
return;
}
String filename = "${path.split("/").last.split(".").first}-${const Uuid().v4()}.${path.split(".").last}";
String shareFolder = 'MarianumMobile';
var filename = "${path.split("/").last.split(".").first}-${const Uuid().v4()}.${path.split(".").last}";
var shareFolder = 'MarianumMobile';
WebdavApi.webdav.then((webdav) {
webdav.mkcol(PathUri.parse('/$shareFolder'));
});
@ -91,8 +91,7 @@ class _ChatTextfieldState extends State<ChatTextfield> {
children: <Widget>[
GestureDetector(
onTap: (){
showDialog(context: context, builder: (context) {
return SimpleDialog(
showDialog(context: context, builder: (context) => SimpleDialog(
children: [
ListTile(
leading: const Icon(Icons.file_open),
@ -118,8 +117,7 @@ class _ChatTextfieldState extends State<ChatTextfield> {
),
),
],
);
});
));
},
child: Material(
elevation: 5,

View File

@ -40,7 +40,7 @@ class _ChatTileState extends State<ChatTile> {
username = value.getString('username')!
});
bool isGroup = widget.data.type != GetRoomResponseObjectConversationType.oneToOne;
var isGroup = widget.data.type != GetRoomResponseObjectConversationType.oneToOne;
circleAvatar = UserAvatar(id: isGroup ? widget.data.token : widget.data.name, isGroup: isGroup);
}
@ -56,10 +56,7 @@ class _ChatTileState extends State<ChatTile> {
@override
Widget build(BuildContext context) {
return Consumer<ChatProps>(builder: (context, chatData, child) {
return ListTile(
Widget build(BuildContext context) => Consumer<ChatProps>(builder: (context, chatData, child) => ListTile(
style: ListTileStyle.list,
tileColor: chatData.currentToken() == widget.data.token && TalkNavigator.isSecondaryVisible(context)
? Theme.of(context).primaryColor.withAlpha(100)
@ -120,7 +117,7 @@ class _ChatTileState extends State<ChatTile> {
),
onTap: () async {
setCurrentAsRead();
ChatView view = ChatView(room: widget.data, selfId: username, avatar: circleAvatar);
var view = ChatView(room: widget.data, selfId: username, avatar: circleAvatar);
TalkNavigator.pushSplitView(context, view, overrideToSingleSubScreen: true);
Provider.of<ChatProps>(context, listen: false).setQueryToken(widget.data.token);
},
@ -185,7 +182,5 @@ class _ChatTileState extends State<ChatTile> {
],
));
},
);
});
}
));
}

View File

@ -6,8 +6,7 @@ class SplitViewPlaceholder extends StatelessWidget {
const SplitViewPlaceholder({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
@ -25,5 +24,4 @@ class SplitViewPlaceholder extends StatelessWidget {
),
)
);
}
}

View File

@ -11,8 +11,7 @@ class JoinChat extends SearchDelegate<String> {
CancelableOperation<AutocompleteResponse>? future;
@override
List<Widget>? buildActions(BuildContext context) {
return [
List<Widget>? buildActions(BuildContext context) => [
if(future != null && query.isNotEmpty) FutureBuilder(
future: future!.value,
builder: (context, snapshot) {
@ -35,12 +34,9 @@ class JoinChat extends SearchDelegate<String> {
),
if(query.isNotEmpty) IconButton(onPressed: () => query = '', icon: const Icon(Icons.delete)),
];
}
@override
Widget? buildLeading(BuildContext context) {
return null;
}
Widget? buildLeading(BuildContext context) => null;
@override
Widget buildResults(BuildContext context) {
@ -61,8 +57,8 @@ class JoinChat extends SearchDelegate<String> {
return ListView.builder(
itemCount: snapshot.data!.data.length,
itemBuilder: (context, index) {
AutocompleteResponseObject object = snapshot.data!.data[index];
CircleAvatar circleAvatar = CircleAvatar(
var object = snapshot.data!.data[index];
var circleAvatar = CircleAvatar(
foregroundImage: Image.network('https://${EndpointData().nextcloud().full()}/avatar/${object.id}/128').image,
backgroundColor: Theme.of(context).primaryColor,
foregroundColor: Colors.white,
@ -89,8 +85,6 @@ class JoinChat extends SearchDelegate<String> {
}
@override
Widget buildSuggestions(BuildContext context) {
return buildResults(context);
}
Widget buildSuggestions(BuildContext context) => buildResults(context);
}
}

View File

@ -30,8 +30,7 @@ class _MessageReactionsState extends State<MessageReactions> {
}
@override
Widget build(BuildContext context) {
return Scaffold(
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('Reaktionen'),
),
@ -42,8 +41,7 @@ class _MessageReactionsState extends State<MessageReactions> {
if(snapshot.data == null) return const PlaceholderView(icon: Icons.search_off_outlined, text: 'Keine Reaktionen gefunden!');
return ListView(
children: [
...snapshot.data!.data.entries.map<Widget>((entry) {
return ExpansionTile(
...snapshot.data!.data.entries.map<Widget>((entry) => ExpansionTile(
textColor: Theme.of(context).colorScheme.onSurface,
collapsedTextColor: Theme.of(context).colorScheme.onSurface,
iconColor: Theme.of(context).colorScheme.onSurface,
@ -53,7 +51,7 @@ class _MessageReactionsState extends State<MessageReactions> {
leading: CenteredLeading(Text(entry.key)),
title: Text('${entry.value.length} mal reagiert'),
children: entry.value.map((e) {
bool isSelf = AccountData().getUsername() == e.actorId;
var isSelf = AccountData().getUsername() == e.actorId;
return ListTile(
leading: UserAvatar(id: e.actorId, isGroup: false),
title: Text(e.actorDisplayName),
@ -71,12 +69,10 @@ class _MessageReactionsState extends State<MessageReactions> {
),
);
}).toList(),
);
})
))
],
);
},
),
);
}
}

View File

@ -9,16 +9,12 @@ class SearchChat extends SearchDelegate {
SearchChat(this.chats);
@override
List<Widget>? buildActions(BuildContext context) {
return [
List<Widget>? buildActions(BuildContext context) => [
if(query.isNotEmpty) IconButton(onPressed: () => query = '', icon: const Icon(Icons.delete)),
];
}
@override
Widget? buildLeading(BuildContext context) {
return null;
}
Widget? buildLeading(BuildContext context) => null;
@override
Widget buildResults(BuildContext context) {
@ -35,7 +31,5 @@ class SearchChat extends SearchDelegate {
}
@override
Widget buildSuggestions(BuildContext context) {
return buildResults(context);
}
}
Widget buildSuggestions(BuildContext context) => buildResults(context);
}

View File

@ -9,10 +9,10 @@ class TalkNavigator {
static void pushSplitView(BuildContext context, Widget view, {bool overrideToSingleSubScreen = false}) {
if(isSecondaryVisible(context)) {
SplitViewState splitView = SplitView.of(context);
var splitView = SplitView.of(context);
overrideToSingleSubScreen ? splitView.setSecondary(view) : splitView.push(view);
} else {
pushScreen(context, screen: view, withNavBar: false);
}
}
}
}

View File

@ -13,4 +13,4 @@ class CrossPainter extends CustomPainter {
@override
bool shouldRepaint(CrossPainter oldDelegate) => false;
}
}

View File

@ -33,7 +33,7 @@ class AppointmentDetails {
}
static void show(BuildContext context, TimetableProps webuntisData, Appointment appointment) {
(appointment.id as ArbitraryAppointment).handlers(
(appointment.id! as ArbitraryAppointment).handlers(
(webuntis) => _webuntis(context, webuntisData, appointment, webuntis),
(customData) => _custom(context, webuntisData, customData)
);
@ -76,21 +76,18 @@ class AppointmentDetails {
_bottomSheet(
context,
(context) {
return Center(
(context) => Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text("${_getEventPrefix(timetableData.code)}${subject.alternateName}", textAlign: TextAlign.center, style: const TextStyle(fontSize: 25), overflow: TextOverflow.ellipsis),
Text('${_getEventPrefix(timetableData.code)}${subject.alternateName}', textAlign: TextAlign.center, style: const TextStyle(fontSize: 25), overflow: TextOverflow.ellipsis),
Text(subject.longName),
Text("${Jiffy.parseFromDateTime(appointment.startTime).format(pattern: "HH:mm")} - ${Jiffy.parseFromDateTime(appointment.endTime).format(pattern: "HH:mm")}", style: const TextStyle(fontSize: 15)),
],
),
);
},
),
(context) {
return SliverChildListDelegate(
(context) => SliverChildListDelegate(
[
const Divider(),
ListTile(
@ -132,13 +129,12 @@ class AppointmentDetails {
),
DebugTile(context).jsonData(timetableData.toJson()),
],
);
}
)
);
}
static Completer deleteCustomEvent(BuildContext context, CustomTimetableEvent appointment) {
Completer future = Completer();
var future = Completer();
ConfirmDialog(
title: 'Termin löschen',
content: "Der ${appointment.rrule.isEmpty ? "Termin" : "Serientermin"} wird unwiederruflich gelöscht.",
@ -160,8 +156,7 @@ class AppointmentDetails {
static void _custom(BuildContext context, TimetableProps webuntisData, CustomTimetableEvent appointment) {
_bottomSheet(
context,
(context) {
return Center(
(context) => Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
@ -169,10 +164,8 @@ class AppointmentDetails {
Text("${Jiffy.parseFromDateTime(appointment.startDate).format(pattern: "HH:mm")} - ${Jiffy.parseFromDateTime(appointment.endDate).format(pattern: "HH:mm")}", style: const TextStyle(fontSize: 15)),
],
),
);
},
(context) {
return SliverChildListDelegate(
),
(context) => SliverChildListDelegate(
[
const Divider(),
Center(
@ -212,7 +205,7 @@ class AppointmentDetails {
builder: (context, snapshot) {
if(appointment.rrule.isEmpty) return const Text('Keine weiteren vorkomnisse');
if(snapshot.data == null) return const Text('...');
RecurrenceRule rrule = RecurrenceRule.fromString(appointment.rrule);
var rrule = RecurrenceRule.fromString(appointment.rrule);
if(!rrule.canFullyConvertToText) return const Text('Keine genauere Angabe möglich.');
return Text(rrule.toText(l10n: snapshot.data!));
},
@ -227,8 +220,7 @@ class AppointmentDetails {
),
DebugTile(context).jsonData(appointment.toJson()),
]
);
}
)
);
}
}
}

View File

@ -8,16 +8,12 @@ class ArbitraryAppointment {
ArbitraryAppointment({this.webuntis, this.custom});
bool hasWebuntis() {
return webuntis != null;
}
bool hasWebuntis() => webuntis != null;
bool hasCustom() {
return custom != null;
}
bool hasCustom() => custom != null;
void handlers(void Function(GetTimetableResponseObject webuntisData) webuntis, void Function(CustomTimetableEvent customData) custom) {
if(hasWebuntis()) webuntis(this.webuntis!);
if(hasCustom()) custom(this.custom!);
}
}
}

View File

@ -29,9 +29,7 @@ class TimetableColors {
}
}
static Color getColorFromString(String color) {
return getDisplayOptions(CustomTimetableColors.values.firstWhere((element) => element.name == color, orElse: () => TimetableColors.defaultColor)).color;
}
static Color getColorFromString(String color) => getDisplayOptions(CustomTimetableColors.values.firstWhere((element) => element.name == color, orElse: () => TimetableColors.defaultColor)).color;
}
class ColorModeDisplay {
@ -39,4 +37,4 @@ class ColorModeDisplay {
final String displayName;
ColorModeDisplay({required this.color, required this.displayName});
}
}

View File

@ -51,8 +51,7 @@ class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEdit
}
@override
Widget build(BuildContext context) {
return AlertDialog(
Widget build(BuildContext context) => AlertDialog(
insetPadding: const EdgeInsets.all(20),
contentPadding: const EdgeInsets.all(10),
title: const Text('Termin hinzufügen'),
@ -89,7 +88,7 @@ class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEdit
title: Text(Jiffy.parseFromDateTime(_date).yMMMd),
subtitle: const Text('Datum'),
onTap: () async {
final DateTime? pickedDate = await showDatePicker(
final pickedDate = await showDatePicker(
context: context,
initialDate: _date,
firstDate: DateTime.now().subtract(const Duration(days: 30)),
@ -185,7 +184,7 @@ class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEdit
onPressed: () {
if(!validate()) return;
CustomTimetableEvent editedEvent = CustomTimetableEvent(
var editedEvent = CustomTimetableEvent(
id: '',
title: _eventName.text,
description: _eventDescription.text,
@ -231,5 +230,4 @@ class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEdit
),
],
);
}
}

View File

@ -12,8 +12,8 @@ class TimeRegionComponent extends StatefulWidget {
class _TimeRegionComponentState extends State<TimeRegionComponent> {
@override
Widget build(BuildContext context) {
String text = widget.details.region.text!;
Color? color = widget.details.region.color;
var text = widget.details.region.text!;
var color = widget.details.region.color;
if (text == 'centerIcon') {
return Container(

View File

@ -7,8 +7,6 @@ import 'package:provider/provider.dart';
import 'package:syncfusion_flutter_calendar/calendar.dart';
import '../../../api/webuntis/queries/getHolidays/getHolidaysResponse.dart';
import '../../../api/webuntis/queries/getRooms/getRoomsResponse.dart';
import '../../../api/webuntis/queries/getSubjects/getSubjectsResponse.dart';
import '../../../api/webuntis/queries/getTimetable/getTimetableResponse.dart';
import '../../../model/timetable/timetableProps.dart';
import '../../../storage/base/settingsProvider.dart';
@ -53,9 +51,7 @@ class _TimetableState extends State<Timetable> {
}
@override
Widget build(BuildContext context) {
return Scaffold(
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('Stunden & Vertretungsplan'),
actions: [
@ -67,8 +63,7 @@ class _TimetableState extends State<Timetable> {
),
PopupMenuButton<CalendarActions>(
icon: const Icon(Icons.edit_calendar_outlined),
itemBuilder: (context) {
return CalendarActions.values.map(
itemBuilder: (context) => CalendarActions.values.map(
(e) {
String title;
Icon icon;
@ -89,8 +84,7 @@ class _TimetableState extends State<Timetable> {
)
);
}
).toList();
},
).toList(),
onSelected: (value) {
switch(value) {
case CalendarActions.addEvent:
@ -125,7 +119,7 @@ class _TimetableState extends State<Timetable> {
if(value.primaryLoading()) return const LoadingSpinner();
GetHolidaysResponse holidays = value.getHolidaysResponse;
var holidays = value.getHolidaysResponse;
return RefreshIndicator(
child: SfCalendar(
@ -181,7 +175,6 @@ class _TimetableState extends State<Timetable> {
},
),
);
}
@override
void dispose() {
@ -190,19 +183,18 @@ class _TimetableState extends State<Timetable> {
}
List<TimeRegion> _buildSpecialTimeRegions(GetHolidaysResponse holidays) {
DateTime lastMonday = DateTime.now().subtract(const Duration(days: 14)).nextWeekday(DateTime.monday);
DateTime firstBreak = lastMonday.copyWith(hour: 10, minute: 15);
DateTime secondBreak = lastMonday.copyWith(hour: 13, minute: 50);
var lastMonday = DateTime.now().subtract(const Duration(days: 14)).nextWeekday(DateTime.monday);
var firstBreak = lastMonday.copyWith(hour: 10, minute: 15);
var secondBreak = lastMonday.copyWith(hour: 13, minute: 50);
Iterable<TimeRegion> holidayList = holidays.result.map((holiday) {
DateTime startDay = _parseWebuntisTimestamp(holiday.startDate, 0);
int dayCount = _parseWebuntisTimestamp(holiday.endDate, 0)
var holidayList = holidays.result.map((holiday) {
var startDay = _parseWebuntisTimestamp(holiday.startDate, 0);
var dayCount = _parseWebuntisTimestamp(holiday.endDate, 0)
.difference(startDay)
.inDays;
List<DateTime> days = List.generate(dayCount, (index) => startDay.add(Duration(days: index)));
var days = List<DateTime>.generate(dayCount, (index) => startDay.add(Duration(days: index)));
return days.map((holidayDay) {
return TimeRegion(
return days.map((holidayDay) => TimeRegion(
startTime: holidayDay.copyWith(hour: 07, minute: 55),
endTime: holidayDay.copyWith(hour: 16, minute: 30),
text: 'holiday:${holiday.name}',
@ -211,13 +203,10 @@ class _TimetableState extends State<Timetable> {
.disabledColor
.withAlpha(50),
iconData: Icons.holiday_village_outlined
);
});
));
}).expand((e) => e);
bool isInHoliday(DateTime time) {
return holidayList.any((element) => element.startTime.isSameDay(time));
}
bool isInHoliday(DateTime time) => holidayList.any((element) => element.startTime.isSameDay(time));
return [
...holidayList,
@ -246,34 +235,34 @@ class _TimetableState extends State<Timetable> {
List<GetTimetableResponseObject> _removeDuplicates(TimetableProps data, Duration maxTimeBetweenDouble) {
List<GetTimetableResponseObject> timetableList = data.getTimetableResponse.result.toList();
var timetableList = data.getTimetableResponse.result.toList();
if(timetableList.isEmpty) return timetableList;
timetableList.sort((a, b) => _parseWebuntisTimestamp(a.date, a.startTime).compareTo(_parseWebuntisTimestamp(b.date, b.startTime)));
GetTimetableResponseObject previousElement = timetableList.first;
var previousElement = timetableList.first;
for(var i = 1; i < timetableList.length; i++) {
GetTimetableResponseObject currentElement = timetableList.elementAt(i);
var currentElement = timetableList.elementAt(i);
bool isSameLesson() {
int? currentSubjectId = currentElement.su.firstOrNull?.id;
int? previousSubjectId = previousElement.su.firstOrNull?.id;
var currentSubjectId = currentElement.su.firstOrNull?.id;
var previousSubjectId = previousElement.su.firstOrNull?.id;
if(currentSubjectId == null || previousSubjectId == null || currentSubjectId != previousSubjectId) return false;
int? currentRoomId = currentElement.ro.firstOrNull?.id;
int? previousRoomId = previousElement.ro.firstOrNull?.id;
var currentRoomId = currentElement.ro.firstOrNull?.id;
var previousRoomId = previousElement.ro.firstOrNull?.id;
if(currentRoomId != previousRoomId) return false;
int? currentTeacherId = currentElement.te.firstOrNull?.id;
int? previousTeacherId = previousElement.te.firstOrNull?.id;
var currentTeacherId = currentElement.te.firstOrNull?.id;
var previousTeacherId = previousElement.te.firstOrNull?.id;
if(currentTeacherId != previousTeacherId) return false;
String? currentStatusCode = currentElement.code;
String? previousStatusCode = previousElement.code;
var currentStatusCode = currentElement.code;
var previousStatusCode = previousElement.code;
if(currentStatusCode != previousStatusCode) return false;
@ -297,20 +286,20 @@ class _TimetableState extends State<Timetable> {
TimetableEvents _buildTableEvents(TimetableProps data) {
List<GetTimetableResponseObject> timetableList = data.getTimetableResponse.result.toList();
var timetableList = data.getTimetableResponse.result.toList();
if(settings.val().timetableSettings.connectDoubleLessons) {
timetableList = _removeDuplicates(data, const Duration(minutes: 5));
}
List<Appointment> appointments = timetableList.map((element) {
var appointments = timetableList.map((element) {
GetRoomsResponse rooms = data.getRoomsResponse;
GetSubjectsResponse subjects = data.getSubjectsResponse;
var rooms = data.getRoomsResponse;
var subjects = data.getSubjectsResponse;
try {
DateTime startTime = _parseWebuntisTimestamp(element.date, element.startTime);
DateTime endTime = _parseWebuntisTimestamp(element.date, element.endTime);
var startTime = _parseWebuntisTimestamp(element.date, element.startTime);
var endTime = _parseWebuntisTimestamp(element.date, element.endTime);
return Appointment(
id: ArbitraryAppointment(webuntis: element),
startTime: startTime,
@ -324,7 +313,7 @@ class _TimetableState extends State<Timetable> {
color: _getEventColor(element, startTime, endTime),
);
} catch(e) {
DateTime endTime = _parseWebuntisTimestamp(element.date, element.endTime);
var endTime = _parseWebuntisTimestamp(element.date, element.endTime);
return Appointment(
id: ArbitraryAppointment(webuntis: element),
startTime: _parseWebuntisTimestamp(element.date, element.startTime),
@ -339,8 +328,7 @@ class _TimetableState extends State<Timetable> {
}
}).toList();
appointments.addAll(data.getCustomTimetableEventResponse.events.map((customEvent) {
return Appointment(
appointments.addAll(data.getCustomTimetableEventResponse.events.map((customEvent) => Appointment(
id: ArbitraryAppointment(custom: customEvent),
startTime: customEvent.startDate,
endTime: customEvent.endDate,
@ -350,20 +338,19 @@ class _TimetableState extends State<Timetable> {
color: TimetableColors.getColorFromString(customEvent.color ?? TimetableColors.defaultColor.name),
startTimeZone: '',
endTimeZone: '',
);
}));
)));
return TimetableEvents(appointments);
}
DateTime _parseWebuntisTimestamp(int date, int time) {
String timeString = time.toString().padLeft(4, '0');
var timeString = time.toString().padLeft(4, '0');
return DateTime.parse('$date ${timeString.substring(0, 2)}:${timeString.substring(2, 4)}');
}
Color _getEventColor(GetTimetableResponseObject webuntisElement, DateTime startTime, DateTime endTime) {
// Make element darker, when it already took place
int alpha = endTime.isBefore(DateTime.now()) ? 100 : 255;
var alpha = endTime.isBefore(DateTime.now()) ? 100 : 255;
// Cancelled
if(webuntisElement.code == 'cancelled') return const Color(0xff000000).withAlpha(alpha);
@ -382,7 +369,7 @@ class _TimetableState extends State<Timetable> {
}
bool _isCrossedOut(CalendarAppointmentDetails calendarEntry) {
ArbitraryAppointment appointment = calendarEntry.appointments.first.id as ArbitraryAppointment;
var appointment = calendarEntry.appointments.first.id as ArbitraryAppointment;
if(appointment.hasWebuntis()) {
return appointment.webuntis!.code == 'cancelled';
}

View File

@ -5,4 +5,4 @@ class TimetableEvents extends CalendarDataSource {
TimetableEvents(List<Appointment> source) {
appointments = source;
}
}
}

View File

@ -34,8 +34,7 @@ class _ViewCustomTimetableEventsState extends State<ViewCustomTimetableEvents> {
}
@override
Widget build(BuildContext context) {
return Scaffold(
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('Eigene Termine'),
actions: [
@ -49,8 +48,7 @@ class _ViewCustomTimetableEventsState extends State<ViewCustomTimetableEvents> {
if(value.primaryLoading()) return const LoadingSpinner();
var listView = ListView(
children: value.getCustomTimetableEventResponse.events.map((e) {
return ListTile(
children: value.getCustomTimetableEventResponse.events.map((e) => ListTile(
title: Text(e.title),
subtitle: Text("${e.rrule.isNotEmpty ? "wiederholdend, " : ""}beginnend ${Jiffy.parseFromDateTime(e.startDate).fromNow()}"),
leading: CenteredLeading(Icon(e.rrule.isEmpty ? Icons.event_outlined : Icons.event_repeat_outlined)),
@ -71,8 +69,7 @@ class _ViewCustomTimetableEventsState extends State<ViewCustomTimetableEvents> {
)
],
),
);
}).toList(),
)).toList(),
);
var placeholder = PlaceholderView(
@ -95,5 +92,4 @@ class _ViewCustomTimetableEventsState extends State<ViewCustomTimetableEvents> {
);
}),
);
}
}

View File

@ -14,8 +14,7 @@ import '../../storage/timetable/timetableSettings.dart';
import '../pages/files/files.dart';
class DefaultSettings {
static Settings get() {
return Settings(
static Settings get() => Settings(
appTheme: ThemeMode.system,
devToolsEnabled: false,
gradeAveragesSettings: GradeAveragesSettings(
@ -53,5 +52,4 @@ class DefaultSettings {
showPerformanceOverlay: false,
),
);
}
}
}

View File

@ -19,8 +19,7 @@ class DevToolsSettingsDialog extends StatefulWidget {
class _DevToolsSettingsDialogState extends State<DevToolsSettingsDialog> {
@override
Widget build(BuildContext context) {
return Column(
Widget build(BuildContext context) => Column(
children: [
ListTile(
leading: const CenteredLeading(Icon(Icons.speed_outlined)),
@ -95,14 +94,10 @@ class _DevToolsSettingsDialogState extends State<DevToolsSettingsDialog> {
title: const Text('Cache-storage JSON dump'),
subtitle: FutureBuilder(
future: const CacheView().totalSize(),
builder: (context, snapshot) {
return Text("etwa ${snapshot.hasError ? "?" : snapshot.hasData ? filesize(snapshot.data) : "..."}\nLange tippen um zu löschen");
},
builder: (context, snapshot) => Text("etwa ${snapshot.hasError ? "?" : snapshot.hasData ? filesize(snapshot.data) : "..."}\nLange tippen um zu löschen"),
),
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return const CacheView();
}));
Navigator.push(context, MaterialPageRoute(builder: (context) => const CacheView()));
},
onLongPress: () {
ConfirmDialog(
@ -116,5 +111,4 @@ class _DevToolsSettingsDialogState extends State<DevToolsSettingsDialog> {
),
],
);
}
}

View File

@ -11,8 +11,7 @@ class PrivacyInfo {
PrivacyInfo({required this.providerText, required this.imprintUrl, required this.privacyUrl});
void showPopup(BuildContext context) {
showDialog(context: context, builder: (context) {
return SimpleDialog(
showDialog(context: context, builder: (context) => SimpleDialog(
title: Text('Betreiberinformation | $providerText'),
children: [
ListTile(
@ -28,7 +27,6 @@ class PrivacyInfo {
onTap: () => ConfirmDialog.openBrowser(context, privacyUrl),
),
],
);
});
));
}
}
}

View File

@ -36,10 +36,7 @@ class _SettingsState extends State<Settings> {
bool developerMode = false;
@override
Widget build(BuildContext context) {
return Consumer<SettingsProvider>(builder: (context, settings, child) {
return Scaffold(
Widget build(BuildContext context) => Consumer<SettingsProvider>(builder: (context, settings, child) => Scaffold(
appBar: AppBar(
title: const Text('Einstellungen'),
),
@ -218,8 +215,7 @@ class _SettingsState extends State<Settings> {
leading: const Icon(Icons.policy_outlined),
title: const Text('Impressum & Datenschutz'),
onTap: () {
showDialog(context: context, builder: (context) {
return SimpleDialog(
showDialog(context: context, builder: (context) => SimpleDialog(
children: [
ListTile(
leading: const CenteredLeading(Icon(Icons.school_outlined)),
@ -243,8 +239,7 @@ class _SettingsState extends State<Settings> {
onTap: () => PrivacyInfo(providerText: 'mhsl', imprintUrl: 'https://mhsl.eu/id.html', privacyUrl: 'https://mhsl.eu/datenschutz.html').showPopup(context),
),
],
);
});
));
},
trailing: const Icon(Icons.arrow_right),
),
@ -297,7 +292,5 @@ class _SettingsState extends State<Settings> {
),
],
),
);
});
}
));
}