Added central user credentials management
This commit is contained in:
parent
04c244503e
commit
1521056217
@ -3,13 +3,12 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
|
|
||||||
|
import '../../../model/accountData.dart';
|
||||||
import 'autocompleteResponse.dart';
|
import 'autocompleteResponse.dart';
|
||||||
|
|
||||||
class AutocompleteApi {
|
class AutocompleteApi {
|
||||||
Future<AutocompleteResponse> find(String query) async {
|
Future<AutocompleteResponse> find(String query) async {
|
||||||
var preferences = await SharedPreferences.getInstance();
|
|
||||||
Map<String, dynamic> getParameters = {
|
Map<String, dynamic> getParameters = {
|
||||||
"search": query,
|
"search": query,
|
||||||
"itemType": " ",
|
"itemType": " ",
|
||||||
@ -22,7 +21,7 @@ class AutocompleteApi {
|
|||||||
headers.putIfAbsent("Accept", () => "application/json");
|
headers.putIfAbsent("Accept", () => "application/json");
|
||||||
headers.putIfAbsent("OCS-APIRequest", () => "true");
|
headers.putIfAbsent("OCS-APIRequest", () => "true");
|
||||||
|
|
||||||
Uri endpoint = Uri.https("${preferences.getString("username")!}:${preferences.getString("password")!}@cloud.marianum-fulda.de", "/ocs/v2.php/core/autocomplete/get", getParameters);
|
Uri endpoint = Uri.https("${AccountData().buildHttpAuthString()}@cloud.marianum-fulda.de", "/ocs/v2.php/core/autocomplete/get", getParameters);
|
||||||
|
|
||||||
Response response = await http.get(endpoint, headers: headers);
|
Response response = await http.get(endpoint, headers: headers);
|
||||||
if(response.statusCode != HttpStatus.ok) throw Exception("Api call failed with ${response.statusCode}: ${response.body}");
|
if(response.statusCode != HttpStatus.ok) throw Exception("Api call failed with ${response.statusCode}: ${response.body}");
|
||||||
|
@ -3,19 +3,17 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
|
|
||||||
|
import '../../../model/accountData.dart';
|
||||||
import 'fileSharingApiParams.dart';
|
import 'fileSharingApiParams.dart';
|
||||||
|
|
||||||
class FileSharingApi {
|
class FileSharingApi {
|
||||||
Future<void> share(FileSharingApiParams query) async {
|
Future<void> share(FileSharingApiParams query) async {
|
||||||
var preferences = await SharedPreferences.getInstance();
|
|
||||||
|
|
||||||
Map<String, String> headers = {};
|
Map<String, String> headers = {};
|
||||||
headers.putIfAbsent("Accept", () => "application/json");
|
headers.putIfAbsent("Accept", () => "application/json");
|
||||||
headers.putIfAbsent("OCS-APIRequest", () => "true");
|
headers.putIfAbsent("OCS-APIRequest", () => "true");
|
||||||
|
|
||||||
Uri endpoint = Uri.https("${preferences.getString("username")!}:${preferences.getString("password")!}@cloud.marianum-fulda.de", "/ocs/v2.php/apps/files_sharing/api/v1/shares", query.toJson().map((key, value) => MapEntry(key, value.toString())));
|
Uri endpoint = Uri.https("${AccountData().buildHttpAuthString()}@cloud.marianum-fulda.de", "/ocs/v2.php/apps/files_sharing/api/v1/shares", query.toJson().map((key, value) => MapEntry(key, value.toString())));
|
||||||
|
|
||||||
log("request file share");
|
log("request file share");
|
||||||
Response response = await http.post(endpoint, headers: headers);
|
Response response = await http.post(endpoint, headers: headers);
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
|
|
||||||
|
import '../../../model/accountData.dart';
|
||||||
import '../../apiError.dart';
|
import '../../apiError.dart';
|
||||||
import '../../apiParams.dart';
|
import '../../apiParams.dart';
|
||||||
import '../../apiRequest.dart';
|
import '../../apiRequest.dart';
|
||||||
@ -32,9 +32,7 @@ abstract class TalkApi<T> extends ApiRequest {
|
|||||||
getParameters?.update(key, (value) => value.toString());
|
getParameters?.update(key, (value) => value.toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
SharedPreferences preferences = await SharedPreferences.getInstance();
|
Uri endpoint = Uri.https("${AccountData().buildHttpAuthString()}@cloud.marianum-fulda.de", "/ocs/v2.php/apps/spreed/api/$path", getParameters);
|
||||||
|
|
||||||
Uri endpoint = Uri.https("${preferences.getString("username")!}:${preferences.getString("password")!}@cloud.marianum-fulda.de", "/ocs/v2.php/apps/spreed/api/$path", getParameters);
|
|
||||||
|
|
||||||
headers ??= {};
|
headers ??= {};
|
||||||
headers?.putIfAbsent("Accept", () => "application/json");
|
headers?.putIfAbsent("Accept", () => "application/json");
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:nextcloud/nextcloud.dart';
|
import 'package:nextcloud/nextcloud.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
|
|
||||||
|
import '../../../model/accountData.dart';
|
||||||
import '../../apiRequest.dart';
|
import '../../apiRequest.dart';
|
||||||
import '../../apiResponse.dart';
|
import '../../apiResponse.dart';
|
||||||
|
|
||||||
@ -17,14 +17,10 @@ abstract class WebdavApi<T> extends ApiRequest {
|
|||||||
static Future<String> webdavConnectString = buildWebdavConnectString();
|
static Future<String> webdavConnectString = buildWebdavConnectString();
|
||||||
|
|
||||||
static Future<WebDavClient> establishWebdavConnection() async {
|
static Future<WebDavClient> establishWebdavConnection() async {
|
||||||
SharedPreferences preferences = await SharedPreferences.getInstance();
|
return NextcloudClient("https://cloud.marianum-fulda.de/", username: AccountData().getUsername(), password: AccountData().getPassword(), loginName: AccountData().getUsername()).webdav;
|
||||||
|
|
||||||
return NextcloudClient("https://cloud.marianum-fulda.de/", username: preferences.getString("username"), password: preferences.getString("password"), loginName: preferences.getString("username")).webdav;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<String> buildWebdavConnectString() async {
|
static Future<String> buildWebdavConnectString() async {
|
||||||
SharedPreferences preferences = await SharedPreferences.getInstance();
|
return "https://${AccountData().buildHttpAuthString()}@cloud.marianum-fulda.de/remote.php/dav/files/${AccountData().getUsername()}/";
|
||||||
|
|
||||||
return "https://${preferences.getString("username")}:${preferences.getString("password")}@cloud.marianum-fulda.de/remote.php/dav/files/${preferences.getString("username")}/";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,8 +2,7 @@ import 'dart:async';
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import '../../../../model/accountData.dart';
|
||||||
|
|
||||||
import '../../webuntisApi.dart';
|
import '../../webuntisApi.dart';
|
||||||
import 'authenticateParams.dart';
|
import 'authenticateParams.dart';
|
||||||
import 'authenticateResponse.dart';
|
import 'authenticateResponse.dart';
|
||||||
@ -28,12 +27,10 @@ class Authenticate extends WebuntisApi {
|
|||||||
static AuthenticateResponse? _lastResponse;
|
static AuthenticateResponse? _lastResponse;
|
||||||
|
|
||||||
static Future<void> createSession() async {
|
static Future<void> createSession() async {
|
||||||
SharedPreferences preferences = await SharedPreferences.getInstance();
|
|
||||||
|
|
||||||
_lastResponse = await Authenticate(
|
_lastResponse = await Authenticate(
|
||||||
AuthenticateParams(
|
AuthenticateParams(
|
||||||
user: preferences.getString("username")!,
|
user: AccountData().getUsername(),
|
||||||
password: preferences.getString("password")!,
|
password: AccountData().getPassword(),
|
||||||
)
|
)
|
||||||
).run();
|
).run();
|
||||||
}
|
}
|
||||||
|
@ -22,14 +22,16 @@ class App extends StatefulWidget {
|
|||||||
class _AppState extends State<App> {
|
class _AppState extends State<App> {
|
||||||
int currentPage = 0;
|
int currentPage = 0;
|
||||||
late Timer refetchChats;
|
late Timer refetchChats;
|
||||||
|
late Timer updateTimings;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
Timer.periodic(const Duration(seconds: 30), (Timer t) => setState((){}));
|
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||||
Provider.of<ChatListProps>(context, listen: false).run();
|
Provider.of<ChatListProps>(context, listen: false).run();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
updateTimings = Timer.periodic(const Duration(seconds: 30), (Timer t) => setState((){}));
|
||||||
|
|
||||||
refetchChats = Timer.periodic(const Duration(minutes: 1), (timer) {
|
refetchChats = Timer.periodic(const Duration(minutes: 1), (timer) {
|
||||||
if(!context.mounted) return;
|
if(!context.mounted) return;
|
||||||
Provider.of<ChatListProps>(context, listen: false).run();
|
Provider.of<ChatListProps>(context, listen: false).run();
|
||||||
@ -107,6 +109,7 @@ class _AppState extends State<App> {
|
|||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
refetchChats.cancel();
|
refetchChats.cancel();
|
||||||
|
updateTimings.cancel();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,10 +4,10 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:jiffy/jiffy.dart';
|
import 'package:jiffy/jiffy.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
|
|
||||||
import 'app.dart';
|
import 'app.dart';
|
||||||
|
import 'model/accountData.dart';
|
||||||
import 'model/accountModel.dart';
|
import 'model/accountModel.dart';
|
||||||
import 'model/chatList/chatListProps.dart';
|
import 'model/chatList/chatListProps.dart';
|
||||||
import 'model/chatList/chatProps.dart';
|
import 'model/chatList/chatProps.dart';
|
||||||
@ -18,7 +18,7 @@ import 'storage/base/settingsProvider.dart';
|
|||||||
import 'theming/darkAppTheme.dart';
|
import 'theming/darkAppTheme.dart';
|
||||||
import 'theming/lightAppTheme.dart';
|
import 'theming/lightAppTheme.dart';
|
||||||
import 'view/login/login.dart';
|
import 'view/login/login.dart';
|
||||||
import 'widget/errorView.dart';
|
import 'widget/placeholderView.dart';
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
@ -27,7 +27,7 @@ Future<void> main() async {
|
|||||||
SecurityContext.defaultContext.setTrustedCertificatesBytes(data.buffer.asUint8List());
|
SecurityContext.defaultContext.setTrustedCertificatesBytes(data.buffer.asUint8List());
|
||||||
|
|
||||||
ErrorWidget.builder = (error) {
|
ErrorWidget.builder = (error) {
|
||||||
return ErrorView(icon: Icons.phonelink_erase_rounded, text: error.toString());
|
return PlaceholderView(icon: Icons.phonelink_erase_rounded, text: error.toString());
|
||||||
};
|
};
|
||||||
|
|
||||||
runApp(
|
runApp(
|
||||||
@ -56,27 +56,22 @@ class Main extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MainState extends State<Main> {
|
class _MainState extends State<Main> {
|
||||||
|
|
||||||
final Future<SharedPreferences> _storage = SharedPreferences.getInstance();
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
|
||||||
Jiffy.setLocale("de");
|
Jiffy.setLocale("de");
|
||||||
_storage.then((SharedPreferences preferences) => preferences.getBool("loggedIn") ?? false).then((value) => {
|
|
||||||
if(value) {
|
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
|
||||||
Provider.of<AccountModel>(context, listen: false).login()
|
|
||||||
} else {
|
AccountData().waitForPopulation().then((value) {
|
||||||
Provider.of<AccountModel>(context, listen: false).logout()
|
Provider.of<AccountModel>(context, listen: false)
|
||||||
}
|
.setState(value ? AccountModelState.loggedIn : AccountModelState.loggedOut);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
|
||||||
|
|
||||||
return Directionality(
|
return Directionality(
|
||||||
textDirection: TextDirection.ltr,
|
textDirection: TextDirection.ltr,
|
||||||
child: Consumer<SettingsProvider>(
|
child: Consumer<SettingsProvider>(
|
||||||
@ -93,7 +88,6 @@ class _MainState extends State<Main> {
|
|||||||
],
|
],
|
||||||
locale: const Locale('de'),
|
locale: const Locale('de'),
|
||||||
|
|
||||||
|
|
||||||
title: 'Marianum Fulda',
|
title: 'Marianum Fulda',
|
||||||
|
|
||||||
themeMode: settings.val().appTheme,
|
themeMode: settings.val().appTheme,
|
||||||
@ -101,21 +95,15 @@ class _MainState extends State<Main> {
|
|||||||
darkTheme: DarkAppTheme.theme,
|
darkTheme: DarkAppTheme.theme,
|
||||||
|
|
||||||
|
|
||||||
home: FutureBuilder<SharedPreferences>(
|
home: Consumer<AccountModel>(
|
||||||
future: _storage,
|
|
||||||
builder: (BuildContext context, AsyncSnapshot<SharedPreferences> snapshot) {
|
|
||||||
|
|
||||||
if(snapshot.hasData) {
|
|
||||||
return Consumer<AccountModel>(
|
|
||||||
builder: (context, accountModel, child) {
|
builder: (context, accountModel, child) {
|
||||||
return accountModel.isLoggedIn ? const App() : const Login();
|
switch(accountModel.state) {
|
||||||
},
|
case AccountModelState.loggedIn: return const App();
|
||||||
);
|
case AccountModelState.loggedOut: return const Login();
|
||||||
} else {
|
case AccountModelState.undefined: return const PlaceholderView(icon: Icons.timer, text: "Daten werden geladen");
|
||||||
return const Center(child: CircularProgressIndicator());
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
78
lib/model/accountData.dart
Normal file
78
lib/model/accountData.dart
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
import 'accountModel.dart';
|
||||||
|
|
||||||
|
class AccountData {
|
||||||
|
static const _usernameField = "username";
|
||||||
|
static const _passwordField = "password";
|
||||||
|
|
||||||
|
static final AccountData _instance = AccountData._construct();
|
||||||
|
final Future<SharedPreferences> _storage = SharedPreferences.getInstance();
|
||||||
|
Completer<void> _populated = Completer();
|
||||||
|
|
||||||
|
factory AccountData() {
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountData._construct() {
|
||||||
|
_updateFromStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
String? _username;
|
||||||
|
String? _password;
|
||||||
|
|
||||||
|
String getUsername() {
|
||||||
|
if(_username == null) throw Exception("Username not initialized");
|
||||||
|
return _username!;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getPassword() {
|
||||||
|
if(_password == null) throw Exception("Password not initialized");
|
||||||
|
return _password!;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> setData(BuildContext context, String username, String password) async {
|
||||||
|
SharedPreferences storage = await _storage;
|
||||||
|
|
||||||
|
storage.setString(_usernameField, username);
|
||||||
|
storage.setString(_passwordField, password);
|
||||||
|
await _updateFromStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeData(BuildContext context) async {
|
||||||
|
_populated = Completer();
|
||||||
|
Provider.of<AccountModel>(context, listen: false).setState(AccountModelState.loggedOut);
|
||||||
|
|
||||||
|
SharedPreferences storage = await _storage;
|
||||||
|
storage.remove(_usernameField);
|
||||||
|
storage.remove(_passwordField);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _updateFromStorage() async {
|
||||||
|
SharedPreferences storage = await _storage;
|
||||||
|
await storage.reload();
|
||||||
|
if(storage.containsKey(_usernameField) && storage.containsKey(_passwordField)) {
|
||||||
|
_username = storage.getString(_usernameField);
|
||||||
|
_password = storage.getString(_passwordField);
|
||||||
|
_populated.complete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> waitForPopulation() async {
|
||||||
|
await _populated.future;
|
||||||
|
return isPopulated();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPopulated() {
|
||||||
|
return _username != null && _password != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String buildHttpAuthString() {
|
||||||
|
if(!isPopulated()) throw Exception("AccountData (e.g. username or password) is not initialized!");
|
||||||
|
return "$_username:$_password";
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,17 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
||||||
class AccountModel extends ChangeNotifier {
|
class AccountModel extends ChangeNotifier {
|
||||||
bool _isLoggedIn = false;
|
AccountModelState _accountState = AccountModelState.undefined;
|
||||||
|
AccountModelState get state => _accountState;
|
||||||
|
|
||||||
bool get isLoggedIn => _isLoggedIn;
|
void setState(AccountModelState state) {
|
||||||
|
_accountState = state;
|
||||||
void logout() {
|
|
||||||
_isLoggedIn = false;
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
void login() {
|
|
||||||
_isLoggedIn = true;
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum AccountModelState {
|
||||||
|
undefined,
|
||||||
|
loggedIn,
|
||||||
|
loggedOut,
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:marianum_mobile/storage/file/fileSettings.dart';
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
import '../file/fileSettings.dart';
|
||||||
import '../gradeAverages/gradeAveragesSettings.dart';
|
import '../gradeAverages/gradeAveragesSettings.dart';
|
||||||
import '../talk/talkSettings.dart';
|
import '../talk/talkSettings.dart';
|
||||||
import '../timetable/timetableSettings.dart';
|
import '../timetable/timetableSettings.dart';
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
|
|
||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_login/flutter_login.dart';
|
import 'package:flutter_login/flutter_login.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
|
|
||||||
import '../../api/apiError.dart';
|
|
||||||
import '../../api/webuntis/queries/authenticate/authenticateParams.dart';
|
import '../../api/webuntis/queries/authenticate/authenticateParams.dart';
|
||||||
import '../../api/webuntis/queries/authenticate/authenticate.dart';
|
import '../../api/webuntis/queries/authenticate/authenticate.dart';
|
||||||
import '../../api/webuntis/webuntisError.dart';
|
import '../../model/accountData.dart';
|
||||||
import '../../model/accountModel.dart';
|
import '../../model/accountModel.dart';
|
||||||
|
|
||||||
class Login extends StatefulWidget {
|
class Login extends StatefulWidget {
|
||||||
@ -27,8 +23,7 @@ class _LoginState extends State<Login> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> _login(LoginData data) async {
|
Future<String?> _login(LoginData data) async {
|
||||||
SharedPreferences preferences = await SharedPreferences.getInstance();
|
AccountData().removeData(context);
|
||||||
preferences.setBool("loggedIn", false);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await Authenticate(
|
await Authenticate(
|
||||||
@ -36,22 +31,16 @@ class _LoginState extends State<Login> {
|
|||||||
user: data.name,
|
user: data.name,
|
||||||
password: data.password,
|
password: data.password,
|
||||||
)
|
)
|
||||||
).run().then((value) => {
|
).run().then((value) async {
|
||||||
log(value.sessionId)
|
await AccountData().setData(context, data.name, data.password);
|
||||||
});
|
|
||||||
} on WebuntisError catch(e) {
|
|
||||||
return e.toString();
|
|
||||||
} on ApiError catch(e) {
|
|
||||||
return e.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
displayDisclaimerText = false;
|
displayDisclaimerText = false;
|
||||||
});
|
});
|
||||||
|
});
|
||||||
preferences.setBool("loggedIn", true);
|
} catch(e) {
|
||||||
preferences.setString("username", data.name);
|
return e.toString();
|
||||||
preferences.setString("password", data.password);
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -69,7 +58,7 @@ class _LoginState extends State<Login> {
|
|||||||
|
|
||||||
userValidator: _checkInput,
|
userValidator: _checkInput,
|
||||||
passwordValidator: _checkInput,
|
passwordValidator: _checkInput,
|
||||||
onSubmitAnimationCompleted: () => Provider.of<AccountModel>(context, listen: false).login(),
|
onSubmitAnimationCompleted: () => Provider.of<AccountModel>(context, listen: false).setState(AccountModelState.loggedIn),
|
||||||
|
|
||||||
onLogin: _login,
|
onLogin: _login,
|
||||||
onSignup: null,
|
onSignup: null,
|
||||||
|
@ -4,8 +4,6 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:loader_overlay/loader_overlay.dart';
|
import 'package:loader_overlay/loader_overlay.dart';
|
||||||
import 'package:marianum_mobile/storage/base/settingsProvider.dart';
|
|
||||||
import 'package:marianum_mobile/widget/loadingSpinner.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import '../../../api/marianumcloud/webdav/queries/listFiles/cacheableFile.dart';
|
import '../../../api/marianumcloud/webdav/queries/listFiles/cacheableFile.dart';
|
||||||
@ -13,7 +11,9 @@ import '../../../api/marianumcloud/webdav/queries/listFiles/listFilesCache.dart'
|
|||||||
import '../../../api/marianumcloud/webdav/queries/listFiles/listFilesResponse.dart';
|
import '../../../api/marianumcloud/webdav/queries/listFiles/listFilesResponse.dart';
|
||||||
import '../../../api/marianumcloud/webdav/webdavApi.dart';
|
import '../../../api/marianumcloud/webdav/webdavApi.dart';
|
||||||
import '../../../model/files/filesProps.dart';
|
import '../../../model/files/filesProps.dart';
|
||||||
import '../../../widget/errorView.dart';
|
import '../../../storage/base/settingsProvider.dart';
|
||||||
|
import '../../../widget/loadingSpinner.dart';
|
||||||
|
import '../../../widget/placeholderView.dart';
|
||||||
import '../../../widget/filePick.dart';
|
import '../../../widget/filePick.dart';
|
||||||
import 'fileUploadDialog.dart';
|
import 'fileUploadDialog.dart';
|
||||||
import 'fileElement.dart';
|
import 'fileElement.dart';
|
||||||
@ -224,7 +224,7 @@ class _FilesState extends State<Files> {
|
|||||||
},
|
},
|
||||||
child: const Icon(Icons.add),
|
child: const Icon(Icons.add),
|
||||||
),
|
),
|
||||||
body: data == null ? const LoadingSpinner() : data!.files.isEmpty ? const ErrorView(icon: Icons.folder_off_rounded, text: "Der Ordner ist leer") : LoaderOverlay(
|
body: data == null ? const LoadingSpinner() : data!.files.isEmpty ? const PlaceholderView(icon: Icons.folder_off_rounded, text: "Der Ordner ist leer") : LoaderOverlay(
|
||||||
child: RefreshIndicator(
|
child: RefreshIndicator(
|
||||||
onRefresh: () {
|
onRefresh: () {
|
||||||
_query();
|
_query();
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:marianum_mobile/widget/loadingSpinner.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import '../../../../api/mhsl/message/getMessages/getMessagesResponse.dart';
|
import '../../../../api/mhsl/message/getMessages/getMessagesResponse.dart';
|
||||||
import '../../../../model/message/messageProps.dart';
|
import '../../../../model/message/messageProps.dart';
|
||||||
|
import '../../../../widget/loadingSpinner.dart';
|
||||||
import 'messageView.dart';
|
import 'messageView.dart';
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,12 +4,12 @@ import 'package:flowder/flowder.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:jiffy/jiffy.dart';
|
import 'package:jiffy/jiffy.dart';
|
||||||
import 'package:marianum_mobile/api/marianumcloud/talk/deleteMessage/deleteMessage.dart';
|
|
||||||
import 'package:marianum_mobile/model/chatList/chatProps.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import '../../../api/marianumcloud/talk/chat/getChatResponse.dart';
|
import '../../../api/marianumcloud/talk/chat/getChatResponse.dart';
|
||||||
|
import '../../../api/marianumcloud/talk/deleteMessage/deleteMessage.dart';
|
||||||
import '../../../api/marianumcloud/talk/room/getRoomResponse.dart';
|
import '../../../api/marianumcloud/talk/room/getRoomResponse.dart';
|
||||||
|
import '../../../model/chatList/chatProps.dart';
|
||||||
import '../../../theming/appTheme.dart';
|
import '../../../theming/appTheme.dart';
|
||||||
import '../../../widget/debug/debugTile.dart';
|
import '../../../widget/debug/debugTile.dart';
|
||||||
import '../files/fileElement.dart';
|
import '../files/fileElement.dart';
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:marianum_mobile/api/marianumcloud/talk/createRoom/createRoomParams.dart';
|
|
||||||
import 'package:marianum_mobile/widget/confirmDialog.dart';
|
|
||||||
import 'package:marianum_mobile/widget/loadingSpinner.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import '../../../api/marianumcloud/talk/createRoom/createRoom.dart';
|
import '../../../api/marianumcloud/talk/createRoom/createRoom.dart';
|
||||||
|
import '../../../api/marianumcloud/talk/createRoom/createRoomParams.dart';
|
||||||
import '../../../model/chatList/chatListProps.dart';
|
import '../../../model/chatList/chatListProps.dart';
|
||||||
import '../../../storage/base/settingsProvider.dart';
|
import '../../../storage/base/settingsProvider.dart';
|
||||||
|
import '../../../widget/confirmDialog.dart';
|
||||||
|
import '../../../widget/loadingSpinner.dart';
|
||||||
import 'chatTile.dart';
|
import 'chatTile.dart';
|
||||||
import 'joinChat.dart';
|
import 'joinChat.dart';
|
||||||
import 'searchChat.dart';
|
import 'searchChat.dart';
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:jiffy/jiffy.dart';
|
import 'package:jiffy/jiffy.dart';
|
||||||
import 'package:loader_overlay/loader_overlay.dart';
|
import 'package:loader_overlay/loader_overlay.dart';
|
||||||
import 'package:marianum_mobile/widget/loadingSpinner.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import '../../../api/marianumcloud/talk/chat/getChatResponse.dart';
|
import '../../../api/marianumcloud/talk/chat/getChatResponse.dart';
|
||||||
import '../../../api/marianumcloud/talk/room/getRoomResponse.dart';
|
import '../../../api/marianumcloud/talk/room/getRoomResponse.dart';
|
||||||
import '../../../theming/appTheme.dart';
|
import '../../../theming/appTheme.dart';
|
||||||
import '../../../model/chatList/chatProps.dart';
|
import '../../../model/chatList/chatProps.dart';
|
||||||
|
import '../../../widget/loadingSpinner.dart';
|
||||||
import 'chatBubble.dart';
|
import 'chatBubble.dart';
|
||||||
import 'chatTextfield.dart';
|
import 'chatTextfield.dart';
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
import '../../../api/marianumcloud/autocomplete/autocompleteApi.dart';
|
import '../../../api/marianumcloud/autocomplete/autocompleteApi.dart';
|
||||||
import '../../../api/marianumcloud/autocomplete/autocompleteResponse.dart';
|
import '../../../api/marianumcloud/autocomplete/autocompleteResponse.dart';
|
||||||
import '../../../widget/errorView.dart';
|
import '../../../widget/placeholderView.dart';
|
||||||
|
|
||||||
class JoinChat extends SearchDelegate<String> {
|
class JoinChat extends SearchDelegate<String> {
|
||||||
CancelableOperation<AutocompleteResponse>? future;
|
CancelableOperation<AutocompleteResponse>? future;
|
||||||
@ -47,7 +47,7 @@ class JoinChat extends SearchDelegate<String> {
|
|||||||
if(future != null) future!.cancel();
|
if(future != null) future!.cancel();
|
||||||
|
|
||||||
if(query.isEmpty) {
|
if(query.isEmpty) {
|
||||||
return const ErrorView(
|
return const PlaceholderView(
|
||||||
text: "Suche nach benutzern",
|
text: "Suche nach benutzern",
|
||||||
icon: Icons.person_search_outlined,
|
icon: Icons.person_search_outlined,
|
||||||
);
|
);
|
||||||
@ -81,7 +81,7 @@ class JoinChat extends SearchDelegate<String> {
|
|||||||
);
|
);
|
||||||
} else if(snapshot.hasError) {
|
} else if(snapshot.hasError) {
|
||||||
log(snapshot.error.toString());
|
log(snapshot.error.toString());
|
||||||
return ErrorView(text: snapshot.error.toString());
|
return PlaceholderView(icon: Icons.search_off, text: snapshot.error.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return const Center(child: CircularProgressIndicator());
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:marianum_mobile/widget/loadingSpinner.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:syncfusion_flutter_calendar/calendar.dart';
|
import 'package:syncfusion_flutter_calendar/calendar.dart';
|
||||||
|
|
||||||
@ -11,7 +10,8 @@ import '../../../api/webuntis/queries/getRooms/getRoomsResponse.dart';
|
|||||||
import '../../../api/webuntis/queries/getSubjects/getSubjectsResponse.dart';
|
import '../../../api/webuntis/queries/getSubjects/getSubjectsResponse.dart';
|
||||||
import '../../../model/timetable/timetableProps.dart';
|
import '../../../model/timetable/timetableProps.dart';
|
||||||
import '../../../storage/base/settingsProvider.dart';
|
import '../../../storage/base/settingsProvider.dart';
|
||||||
import '../../../widget/errorView.dart';
|
import '../../../widget/loadingSpinner.dart';
|
||||||
|
import '../../../widget/placeholderView.dart';
|
||||||
import 'appointmenetComponent.dart';
|
import 'appointmenetComponent.dart';
|
||||||
import 'appointmentDetails.dart';
|
import 'appointmentDetails.dart';
|
||||||
import 'timeRegionComponent.dart';
|
import 'timeRegionComponent.dart';
|
||||||
@ -68,7 +68,7 @@ class _TimetableState extends State<Timetable> {
|
|||||||
GetHolidaysResponse holidays = value.getHolidaysResponse;
|
GetHolidaysResponse holidays = value.getHolidaysResponse;
|
||||||
|
|
||||||
if(value.hasError) {
|
if(value.hasError) {
|
||||||
return ErrorView(
|
return PlaceholderView(
|
||||||
icon: Icons.calendar_month,
|
icon: Icons.calendar_month,
|
||||||
text: "Webuntis error: ${value.error.toString()}",
|
text: "Webuntis error: ${value.error.toString()}",
|
||||||
);
|
);
|
||||||
|
@ -5,7 +5,7 @@ import 'package:package_info/package_info.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
import '../../model/accountModel.dart';
|
import '../../model/accountData.dart';
|
||||||
import '../../storage/base/settingsProvider.dart';
|
import '../../storage/base/settingsProvider.dart';
|
||||||
import '../../theming/appTheme.dart';
|
import '../../theming/appTheme.dart';
|
||||||
import '../../widget/confirmDialog.dart';
|
import '../../widget/confirmDialog.dart';
|
||||||
@ -52,9 +52,9 @@ class _SettingsState extends State<Settings> {
|
|||||||
onConfirm: () {
|
onConfirm: () {
|
||||||
SharedPreferences.getInstance().then((value) => {
|
SharedPreferences.getInstance().then((value) => {
|
||||||
value.clear(),
|
value.clear(),
|
||||||
}).then((value) => {
|
}).then((value) {
|
||||||
Provider.of<AccountModel>(context, listen: false).logout(),
|
AccountData().removeData(context);
|
||||||
Navigator.popUntil(context, (route) => !Navigator.canPop(context)),
|
Navigator.popUntil(context, (route) => !Navigator.canPop(context));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -7,7 +7,7 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:jiffy/jiffy.dart';
|
import 'package:jiffy/jiffy.dart';
|
||||||
import 'package:localstore/localstore.dart';
|
import 'package:localstore/localstore.dart';
|
||||||
|
|
||||||
import '../../../widget/errorView.dart';
|
import '../../../widget/placeholderView.dart';
|
||||||
import 'jsonViewer.dart';
|
import 'jsonViewer.dart';
|
||||||
|
|
||||||
class CacheView extends StatefulWidget {
|
class CacheView extends StatefulWidget {
|
||||||
@ -93,7 +93,7 @@ class _CacheViewState extends State<CacheView> {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return const Center(
|
return const Center(
|
||||||
child: ErrorView(icon: Icons.hourglass_empty, text: "Keine Daten"),
|
child: PlaceholderView(icon: Icons.hourglass_empty, text: "Keine Daten"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class ErrorView extends StatelessWidget {
|
|
||||||
final IconData icon;
|
|
||||||
final String text;
|
|
||||||
const ErrorView({Key? key, this.icon = Icons.report_gmailerrorred, this.text = "Es ist ein Fehler aufgetreten!"}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Center(
|
|
||||||
child: Container(
|
|
||||||
margin: const EdgeInsets.only(top: 100, left: 20, right: 20),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
margin: const EdgeInsets.all(30),
|
|
||||||
child: Icon(icon, color: Colors.grey, size: 60),
|
|
||||||
),
|
|
||||||
Text(text,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 20,
|
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
34
lib/widget/placeholderView.dart
Normal file
34
lib/widget/placeholderView.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class PlaceholderView extends StatelessWidget {
|
||||||
|
final IconData icon;
|
||||||
|
final String text;
|
||||||
|
const PlaceholderView({Key? key, required this.icon, required this.text}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DefaultTextStyle(
|
||||||
|
style: const TextStyle(),
|
||||||
|
child: Center(
|
||||||
|
child: Container(
|
||||||
|
margin: const EdgeInsets.only(top: 100, left: 20, right: 20),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
margin: const EdgeInsets.all(30),
|
||||||
|
child: Icon(icon, color: Colors.grey, size: 60),
|
||||||
|
),
|
||||||
|
Text(text,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user