Initial commit
This commit is contained in:
		
							
								
								
									
										111
									
								
								lib/app.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								lib/app.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:marianum_mobile/data/incommingPackets/talkNotificationsPacket.dart';
 | 
			
		||||
import 'package:provider/provider.dart';
 | 
			
		||||
import 'package:shared_preferences/shared_preferences.dart';
 | 
			
		||||
 | 
			
		||||
import 'data/accountModel.dart';
 | 
			
		||||
import 'screen/pages/files/files.dart';
 | 
			
		||||
import 'screen/pages/more/overhang.dart';
 | 
			
		||||
import 'screen/pages/talk/chatOverview.dart';
 | 
			
		||||
import 'screen/pages/timetable/timetable.dart';
 | 
			
		||||
import 'screen/settings/settings.dart';
 | 
			
		||||
 | 
			
		||||
class App extends StatefulWidget {
 | 
			
		||||
  const App({Key? key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<App> createState() => _AppState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _AppState extends State<App> {
 | 
			
		||||
  int currentPage = 0;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    final PageController pageController = PageController();
 | 
			
		||||
    return Scaffold(
 | 
			
		||||
      appBar: AppBar(
 | 
			
		||||
        title: const Text("Marianum Fulda"),
 | 
			
		||||
        actions: <Widget>[
 | 
			
		||||
          IconButton(
 | 
			
		||||
            padding: const EdgeInsets.only(right: 15),
 | 
			
		||||
            icon: const Icon(Icons.settings),
 | 
			
		||||
            onPressed: () {
 | 
			
		||||
              Navigator.push(context, MaterialPageRoute(builder: (context) => const Settings()));
 | 
			
		||||
            },
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
      ),
 | 
			
		||||
      body: PageView(
 | 
			
		||||
        controller: pageController,
 | 
			
		||||
        children: const [
 | 
			
		||||
          Timetable(),
 | 
			
		||||
          Talk(),
 | 
			
		||||
          Files(),
 | 
			
		||||
          Overhang(),
 | 
			
		||||
        ],
 | 
			
		||||
        onPageChanged: (page) {
 | 
			
		||||
          setState(() {
 | 
			
		||||
            currentPage = page;
 | 
			
		||||
          });
 | 
			
		||||
        },
 | 
			
		||||
      ),
 | 
			
		||||
 | 
			
		||||
      bottomNavigationBar: BottomNavigationBar(
 | 
			
		||||
        items: [
 | 
			
		||||
          const BottomNavigationBarItem(icon: Icon(Icons.calendar_month), label: "Vertretung"),
 | 
			
		||||
          BottomNavigationBarItem(icon: Stack(
 | 
			
		||||
            children: [
 | 
			
		||||
              const Icon(Icons.chat),
 | 
			
		||||
 | 
			
		||||
              Consumer<TalkNotificationsPacket>(
 | 
			
		||||
                builder: (context, data, child) {
 | 
			
		||||
                  return Visibility(
 | 
			
		||||
                    visible: data.amount != 0,
 | 
			
		||||
                    child: Positioned(
 | 
			
		||||
                      right: 0,
 | 
			
		||||
                      child: Container(
 | 
			
		||||
                        padding: const EdgeInsets.all(1),
 | 
			
		||||
                        decoration: BoxDecoration(
 | 
			
		||||
                          color: Colors.red,
 | 
			
		||||
                          borderRadius: BorderRadius.circular(6),
 | 
			
		||||
                        ),
 | 
			
		||||
                        constraints: const BoxConstraints(
 | 
			
		||||
                          minWidth: 12,
 | 
			
		||||
                          minHeight: 12,
 | 
			
		||||
                        ),
 | 
			
		||||
                        child: Text(
 | 
			
		||||
                          "${data.amount}",
 | 
			
		||||
                          style: const TextStyle(
 | 
			
		||||
                            color: Colors.black,
 | 
			
		||||
                            fontSize: 10,
 | 
			
		||||
                          ),
 | 
			
		||||
                          textAlign: TextAlign.center,
 | 
			
		||||
                        ),
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                  );
 | 
			
		||||
                },
 | 
			
		||||
              )
 | 
			
		||||
            ],
 | 
			
		||||
          ), label: "Talk"),
 | 
			
		||||
          const BottomNavigationBarItem(icon: Icon(Icons.folder), label: "Dateien"),
 | 
			
		||||
          const BottomNavigationBarItem(icon: Icon(Icons.list), label: "Mehr"),
 | 
			
		||||
        ],
 | 
			
		||||
        selectedItemColor: Theme.of(context).primaryColor,
 | 
			
		||||
        unselectedItemColor: Colors.grey,
 | 
			
		||||
        showUnselectedLabels: true,
 | 
			
		||||
        showSelectedLabels: true,
 | 
			
		||||
 | 
			
		||||
        currentIndex: currentPage,
 | 
			
		||||
        onTap: (item) {
 | 
			
		||||
          setState(() {
 | 
			
		||||
            currentPage = item;
 | 
			
		||||
            pageController.jumpToPage(item);
 | 
			
		||||
          });
 | 
			
		||||
        },
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								lib/data/accountModel.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								lib/data/accountModel.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
import 'package:flutter/cupertino.dart';
 | 
			
		||||
import 'package:shared_preferences/shared_preferences.dart';
 | 
			
		||||
import 'package:web_socket_channel/web_socket_channel.dart';
 | 
			
		||||
 | 
			
		||||
class AccountModel extends ChangeNotifier {
 | 
			
		||||
  bool _isLoggedIn = false;
 | 
			
		||||
 | 
			
		||||
  bool get isLoggedIn => _isLoggedIn;
 | 
			
		||||
 | 
			
		||||
  void logout() {
 | 
			
		||||
    _isLoggedIn = false;
 | 
			
		||||
    notifyListeners();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void login() {
 | 
			
		||||
    _isLoggedIn = true;
 | 
			
		||||
    notifyListeners();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								lib/data/incomingPacket.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								lib/data/incomingPacket.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
import 'dart:async';
 | 
			
		||||
import 'dart:convert';
 | 
			
		||||
import 'dart:developer';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/cupertino.dart';
 | 
			
		||||
import 'package:marianum_mobile/data/socketConnection.dart';
 | 
			
		||||
 | 
			
		||||
class IncomingPacket extends ChangeNotifier {
 | 
			
		||||
 | 
			
		||||
  String packetId;
 | 
			
		||||
 | 
			
		||||
  bool _isReceived = false;
 | 
			
		||||
  bool get isReceived => _isReceived;
 | 
			
		||||
  
 | 
			
		||||
  IncomingPacket(this.packetId) {
 | 
			
		||||
    log("PACKETLISTENER ERSTELLT!");
 | 
			
		||||
    SocketConnection.read.listen((event) {
 | 
			
		||||
      if(event.startsWith("$packetId:")) {
 | 
			
		||||
        _isReceived = true;
 | 
			
		||||
 | 
			
		||||
        // THIS listener handles the incomming request
 | 
			
		||||
        log("$packetId is handled!");
 | 
			
		||||
        handle(jsonDecode(event.split("$packetId:")[1]));
 | 
			
		||||
      }
 | 
			
		||||
      notifyListeners();
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void invoke({Object? data, bool indicateLoading = false, bool allowNotifyListeners = true}) {
 | 
			
		||||
    data = data ?? {};
 | 
			
		||||
    log("$packetId is invoked with data: $data");
 | 
			
		||||
    SocketConnection.write.add("$packetId:${jsonEncode(data)}");
 | 
			
		||||
 | 
			
		||||
    if(indicateLoading) {
 | 
			
		||||
      _isReceived = false;
 | 
			
		||||
      if(allowNotifyListeners) notifyListeners();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void handle(dynamic data) {
 | 
			
		||||
    log("Warning: $packetId packet listener is registered, but no handle is defined!");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								lib/data/incommingPackets/authenticatePacket.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								lib/data/incommingPackets/authenticatePacket.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
 | 
			
		||||
import 'dart:developer';
 | 
			
		||||
 | 
			
		||||
import 'package:marianum_mobile/data/incomingPacket.dart';
 | 
			
		||||
import 'package:shared_preferences/shared_preferences.dart';
 | 
			
		||||
 | 
			
		||||
class AuthenticatePacket extends IncomingPacket {
 | 
			
		||||
  AuthenticatePacket() : super("authenticate");
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void handle(data) {
 | 
			
		||||
    SharedPreferences.getInstance().then((value) => {
 | 
			
		||||
      invoke(data: {
 | 
			
		||||
        'username': value.getString("username"),
 | 
			
		||||
        'password': value.getString("password")
 | 
			
		||||
      })
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								lib/data/incommingPackets/fileListPacket.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								lib/data/incommingPackets/fileListPacket.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
 | 
			
		||||
import 'package:marianum_mobile/data/incomingPacket.dart';
 | 
			
		||||
 | 
			
		||||
class FileEntry {
 | 
			
		||||
  String name;
 | 
			
		||||
  bool isFolder;
 | 
			
		||||
  String path;
 | 
			
		||||
 | 
			
		||||
  FileEntry(this.name, this.isFolder, this.path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class FileListPacket extends IncomingPacket {
 | 
			
		||||
  FileListPacket() : super("fileList");
 | 
			
		||||
 | 
			
		||||
  List<FileEntry> _entries = List<FileEntry>.empty(growable: true);
 | 
			
		||||
  List<FileEntry> get entries => _entries;
 | 
			
		||||
 | 
			
		||||
  String _lastPath = "/";
 | 
			
		||||
  String get lastPath => _lastPath;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void handle(data) {
 | 
			
		||||
    _entries = List<FileEntry>.empty(growable: true);
 | 
			
		||||
    _lastPath = data['backLink'];
 | 
			
		||||
    data['files'].forEach((value) => {
 | 
			
		||||
      _entries.add(FileEntry(value['name'], value['is_folder'], value['path']))
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								lib/data/incommingPackets/serverInfoPacket.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								lib/data/incommingPackets/serverInfoPacket.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
import 'dart:convert';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/cupertino.dart';
 | 
			
		||||
import 'package:marianum_mobile/data/socketConnection.dart';
 | 
			
		||||
 | 
			
		||||
import '../incomingPacket.dart';
 | 
			
		||||
 | 
			
		||||
class ServerInfoPacket extends IncomingPacket {
 | 
			
		||||
  ServerInfoPacket() : super('serverInfo');
 | 
			
		||||
 | 
			
		||||
  String _serverName = "Unbekannt";
 | 
			
		||||
  String _serverOwner = "Unbekannt";
 | 
			
		||||
  String _serverVersion = "?";
 | 
			
		||||
  String _legal = "Keine";
 | 
			
		||||
 | 
			
		||||
  String get serverName => _serverName;
 | 
			
		||||
  String get serverOwner => _serverOwner;
 | 
			
		||||
  String get serverVersion => _serverVersion;
 | 
			
		||||
  String get legal => _legal;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void handle(data) {
 | 
			
		||||
    _serverName = data['name'];
 | 
			
		||||
    _serverOwner = data['owner'];
 | 
			
		||||
    _serverVersion = data['version'];
 | 
			
		||||
    _legal = data['legal'];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								lib/data/incommingPackets/talkChatPacket.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								lib/data/incommingPackets/talkChatPacket.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
import 'package:marianum_mobile/data/incomingPacket.dart';
 | 
			
		||||
 | 
			
		||||
class TalkMessage {
 | 
			
		||||
  bool self;
 | 
			
		||||
  String sender;
 | 
			
		||||
  String content;
 | 
			
		||||
  String date;
 | 
			
		||||
 | 
			
		||||
  TalkMessage(this.self, this.sender, this.content, this.date);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class TalkChatPacket extends IncomingPacket {
 | 
			
		||||
  TalkChatPacket() : super("talkChat");
 | 
			
		||||
 | 
			
		||||
  List<TalkMessage> _messages = List<TalkMessage>.empty(growable: true);
 | 
			
		||||
  List<TalkMessage> get messages => _messages;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void handle(data) {
 | 
			
		||||
    _messages = List<TalkMessage>.empty(growable: true);
 | 
			
		||||
    print(data);
 | 
			
		||||
    data.forEach((message) => {
 | 
			
		||||
      _messages.add(TalkMessage(true, message['actorId'], message['message'], message['timestamp']))
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								lib/data/incommingPackets/talkContactsPacket.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								lib/data/incommingPackets/talkContactsPacket.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
import 'dart:convert';
 | 
			
		||||
 | 
			
		||||
import 'package:intl/intl.dart';
 | 
			
		||||
import 'package:jiffy/jiffy.dart';
 | 
			
		||||
import 'package:marianum_mobile/data/incomingPacket.dart';
 | 
			
		||||
 | 
			
		||||
class TalkContact {
 | 
			
		||||
  String name;
 | 
			
		||||
  String lastMessage;
 | 
			
		||||
  String lastTime;
 | 
			
		||||
  String profilePicture;
 | 
			
		||||
  bool unreadMessages;
 | 
			
		||||
  bool isGroup;
 | 
			
		||||
  String userToken;
 | 
			
		||||
 | 
			
		||||
  TalkContact(this.name, this.lastMessage, this.lastTime, this.profilePicture, this.unreadMessages, this.isGroup, this.userToken);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class TalkContactsPaket extends IncomingPacket {
 | 
			
		||||
  TalkContactsPaket() : super('talkContacts');
 | 
			
		||||
 | 
			
		||||
  List<TalkContact> _contacts = List<TalkContact>.empty(growable: true);
 | 
			
		||||
 | 
			
		||||
  List<TalkContact> get contacts => _contacts;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void handle(data) {
 | 
			
		||||
    _contacts = List<TalkContact>.empty(growable: true);
 | 
			
		||||
    //data["ocs"]["data"].sort((a, b) => a['lastActivity'].compareTo(b['lastActivity']));
 | 
			
		||||
 | 
			
		||||
    data.forEach((value) async {
 | 
			
		||||
      await Jiffy.locale("de");
 | 
			
		||||
      _contacts.add(
 | 
			
		||||
          TalkContact(
 | 
			
		||||
              value['displayName'],
 | 
			
		||||
              value['lastMessage']['message'],
 | 
			
		||||
              Jiffy(DateTime.fromMillisecondsSinceEpoch(value['lastActivity'] * 1000)).fromNow(),
 | 
			
		||||
              value['name'] != null ? "https://cloud.marianum-fulda.de/avatar/${value['name']}/128" : "",
 | 
			
		||||
              value['unreadMessages'] > 0,
 | 
			
		||||
              value['type'] != 1,
 | 
			
		||||
              value['token']
 | 
			
		||||
          )
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								lib/data/incommingPackets/talkNotificationsPacket.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								lib/data/incommingPackets/talkNotificationsPacket.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
import 'package:marianum_mobile/data/incomingPacket.dart';
 | 
			
		||||
 | 
			
		||||
class TalkNotificationsPacket extends IncomingPacket {
 | 
			
		||||
  TalkNotificationsPacket() : super("talkNotifications");
 | 
			
		||||
 | 
			
		||||
  int _amount = 0;
 | 
			
		||||
  int get amount => _amount;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void handle(data) {
 | 
			
		||||
    _amount = data['amount'];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								lib/data/outgoingPacket.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								lib/data/outgoingPacket.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
import 'dart:convert';
 | 
			
		||||
 | 
			
		||||
import 'package:marianum_mobile/data/socketConnection.dart';
 | 
			
		||||
 | 
			
		||||
class OutgoingPacket {
 | 
			
		||||
  final String command;
 | 
			
		||||
  final dynamic data;
 | 
			
		||||
 | 
			
		||||
  OutgoingPacket({required this.command, required this.data});
 | 
			
		||||
 | 
			
		||||
  void send() {
 | 
			
		||||
    SocketConnection.write.add("$command:${jsonEncode(data)}");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								lib/data/outgoingPackets/talkContactsAskPacket.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								lib/data/outgoingPackets/talkContactsAskPacket.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
import 'package:marianum_mobile/data/outgoingPacket.dart';
 | 
			
		||||
 | 
			
		||||
class TalkContactsAskPacket extends OutgoingPacket {
 | 
			
		||||
  TalkContactsAskPacket() : super(
 | 
			
		||||
    command: "talkContacts",
 | 
			
		||||
    data: {},
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								lib/data/socketConnection.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								lib/data/socketConnection.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
import 'package:web_socket_channel/web_socket_channel.dart';
 | 
			
		||||
 | 
			
		||||
class SocketConnection {
 | 
			
		||||
  static final _connection = WebSocketChannel.connect(
 | 
			
		||||
    Uri.parse('ws://localhost:1234'),
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  static var read = _connection.stream.asBroadcastStream();
 | 
			
		||||
  static var write = _connection.sink;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										109
									
								
								lib/main.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								lib/main.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
			
		||||
import 'dart:io';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter/services.dart';
 | 
			
		||||
import 'package:marianum_mobile/data/accountModel.dart';
 | 
			
		||||
import 'package:marianum_mobile/data/incommingPackets/authenticatePacket.dart';
 | 
			
		||||
import 'package:marianum_mobile/data/incommingPackets/fileListPacket.dart';
 | 
			
		||||
import 'package:marianum_mobile/data/incommingPackets/talkChatPacket.dart';
 | 
			
		||||
import 'package:marianum_mobile/data/incommingPackets/talkNotificationsPacket.dart';
 | 
			
		||||
import 'package:marianum_mobile/screen/login/login.dart';
 | 
			
		||||
import 'package:marianum_mobile/screen/pages/timetable/timetable.dart';
 | 
			
		||||
import 'package:marianum_mobile/widget/loadingSpinner.dart';
 | 
			
		||||
import 'package:provider/provider.dart';
 | 
			
		||||
import 'package:shared_preferences/shared_preferences.dart';
 | 
			
		||||
import 'package:web_socket_channel/web_socket_channel.dart';
 | 
			
		||||
 | 
			
		||||
import 'app.dart';
 | 
			
		||||
import 'data/incommingPackets/serverInfoPacket.dart';
 | 
			
		||||
import 'data/incommingPackets/talkContactsPacket.dart';
 | 
			
		||||
 | 
			
		||||
Future<void> main() async {
 | 
			
		||||
  WidgetsFlutterBinding.ensureInitialized();
 | 
			
		||||
 | 
			
		||||
  ByteData data = await PlatformAssetBundle().load('assets/ca/lets-encrypt-r3.pem');
 | 
			
		||||
  SecurityContext.defaultContext.setTrustedCertificatesBytes(data.buffer.asUint8List());
 | 
			
		||||
 | 
			
		||||
  AuthenticatePacket();
 | 
			
		||||
 | 
			
		||||
  runApp(
 | 
			
		||||
      MultiProvider(
 | 
			
		||||
        providers: [
 | 
			
		||||
          ChangeNotifierProvider(create: (context) => AccountModel()),
 | 
			
		||||
          ChangeNotifierProvider(create: (context) => ServerInfoPacket()),
 | 
			
		||||
          ChangeNotifierProvider(create: (context) => TalkContactsPaket()),
 | 
			
		||||
          ChangeNotifierProvider(create: (context) => TalkNotificationsPacket()),
 | 
			
		||||
          ChangeNotifierProvider(create: (context) => FileListPacket()),
 | 
			
		||||
          ChangeNotifierProvider(create: (context) => TalkChatPacket()),
 | 
			
		||||
        ],
 | 
			
		||||
        child: const Main(),
 | 
			
		||||
      )
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Main extends StatefulWidget {
 | 
			
		||||
  const Main({Key? key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<Main> createState() => _MainState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _MainState extends State<Main> {
 | 
			
		||||
  static const Color red = Color.fromARGB(255, 153, 51, 51);
 | 
			
		||||
 | 
			
		||||
  final Future<SharedPreferences> _storage = SharedPreferences.getInstance();
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
    super.initState();
 | 
			
		||||
    _storage.then((SharedPreferences preferences) => preferences.getBool("loggedIn") ?? false).then((value) => {
 | 
			
		||||
      if(value) {
 | 
			
		||||
        Provider.of<AccountModel>(context, listen: false).login()
 | 
			
		||||
      } else {
 | 
			
		||||
        Provider.of<AccountModel>(context, listen: false).logout()
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return MaterialApp(
 | 
			
		||||
      debugShowCheckedModeBanner: false,
 | 
			
		||||
 | 
			
		||||
      title: 'Marianum Fulda',
 | 
			
		||||
      theme: ThemeData(
 | 
			
		||||
        brightness: Brightness.light,
 | 
			
		||||
        primaryColor: red,
 | 
			
		||||
        appBarTheme: const AppBarTheme(
 | 
			
		||||
          backgroundColor: red,
 | 
			
		||||
        ),
 | 
			
		||||
        progressIndicatorTheme: const ProgressIndicatorThemeData(
 | 
			
		||||
          color: red,
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
 | 
			
		||||
      home: FutureBuilder<SharedPreferences>(
 | 
			
		||||
        future: _storage,
 | 
			
		||||
        builder: (BuildContext context, AsyncSnapshot<SharedPreferences> snapshot) {
 | 
			
		||||
 | 
			
		||||
          if(snapshot.hasData) {
 | 
			
		||||
 | 
			
		||||
            return Consumer<AccountModel>(
 | 
			
		||||
              builder: (context, value, child) {
 | 
			
		||||
                return value.isLoggedIn ? const App() : const Login();
 | 
			
		||||
              },
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
          } else {
 | 
			
		||||
 | 
			
		||||
            return const LoadingSpinner();
 | 
			
		||||
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
        },
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										93
									
								
								lib/screen/login/login.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								lib/screen/login/login.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,93 @@
 | 
			
		||||
import 'dart:io';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_login/flutter_login.dart';
 | 
			
		||||
import 'package:provider/provider.dart';
 | 
			
		||||
import 'package:shared_preferences/shared_preferences.dart';
 | 
			
		||||
 | 
			
		||||
import '../../data/accountModel.dart';
 | 
			
		||||
 | 
			
		||||
class Login extends StatefulWidget {
 | 
			
		||||
  const Login({Key? key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<Login> createState() => _LoginState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _LoginState extends State<Login> {
 | 
			
		||||
  Duration get loginTime => const Duration(milliseconds: 2250);
 | 
			
		||||
 | 
			
		||||
  final Future<SharedPreferences> _storage = SharedPreferences.getInstance();
 | 
			
		||||
 | 
			
		||||
  String? checkInput(value){
 | 
			
		||||
    return (value ?? "").length < 5 ? "Eingabe zu kurz" : null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return FlutterLogin(
 | 
			
		||||
      logo: Image.file(File("assets/logo/icon.png")).image,
 | 
			
		||||
 | 
			
		||||
      userValidator: checkInput,
 | 
			
		||||
      passwordValidator: checkInput,
 | 
			
		||||
 | 
			
		||||
      onLogin: _authUser,
 | 
			
		||||
      onSignup: null,
 | 
			
		||||
      onRecoverPassword: _recoverPassword,
 | 
			
		||||
 | 
			
		||||
      theme: LoginTheme(
 | 
			
		||||
        primaryColor: Theme.of(context).primaryColor,
 | 
			
		||||
        cardTheme: const CardTheme(
 | 
			
		||||
          elevation: 10,
 | 
			
		||||
          shape: InputBorder.none,
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
 | 
			
		||||
      messages: LoginMessages(
 | 
			
		||||
        loginButton: "Anmelden",
 | 
			
		||||
        userHint: "Nutzername",
 | 
			
		||||
        passwordHint: "Passwort",
 | 
			
		||||
      ),
 | 
			
		||||
 | 
			
		||||
      disableCustomPageTransformer: true,
 | 
			
		||||
 | 
			
		||||
      headerWidget: const Padding(
 | 
			
		||||
        padding: EdgeInsets.only(bottom: 10),
 | 
			
		||||
        child: Center(
 | 
			
		||||
          child: Text(
 | 
			
		||||
            "Dies ist ein Inoffizieller Nextclient & Webuntis Client und wird nicht vom Marianum selbst betrieben.\nBitte bedenke, dass deine persönlichen Anmelde & Infodaten durch dritte, nicht vom Marianum betriebene, Systeme geleitet werden!",
 | 
			
		||||
            textAlign: TextAlign.center,
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
 | 
			
		||||
      footer: "Marianum Fulda - Die persönliche Schule!",
 | 
			
		||||
      title: "Marianum",
 | 
			
		||||
 | 
			
		||||
      hideForgotPasswordButton: true,
 | 
			
		||||
      userType: LoginUserType.name,
 | 
			
		||||
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<String?> _authUser(LoginData data) async {
 | 
			
		||||
    final SharedPreferences preferences = await _storage;
 | 
			
		||||
    preferences.setBool("loggedIn", true);
 | 
			
		||||
    preferences.setString("username", data.name);
 | 
			
		||||
    preferences.setString("password", data.password);
 | 
			
		||||
 | 
			
		||||
    debugPrint('Name: ${data.name}, Password: ${data.password}');
 | 
			
		||||
    return Future.delayed(loginTime).then((_) {
 | 
			
		||||
      Provider.of<AccountModel>(context, listen: false).login();
 | 
			
		||||
      return null;
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<String> _recoverPassword(String name) {
 | 
			
		||||
    return Future.delayed(loginTime).then((_) {
 | 
			
		||||
      return "Diese Funktion steht nicht zur Verfügung!";
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										271
									
								
								lib/screen/pages/files/files.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										271
									
								
								lib/screen/pages/files/files.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,271 @@
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:marianum_mobile/data/incommingPackets/fileListPacket.dart';
 | 
			
		||||
import 'package:marianum_mobile/widget/loadingPacket.dart';
 | 
			
		||||
import 'package:provider/provider.dart';
 | 
			
		||||
import 'package:webdav_client/webdav_client.dart';
 | 
			
		||||
 | 
			
		||||
import '../../../data/accountModel.dart';
 | 
			
		||||
import '../../../widget/loadingSpinner.dart';
 | 
			
		||||
 | 
			
		||||
class Files extends StatefulWidget {
 | 
			
		||||
  const Files({Key? key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<Files> createState() => _FilesState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _FilesState extends State<Files> {
 | 
			
		||||
  // List<String> path = List<String>.empty(growable: true);
 | 
			
		||||
  // List<File> files = List<File>.empty(growable: true);
 | 
			
		||||
  //
 | 
			
		||||
  // var client = newClient(
 | 
			
		||||
  //   "https://cloud.marianum-fulda.de/remote.php/dav/files/***REMOVED***/",
 | 
			
		||||
  //   user: "***REMOVED***",
 | 
			
		||||
  //   password: "***REMOVED***",
 | 
			
		||||
  // );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
    Provider.of<FileListPacket>(context, listen: false).invoke();
 | 
			
		||||
    super.initState();
 | 
			
		||||
 | 
			
		||||
    // client.setHeaders(
 | 
			
		||||
    //     {
 | 
			
		||||
    //       "Authorization": "Bearer",
 | 
			
		||||
    //       "User-Agent": "Marianum Fulda/Alpha0.1 (Development build) ; https://mhsl.eu/id.html",
 | 
			
		||||
    //     }
 | 
			
		||||
    // );
 | 
			
		||||
    //
 | 
			
		||||
    // path.add("/");
 | 
			
		||||
    // Future.delayed(Duration.zero).then((context) => updatePath());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // void homeFolder() {
 | 
			
		||||
  //   path.clear();
 | 
			
		||||
  //   path.add("/");
 | 
			
		||||
  //   updatePath();
 | 
			
		||||
  // }
 | 
			
		||||
  //
 | 
			
		||||
  // void popFolder() {
 | 
			
		||||
  //   if(path.length == 1) return;
 | 
			
		||||
  //   path.removeLast();
 | 
			
		||||
  //   updatePath();
 | 
			
		||||
  // }
 | 
			
		||||
  //
 | 
			
		||||
  // void enterFolder(String sub) {
 | 
			
		||||
  //   path.add(sub);
 | 
			
		||||
  //   updatePath();
 | 
			
		||||
  // }
 | 
			
		||||
  //
 | 
			
		||||
  // void updatePath() {
 | 
			
		||||
  //
 | 
			
		||||
  //   final files = client.readDir(path.join("/"));
 | 
			
		||||
  //
 | 
			
		||||
  //   showDialog(
 | 
			
		||||
  //       context: context,
 | 
			
		||||
  //       barrierDismissible: false,
 | 
			
		||||
  //       builder: (BuildContext context) {
 | 
			
		||||
  //         return const LoadingSpinner();
 | 
			
		||||
  //       }
 | 
			
		||||
  //   );
 | 
			
		||||
  //
 | 
			
		||||
  //   files.then((value) =>
 | 
			
		||||
  //       setState(() {
 | 
			
		||||
  //         Navigator.pop(context);
 | 
			
		||||
  //         this.files.clear();
 | 
			
		||||
  //         this.files = value;
 | 
			
		||||
  //       })
 | 
			
		||||
  //   );
 | 
			
		||||
  // }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    // List<Widget> items = List<Widget>.empty(growable: true);
 | 
			
		||||
    //
 | 
			
		||||
    // var counter = 0;
 | 
			
		||||
    // for (final file in files) {
 | 
			
		||||
    //   bool isDir = file.isDir ?? false;
 | 
			
		||||
    //   String name = file.name ?? "?";
 | 
			
		||||
    //
 | 
			
		||||
    //   items.add(ListTile(
 | 
			
		||||
    //     title: Text(file.name ?? "?"),
 | 
			
		||||
    //     leading: Icon(isDir ? Icons.folder_outlined : Icons.file_copy),
 | 
			
		||||
    //     trailing: Icon(isDir ? Icons.arrow_right : null),
 | 
			
		||||
    //     onTap: () {
 | 
			
		||||
    //       enterFolder(file.name ?? "");
 | 
			
		||||
    //     },
 | 
			
		||||
    //     onLongPress: () {
 | 
			
		||||
    //       setState(() {
 | 
			
		||||
    //         items[counter] = ListTile(
 | 
			
		||||
    //           title: Text(file.name ?? "?"),
 | 
			
		||||
    //           trailing: const Icon(Icons.delete),
 | 
			
		||||
    //         );
 | 
			
		||||
    //       });
 | 
			
		||||
    //     },
 | 
			
		||||
    //   ));
 | 
			
		||||
    //
 | 
			
		||||
    // }
 | 
			
		||||
    //
 | 
			
		||||
    // items.insert(0, AppBar(
 | 
			
		||||
    //   leading: path.length == 1 ? null : IconButton(
 | 
			
		||||
    //     icon: const Icon(Icons.keyboard_arrow_left),
 | 
			
		||||
    //     onPressed: () {
 | 
			
		||||
    //       popFolder();
 | 
			
		||||
    //     },
 | 
			
		||||
    //   ),
 | 
			
		||||
    //   actions: [
 | 
			
		||||
    //     IconButton(
 | 
			
		||||
    //       icon: const Icon(Icons.home),
 | 
			
		||||
    //       onPressed: () {
 | 
			
		||||
    //         homeFolder();
 | 
			
		||||
    //       },
 | 
			
		||||
    //     ),
 | 
			
		||||
    //
 | 
			
		||||
    //     IconButton(
 | 
			
		||||
    //       icon: const Icon(Icons.refresh),
 | 
			
		||||
    //       onPressed: () {
 | 
			
		||||
    //         updatePath();
 | 
			
		||||
    //       },
 | 
			
		||||
    //     )
 | 
			
		||||
    //   ],
 | 
			
		||||
    //
 | 
			
		||||
    //   title: Text(path.length == 1 ? "Dateien" : path.last),
 | 
			
		||||
    // ));
 | 
			
		||||
    //
 | 
			
		||||
    // return ListView(
 | 
			
		||||
    //   children: items,
 | 
			
		||||
    // );
 | 
			
		||||
 | 
			
		||||
    return Consumer<FileListPacket>(
 | 
			
		||||
      builder: (context, data, child) {
 | 
			
		||||
        List<ListTile> entries = List<ListTile>.empty(growable: true);
 | 
			
		||||
 | 
			
		||||
        data.entries.forEach((element) {
 | 
			
		||||
          entries.add(ListTile(
 | 
			
		||||
            title: Text(element.name),
 | 
			
		||||
            leading: Icon(element.isFolder ? Icons.folder : Icons.file_copy_outlined),
 | 
			
		||||
            onTap: () {
 | 
			
		||||
              if(element.isFolder) {
 | 
			
		||||
                Provider.of<FileListPacket>(context, listen: false).invoke(
 | 
			
		||||
                    data: {
 | 
			
		||||
                      "path": element.path
 | 
			
		||||
                    },
 | 
			
		||||
                    indicateLoading: true,
 | 
			
		||||
                );
 | 
			
		||||
              } else {
 | 
			
		||||
                // TODO: Open an File
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            
 | 
			
		||||
            onLongPress: () {
 | 
			
		||||
              showModalBottomSheet<void>(
 | 
			
		||||
                context: context,
 | 
			
		||||
                builder: (context) {
 | 
			
		||||
                  return ListView(
 | 
			
		||||
                    children: [
 | 
			
		||||
                      ListTile(
 | 
			
		||||
                        leading: Icon(Icons.delete),
 | 
			
		||||
                        title: Text("'${element.name.replaceRange(20, element.name.length, " ...")}' Löschen"),
 | 
			
		||||
                      ),
 | 
			
		||||
                      const ListTile(
 | 
			
		||||
                        leading: Icon(Icons.share),
 | 
			
		||||
                        title: Text("Teilen"),
 | 
			
		||||
                      )
 | 
			
		||||
                    ],
 | 
			
		||||
                  );
 | 
			
		||||
                },
 | 
			
		||||
              );
 | 
			
		||||
            },
 | 
			
		||||
          ));
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return Scaffold(
 | 
			
		||||
          appBar: AppBar(
 | 
			
		||||
            leading: IconButton(
 | 
			
		||||
              icon: const Icon(Icons.arrow_back_outlined),
 | 
			
		||||
              onPressed: () {
 | 
			
		||||
                Provider.of<FileListPacket>(context, listen: false).invoke(
 | 
			
		||||
                  data: {
 | 
			
		||||
                    "path": data.lastPath
 | 
			
		||||
                  },
 | 
			
		||||
                  indicateLoading: true,
 | 
			
		||||
                );
 | 
			
		||||
              }
 | 
			
		||||
            ),
 | 
			
		||||
 | 
			
		||||
            title: Text(data.lastPath),
 | 
			
		||||
            actions: [
 | 
			
		||||
              IconButton(
 | 
			
		||||
                onPressed: () {
 | 
			
		||||
                  Provider.of<FileListPacket>(context, listen: false).invoke(indicateLoading: true);
 | 
			
		||||
                },
 | 
			
		||||
                icon: const Icon(Icons.home)
 | 
			
		||||
              ),
 | 
			
		||||
              PopupMenuButton(
 | 
			
		||||
                icon: Icon(Icons.add),
 | 
			
		||||
                itemBuilder: (context) {
 | 
			
		||||
                  return [
 | 
			
		||||
                    const PopupMenuItem<int>(
 | 
			
		||||
                      value: 0,
 | 
			
		||||
                      child: ListTile(
 | 
			
		||||
                        leading: Icon(Icons.folder),
 | 
			
		||||
                        title: Text("Ordner erstellen"),
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                    const PopupMenuItem<int>(
 | 
			
		||||
                      value: 1,
 | 
			
		||||
                      child: ListTile(
 | 
			
		||||
                        leading: Icon(Icons.upload),
 | 
			
		||||
                        title: Text("Datei Hochladen"),
 | 
			
		||||
                      ),
 | 
			
		||||
                    )
 | 
			
		||||
                  ];
 | 
			
		||||
                },
 | 
			
		||||
              )
 | 
			
		||||
            ],
 | 
			
		||||
          ),
 | 
			
		||||
 | 
			
		||||
          floatingActionButton: FloatingActionButton.small(
 | 
			
		||||
            onPressed: () {
 | 
			
		||||
              showModalBottomSheet(
 | 
			
		||||
                isScrollControlled: true,
 | 
			
		||||
                context: context,
 | 
			
		||||
                backgroundColor: Colors.transparent,
 | 
			
		||||
                builder: (context) {
 | 
			
		||||
                  return Container(
 | 
			
		||||
                    height: MediaQuery.of(context).size.height * 0.3,
 | 
			
		||||
                    decoration: const BoxDecoration(
 | 
			
		||||
                      color: Colors.white,
 | 
			
		||||
                      borderRadius: BorderRadius.only(
 | 
			
		||||
                        topLeft: Radius.circular(25.0),
 | 
			
		||||
                        topRight: Radius.circular(25.0),
 | 
			
		||||
                      )
 | 
			
		||||
                    ),
 | 
			
		||||
                    child: ListView(
 | 
			
		||||
                      children: const [
 | 
			
		||||
                        ListTile(
 | 
			
		||||
                          leading: Icon(Icons.create_new_folder_sharp),
 | 
			
		||||
                          title: Text("Neuer Ordner"),
 | 
			
		||||
                        ),
 | 
			
		||||
                        ListTile(
 | 
			
		||||
                          leading: Icon(Icons.upload),
 | 
			
		||||
                          title: Text("Hochladen"),
 | 
			
		||||
                        )
 | 
			
		||||
                      ],
 | 
			
		||||
                    ),
 | 
			
		||||
                  );
 | 
			
		||||
                },
 | 
			
		||||
              );
 | 
			
		||||
            },
 | 
			
		||||
            backgroundColor: Theme.of(context).primaryColor,
 | 
			
		||||
            child: const Icon(Icons.add),
 | 
			
		||||
          ),
 | 
			
		||||
 | 
			
		||||
          body: LoadingPacket(packet: data, child: ListView(children: entries)),
 | 
			
		||||
        );
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								lib/screen/pages/more/message/message.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								lib/screen/pages/more/message/message.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
import 'package:flutter/cupertino.dart';
 | 
			
		||||
 | 
			
		||||
class Message extends StatefulWidget {
 | 
			
		||||
  const Message({Key? key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<Message> createState() => _MessageState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _MessageState extends State<Message> {
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return const Text("Message");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								lib/screen/pages/more/overhang.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								lib/screen/pages/more/overhang.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:marianum_mobile/screen/pages/more/roomplan/roomplan.dart';
 | 
			
		||||
 | 
			
		||||
import '../../../widget/ListItem.dart';
 | 
			
		||||
import 'message/message.dart';
 | 
			
		||||
 | 
			
		||||
class Overhang extends StatelessWidget {
 | 
			
		||||
  const Overhang({Key? key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return ListView(
 | 
			
		||||
      children: const [
 | 
			
		||||
        ListItemNavigator(icon: Icons.newspaper, text: "Marianum Message", target: Message()),
 | 
			
		||||
        ListItemNavigator(icon: Icons.room, text: "Raumplan", target: Roomplan()),
 | 
			
		||||
      ],
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								lib/screen/pages/more/roomplan/roomplan.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								lib/screen/pages/more/roomplan/roomplan.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
import 'package:flutter/cupertino.dart';
 | 
			
		||||
 | 
			
		||||
class Roomplan extends StatelessWidget {
 | 
			
		||||
  const Roomplan({Key? key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return const Text("asd");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										166
									
								
								lib/screen/pages/talk/chatOverview.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								lib/screen/pages/talk/chatOverview.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,166 @@
 | 
			
		||||
import 'dart:convert';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/foundation.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:http/http.dart' as http;
 | 
			
		||||
import 'package:marianum_mobile/data/outgoingPackets/talkContactsAskPacket.dart';
 | 
			
		||||
import 'package:marianum_mobile/widget/loadingPacket.dart';
 | 
			
		||||
import 'package:provider/provider.dart';
 | 
			
		||||
 | 
			
		||||
import '../../../data/accountModel.dart';
 | 
			
		||||
import '../../../data/incommingPackets/talkContactsPacket.dart';
 | 
			
		||||
import '../../../widget/loadingSpinner.dart';
 | 
			
		||||
import 'chatView.dart';
 | 
			
		||||
 | 
			
		||||
class Talk extends StatefulWidget {
 | 
			
		||||
  const Talk({Key? key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<Talk> createState() => _TalkState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _TalkState extends State<Talk> {
 | 
			
		||||
  // List<ChatData> chats = List<ChatData>.empty(growable: true);
 | 
			
		||||
  //
 | 
			
		||||
  // Future<List<ChatData>> getChats() async {
 | 
			
		||||
  //   var url = Uri.https("***REMOVED***:***REMOVED***@mhsl.eu", "marianum/app/middleware/chat.php");
 | 
			
		||||
  //   var response = await http.get(
 | 
			
		||||
  //     url,
 | 
			
		||||
  //     headers: (
 | 
			
		||||
  //       {
 | 
			
		||||
  //         "Accept": "application/json",
 | 
			
		||||
  //         "OCS-APIRequest": "true",
 | 
			
		||||
  //       }
 | 
			
		||||
  //     ),
 | 
			
		||||
  //   );
 | 
			
		||||
  //
 | 
			
		||||
  //   return compute(parseChats, response.body);
 | 
			
		||||
  // }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
    Provider.of<TalkContactsPaket>(context, listen: false).invoke();
 | 
			
		||||
    //TalkContactsAskPacket().send();
 | 
			
		||||
    super.initState();
 | 
			
		||||
    // Future.delayed(Duration.zero).then((context) => updateChats());
 | 
			
		||||
    // Provider.of<AccountModel>(context, listen: false).channel.sink.add("chat");
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void updateChats() {
 | 
			
		||||
    // var chats = getChats();
 | 
			
		||||
    //
 | 
			
		||||
    // showDialog(
 | 
			
		||||
    //     context: context,
 | 
			
		||||
    //     barrierDismissible: false,
 | 
			
		||||
    //     builder: (BuildContext context) {
 | 
			
		||||
    //       return const LoadingSpinner();
 | 
			
		||||
    //     }
 | 
			
		||||
    // );
 | 
			
		||||
    //
 | 
			
		||||
    // chats.then((value) =>
 | 
			
		||||
    //     setState(() {
 | 
			
		||||
    //       Navigator.pop(context);
 | 
			
		||||
    //       this.chats.clear();
 | 
			
		||||
    //       this.chats = value;
 | 
			
		||||
    //     })
 | 
			
		||||
    // );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    // List<ListTile> chats = List<ListTile>.empty(growable: true);
 | 
			
		||||
    //
 | 
			
		||||
    // for (var element in this.chats) {
 | 
			
		||||
    //   chats.add(
 | 
			
		||||
    //     ListTile(
 | 
			
		||||
    //       leading: element.type == 1 ? CircleAvatar(
 | 
			
		||||
    //         backgroundColor: Colors.grey,
 | 
			
		||||
    //         foregroundImage: Image.network(element.avatar).image,
 | 
			
		||||
    //       ) : const Icon(Icons.group),
 | 
			
		||||
    //       title: Text(element.name),
 | 
			
		||||
    //       subtitle: Text(
 | 
			
		||||
    //         "${element.lastMessageAuthor}: ${element.lastMessage.replaceAll("\n", "")}",
 | 
			
		||||
    //         overflow: TextOverflow.ellipsis,
 | 
			
		||||
    //       ),
 | 
			
		||||
    //       onTap: () {
 | 
			
		||||
    //         Navigator.push(context, MaterialPageRoute(builder: (builder) => const ChatView()));
 | 
			
		||||
    //       },
 | 
			
		||||
    //       trailing: element.unreadMessages > 0 ? const Icon(Icons.mark_chat_unread) : Text(element.lastActivity),
 | 
			
		||||
    //     )
 | 
			
		||||
    //   );
 | 
			
		||||
    // }
 | 
			
		||||
    //
 | 
			
		||||
    // return ListView(
 | 
			
		||||
    //   children: chats,
 | 
			
		||||
    // );
 | 
			
		||||
 | 
			
		||||
    return Consumer<TalkContactsPaket>(
 | 
			
		||||
      builder: (context, data, child) {
 | 
			
		||||
        List<ListTile> chats = List<ListTile>.empty(growable: true);
 | 
			
		||||
 | 
			
		||||
        for (var element in data.contacts) {
 | 
			
		||||
          chats.add(ListTile(
 | 
			
		||||
            title: Text(element.name),
 | 
			
		||||
            subtitle: Text("${element.lastTime}: ${element.lastMessage}".replaceAll("\n", " "), overflow: TextOverflow.ellipsis),
 | 
			
		||||
            trailing: element.unreadMessages ? const Icon(Icons.new_releases_outlined) : null,
 | 
			
		||||
            leading: CircleAvatar(
 | 
			
		||||
              foregroundImage: element.isGroup ? null : Image.network(element.profilePicture).image,
 | 
			
		||||
              backgroundColor: Theme.of(context).primaryColor,
 | 
			
		||||
              foregroundColor: Colors.white,
 | 
			
		||||
              child: element.isGroup ? const Icon(Icons.group) : const Icon(Icons.person),
 | 
			
		||||
            ),
 | 
			
		||||
            onTap: () {
 | 
			
		||||
              Navigator.of(context).push(MaterialPageRoute(builder: (context) {
 | 
			
		||||
                return ChatView(
 | 
			
		||||
                  userToken: element.userToken,
 | 
			
		||||
                );
 | 
			
		||||
              }));
 | 
			
		||||
            },
 | 
			
		||||
          ));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return LoadingPacket(packet: data, child: ListView(children: chats));
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// List<ChatData> parseChats(String json) {
 | 
			
		||||
//   final parsed = jsonDecode(json).cast<Map<String, dynamic>>();
 | 
			
		||||
//   return parsed.map<ChatData>((a) => ChatData.fromJson(a)).toList();
 | 
			
		||||
// }
 | 
			
		||||
//
 | 
			
		||||
// class ChatData {
 | 
			
		||||
//   final String name;
 | 
			
		||||
//   final String lastMessage;
 | 
			
		||||
//   final String lastMessageAuthor;
 | 
			
		||||
//   final String avatar;
 | 
			
		||||
//   final int type;
 | 
			
		||||
//   final String lastActivity;
 | 
			
		||||
//   final int unreadMessages;
 | 
			
		||||
//
 | 
			
		||||
//   const ChatData({
 | 
			
		||||
//     required this.name,
 | 
			
		||||
//     required this.lastMessage,
 | 
			
		||||
//     required this.lastMessageAuthor,
 | 
			
		||||
//     required this.avatar,
 | 
			
		||||
//     required this.type,
 | 
			
		||||
//     required this.lastActivity,
 | 
			
		||||
//     required this.unreadMessages,
 | 
			
		||||
//   });
 | 
			
		||||
//
 | 
			
		||||
//   factory ChatData.fromJson(Map<String, dynamic> json) {
 | 
			
		||||
//     return ChatData(
 | 
			
		||||
//       name: json['name'] as String,
 | 
			
		||||
//       lastMessage: json['last_message'] as String,
 | 
			
		||||
//       lastMessageAuthor: json['last_message_author'] as String,
 | 
			
		||||
//       avatar: json['avatar'] as String,
 | 
			
		||||
//       type: json['type'] as int,
 | 
			
		||||
//       lastActivity: json['lastActivity'] as String,
 | 
			
		||||
//       unreadMessages: json['unreadMessages'] as int,
 | 
			
		||||
//     );
 | 
			
		||||
//   }
 | 
			
		||||
// }
 | 
			
		||||
							
								
								
									
										101
									
								
								lib/screen/pages/talk/chatView.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								lib/screen/pages/talk/chatView.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,101 @@
 | 
			
		||||
 | 
			
		||||
import 'package:bubble/bubble.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:marianum_mobile/data/incommingPackets/talkChatPacket.dart';
 | 
			
		||||
import 'package:marianum_mobile/widget/loadingPacket.dart';
 | 
			
		||||
import 'package:provider/provider.dart';
 | 
			
		||||
 | 
			
		||||
class ChatView extends StatefulWidget {
 | 
			
		||||
  final String userToken;
 | 
			
		||||
  const ChatView({Key? key, required this.userToken}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<ChatView> createState() => _ChatViewState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _ChatViewState extends State<ChatView> {
 | 
			
		||||
  static const styleSystem = BubbleStyle(
 | 
			
		||||
    color: Color.fromRGBO(212, 234, 244, 1.0),
 | 
			
		||||
    borderWidth: 1,
 | 
			
		||||
    elevation: 2,
 | 
			
		||||
    margin: BubbleEdges.only(top: 15),
 | 
			
		||||
    alignment: Alignment.center,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  static const styleOther = BubbleStyle(
 | 
			
		||||
    nip: BubbleNip.leftBottom,
 | 
			
		||||
    color: Colors.white,
 | 
			
		||||
    borderWidth: 1,
 | 
			
		||||
    elevation: 2,
 | 
			
		||||
    margin: BubbleEdges.only(top: 15, left: 10),
 | 
			
		||||
    alignment: Alignment.topLeft,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  static const styleSelf = BubbleStyle(
 | 
			
		||||
    nip: BubbleNip.rightBottom,
 | 
			
		||||
    color: Color.fromRGBO(225, 255, 199, 1.0),
 | 
			
		||||
    borderWidth: 1,
 | 
			
		||||
    elevation: 2,
 | 
			
		||||
    margin: BubbleEdges.only(top: 15, right: 10),
 | 
			
		||||
    alignment: Alignment.topRight,
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
    super.initState();
 | 
			
		||||
 | 
			
		||||
    Provider.of<TalkChatPacket>(context, listen: false).invoke(
 | 
			
		||||
      data: {
 | 
			
		||||
        "token": widget.userToken
 | 
			
		||||
      },
 | 
			
		||||
      indicateLoading: true,
 | 
			
		||||
      allowNotifyListeners: false,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Scaffold(
 | 
			
		||||
      backgroundColor: Colors.grey,
 | 
			
		||||
      appBar: AppBar(
 | 
			
		||||
        title: const Text("Chat mit jemandem"),
 | 
			
		||||
      ),
 | 
			
		||||
      body: Consumer<TalkChatPacket>(
 | 
			
		||||
        builder: (context, data, child) {
 | 
			
		||||
          List<Bubble> messages = List<Bubble>.empty(growable: true);
 | 
			
		||||
 | 
			
		||||
          data.messages.forEach((element) {
 | 
			
		||||
            messages.add(Bubble(
 | 
			
		||||
              style: styleSelf,
 | 
			
		||||
              child: Text(element.content),
 | 
			
		||||
            ));
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          return LoadingPacket(packet: data, child: ListView(
 | 
			
		||||
            children: [],
 | 
			
		||||
          ));
 | 
			
		||||
        },
 | 
			
		||||
      ),
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      // ListView(
 | 
			
		||||
      //   children: [
 | 
			
		||||
      //     Bubble(
 | 
			
		||||
      //       style: styleSystem,
 | 
			
		||||
      //       child: const Text("Chat gestartet"),
 | 
			
		||||
      //     ),
 | 
			
		||||
      //     Bubble(
 | 
			
		||||
      //       style: styleOther,
 | 
			
		||||
      //       child: const Text("Hi, das ist ein Testtext"),
 | 
			
		||||
      //     ),
 | 
			
		||||
      //     Bubble(
 | 
			
		||||
      //       style: styleSelf,
 | 
			
		||||
      //       child: Text(widget.userToken),
 | 
			
		||||
      //     )
 | 
			
		||||
      //   ],
 | 
			
		||||
      // ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								lib/screen/pages/timetable/timetable.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								lib/screen/pages/timetable/timetable.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/cupertino.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
class Timetable extends StatefulWidget {
 | 
			
		||||
  const Timetable({Key? key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<Timetable> createState() => _TimetableState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _TimetableState extends State<Timetable> {
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
    super.initState();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    List<ListTile> chats = List<ListTile>.empty(growable: true);
 | 
			
		||||
 | 
			
		||||
    return const Center(
 | 
			
		||||
      child: Text("Not supported"),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								lib/screen/settings/about/about.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								lib/screen/settings/about/about.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
class About extends StatelessWidget {
 | 
			
		||||
  const About({Key? key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Scaffold(
 | 
			
		||||
      appBar: AppBar(
 | 
			
		||||
        title: const Text("Über diese App"),
 | 
			
		||||
      ),
 | 
			
		||||
      body: const Card(
 | 
			
		||||
        elevation: 1,
 | 
			
		||||
        borderOnForeground: true,
 | 
			
		||||
        child: Text("Marianum Fulda"),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										90
									
								
								lib/screen/settings/settings.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								lib/screen/settings/settings.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:provider/provider.dart';
 | 
			
		||||
import 'package:shared_preferences/shared_preferences.dart';
 | 
			
		||||
 | 
			
		||||
import '../../data/accountModel.dart';
 | 
			
		||||
import '../../data/incommingPackets/serverInfoPacket.dart';
 | 
			
		||||
import '../../widget/ListItem.dart';
 | 
			
		||||
 | 
			
		||||
class Settings extends StatefulWidget {
 | 
			
		||||
  const Settings({Key? key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<Settings> createState() => _SettingsState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _SettingsState extends State<Settings> {
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
    super.initState();
 | 
			
		||||
    ServerInfoPacket().invoke();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Scaffold(
 | 
			
		||||
      appBar: AppBar(
 | 
			
		||||
        title: const Text("Einstellungen"),
 | 
			
		||||
      ),
 | 
			
		||||
      body: ListView(
 | 
			
		||||
        children: [
 | 
			
		||||
 | 
			
		||||
          const ListItemNavigator(icon: Icons.info, text: "Über diese App", target: AboutDialog(
 | 
			
		||||
            applicationIcon: Icon(Icons.send_time_extension_outlined),
 | 
			
		||||
            applicationLegalese: "Released under MIT-License",
 | 
			
		||||
            applicationName: "Marianum Fulda",
 | 
			
		||||
            applicationVersion: "ALPHA 0.1",
 | 
			
		||||
          )),
 | 
			
		||||
 | 
			
		||||
          ListTile(
 | 
			
		||||
            leading: const Icon(Icons.logout),
 | 
			
		||||
            title: const Text("Account abmelden"),
 | 
			
		||||
            onTap: () {
 | 
			
		||||
              Navigator.push(context, MaterialPageRoute(builder: (builder) => AlertDialog(
 | 
			
		||||
                title: const Text("Abmelden?"),
 | 
			
		||||
                content: const Text("Möchtest du dich wirklich abmelden?"),
 | 
			
		||||
                actions: [
 | 
			
		||||
                  TextButton(
 | 
			
		||||
                    child: const Text("Abmelden"),
 | 
			
		||||
                    onPressed: () {
 | 
			
		||||
                      SharedPreferences.getInstance().then((value) => {
 | 
			
		||||
                        value.clear(),
 | 
			
		||||
                      }).then((value) => {
 | 
			
		||||
                        Provider.of<AccountModel>(context, listen: false).logout(),
 | 
			
		||||
                        Navigator.popUntil(context, (route) => !Navigator.canPop(context)),
 | 
			
		||||
                      });
 | 
			
		||||
                    }
 | 
			
		||||
                  ),
 | 
			
		||||
 | 
			
		||||
                  TextButton(
 | 
			
		||||
                    child: const Text("Abbrechen"),
 | 
			
		||||
                    onPressed: () {
 | 
			
		||||
                      Navigator.pop(context);
 | 
			
		||||
                    },
 | 
			
		||||
                  ),
 | 
			
		||||
                ],
 | 
			
		||||
              )));
 | 
			
		||||
            },
 | 
			
		||||
          ),
 | 
			
		||||
 | 
			
		||||
          Consumer<ServerInfoPacket>(
 | 
			
		||||
            builder: (context, serverInfo, child) {
 | 
			
		||||
              return ListTile(
 | 
			
		||||
                leading: const Icon(Icons.home_work_outlined),
 | 
			
		||||
                title: Text("Server: ${serverInfo.serverName}"),
 | 
			
		||||
                subtitle: Text(
 | 
			
		||||
                      "Betreiber: ${serverInfo.serverOwner}\n"
 | 
			
		||||
                      "Serverversion: ${serverInfo.serverVersion}\n"
 | 
			
		||||
                      "Rechtliche hinweise: ${serverInfo.legal}\n"
 | 
			
		||||
                ),
 | 
			
		||||
              );
 | 
			
		||||
            },
 | 
			
		||||
          )
 | 
			
		||||
 | 
			
		||||
        ],
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								lib/widget/ListItem.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								lib/widget/ListItem.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
class ListItemNavigator extends StatelessWidget {
 | 
			
		||||
  const ListItemNavigator({Key? key, required this.icon, required this.text, required this.target, this.onLongPress, this.arrow = true}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  final IconData icon;
 | 
			
		||||
  final String text;
 | 
			
		||||
  final bool arrow;
 | 
			
		||||
 | 
			
		||||
  final Widget target;
 | 
			
		||||
 | 
			
		||||
  final GestureLongPressCallback? onLongPress;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    onTabAction() => Navigator.push(context, MaterialPageRoute(builder: (context) => target));
 | 
			
		||||
    onLongPressAction() => onLongPress;
 | 
			
		||||
 | 
			
		||||
    return ListTile(
 | 
			
		||||
      leading: Icon(icon),
 | 
			
		||||
      title: Text(text),
 | 
			
		||||
      trailing: arrow ? const Icon(Icons.arrow_right) : null,
 | 
			
		||||
      onTap: onTabAction,
 | 
			
		||||
      onLongPress: onLongPressAction,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								lib/widget/loadingPacket.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								lib/widget/loadingPacket.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
import 'package:flutter/cupertino.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:marianum_mobile/data/incomingPacket.dart';
 | 
			
		||||
import 'package:provider/provider.dart';
 | 
			
		||||
 | 
			
		||||
class LoadingPacket extends StatefulWidget {
 | 
			
		||||
  final Widget child;
 | 
			
		||||
  final IncomingPacket packet;
 | 
			
		||||
 | 
			
		||||
  const LoadingPacket({Key? key, required this.child, required this.packet}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<LoadingPacket> createState() => _LoadingPacketState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _LoadingPacketState extends State<LoadingPacket> {
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return widget.packet.isReceived ? widget.child : Center(
 | 
			
		||||
      child: Column(
 | 
			
		||||
        mainAxisAlignment: MainAxisAlignment.center,
 | 
			
		||||
        crossAxisAlignment: CrossAxisAlignment.center,
 | 
			
		||||
        children: [
 | 
			
		||||
          const CircularProgressIndicator(),
 | 
			
		||||
          Padding(padding: const EdgeInsets.all(20), child: Text("Request: '${widget.packet.packetId}'"))
 | 
			
		||||
        ]
 | 
			
		||||
      )
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								lib/widget/loadingSpinner.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								lib/widget/loadingSpinner.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
class LoadingSpinner extends StatefulWidget {
 | 
			
		||||
  const LoadingSpinner({Key? key}) : super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<LoadingSpinner> createState() => _LoadingSpinnerState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _LoadingSpinnerState extends State<LoadingSpinner> {
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Dialog(
 | 
			
		||||
      child: Padding(
 | 
			
		||||
        padding: const EdgeInsets.all(20),
 | 
			
		||||
        child: Row(
 | 
			
		||||
          mainAxisSize: MainAxisSize.min,
 | 
			
		||||
          children: [
 | 
			
		||||
            CircularProgressIndicator(
 | 
			
		||||
              color: Theme.of(context).primaryColor,
 | 
			
		||||
            ),
 | 
			
		||||
            const Padding(padding: EdgeInsets.only(left: 15), child: Text("Daten abrufen...")),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user