Added Nextcloud base
This commit is contained in:
parent
e54ae9c2ff
commit
fea36b9a6d
60
.idea/libraries/Dart_Packages.xml
generated
60
.idea/libraries/Dart_Packages.xml
generated
@ -5,14 +5,14 @@
|
||||
<entry key="_fe_analyzer_shared">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/_fe_analyzer_shared-50.0.0/lib" />
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/_fe_analyzer_shared-53.0.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="analyzer">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/analyzer-5.2.0/lib" />
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/analyzer-5.5.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
@ -89,7 +89,7 @@
|
||||
<entry key="build_resolvers">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/build_resolvers-2.1.0/lib" />
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/build_resolvers-2.2.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
@ -194,7 +194,7 @@
|
||||
<entry key="dio">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/dio-4.0.6/lib" />
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/dio-5.0.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
@ -222,7 +222,7 @@
|
||||
<entry key="fixnum">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/fixnum-1.0.1/lib" />
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/fixnum-1.1.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
@ -383,7 +383,7 @@
|
||||
<entry key="localstore">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/localstore-1.2.3/lib" />
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/localstore-1.3.4/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
@ -653,20 +653,6 @@
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="sqflite">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/sqflite-2.2.4+1/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="sqflite_common">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/sqflite_common-2.4.2+2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="stack_trace">
|
||||
<value>
|
||||
<list>
|
||||
@ -695,13 +681,6 @@
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="synchronized">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/synchronized-3.0.1/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="term_glyph">
|
||||
<value>
|
||||
<list>
|
||||
@ -740,7 +719,7 @@
|
||||
<entry key="universal_io">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/universal_io-2.0.4/lib" />
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/universal_io-2.2.0/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
@ -824,7 +803,7 @@
|
||||
<entry key="webdav_client">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/webdav_client-1.1.8/lib" />
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/webdav_client-1.1.9/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
@ -845,7 +824,7 @@
|
||||
<entry key="xml">
|
||||
<value>
|
||||
<list>
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/xml-6.1.0/lib" />
|
||||
<option value="$USER_HOME$/.pub-cache/hosted/pub.dev/xml-6.2.2/lib" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
@ -859,8 +838,8 @@
|
||||
</option>
|
||||
</properties>
|
||||
<CLASSES>
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/_fe_analyzer_shared-50.0.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/analyzer-5.2.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/_fe_analyzer_shared-53.0.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/analyzer-5.5.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/another_flushbar-1.12.29/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/another_transformer_page_view-2.0.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/archive-3.3.6/lib" />
|
||||
@ -871,7 +850,7 @@
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/build-2.3.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/build_config-1.1.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/build_daemon-3.1.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/build_resolvers-2.1.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/build_resolvers-2.2.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/build_runner-2.3.3/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/build_runner_core-7.2.7/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/built_collection-5.1.1/lib" />
|
||||
@ -886,11 +865,11 @@
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/csslib-0.17.2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/cupertino_icons-1.0.5/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/dart_style-2.2.4/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/dio-4.0.6/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/dio-5.0.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/fake_async-1.3.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/ffi-2.0.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/file-6.1.4/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/fixnum-1.0.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/fixnum-1.1.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_lints-2.0.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_login-4.1.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/flutter_native_splash-2.2.17/lib" />
|
||||
@ -910,7 +889,7 @@
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/json_annotation-4.8.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/json_serializable-6.6.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/lints-2.0.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/localstore-1.2.3/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/localstore-1.3.4/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/logging-1.1.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/matcher-0.12.13/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/material_color_utilities-0.2.0/lib" />
|
||||
@ -948,19 +927,16 @@
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/source_gen-1.2.7/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/source_helper-1.3.3/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/source_span-1.9.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/sqflite-2.2.4+1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/sqflite_common-2.4.2+2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/stack_trace-1.11.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/stream_channel-2.1.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/stream_transform-2.1.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/string_scanner-1.2.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/synchronized-3.0.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/term_glyph-1.2.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/test_api-0.4.16/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/timetable_view-0.3.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/timing-1.0.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/typed_data-1.3.1/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/universal_io-2.0.4/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/universal_io-2.2.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher-6.1.9/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_android-6.0.23/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_ios-6.1.0/lib" />
|
||||
@ -972,10 +948,10 @@
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/vector_math-2.1.4/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/watcher-1.0.2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/web_socket_channel-2.3.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/webdav_client-1.1.8/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/webdav_client-1.1.9/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/win32-3.1.3/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/xdg_directories-1.0.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/xml-6.1.0/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/xml-6.2.2/lib" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/yaml-3.1.1/lib" />
|
||||
<root url="file:///opt/flutter/bin/cache/pkg/sky_engine/lib" />
|
||||
<root url="file:///opt/flutter/packages/flutter/lib" />
|
||||
|
1
.idea/libraries/Flutter_Plugins.xml
generated
1
.idea/libraries/Flutter_Plugins.xml
generated
@ -11,7 +11,6 @@
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_web-2.0.14" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher-6.1.9" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_windows-3.0.3" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/sqflite-2.2.4+1" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/path_provider_linux-2.1.8" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.1.3" />
|
||||
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dev/url_launcher_ios-6.1.0" />
|
||||
|
BIN
assets/background/chat.png
Normal file
BIN
assets/background/chat.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
59
flutter_01.log
Normal file
59
flutter_01.log
Normal file
@ -0,0 +1,59 @@
|
||||
Flutter crash report.
|
||||
Please report a bug at https://github.com/flutter/flutter/issues.
|
||||
|
||||
## command
|
||||
|
||||
flutter --no-color run --machine --device-id=5200de3d4dd02295 --profile --dart-define=flutter.inspector.structuredErrors=true lib/main.dart
|
||||
|
||||
## exception
|
||||
|
||||
String: failed to connect to http://127.0.0.1:45275/X0V7tlGyJXA=/
|
||||
|
||||
```
|
||||
```
|
||||
|
||||
## flutter doctor
|
||||
|
||||
```
|
||||
[!] Flutter (Channel stable, 3.7.3, on Linux Mint 20.3 5.15.0-60-generic, locale de_DE.UTF-8)
|
||||
• Flutter version 3.7.3 on channel stable at /opt/flutter
|
||||
! The flutter binary is not on your path. Consider adding /opt/flutter/bin to your path.
|
||||
! The dart binary is not on your path. Consider adding /opt/flutter/bin to your path.
|
||||
• Upstream repository https://github.com/flutter/flutter.git
|
||||
• Framework revision 9944297138 (vor 8 Tagen), 2023-02-08 15:46:04 -0800
|
||||
• Engine revision 248290d6d5
|
||||
• Dart version 2.19.2
|
||||
• DevTools version 2.20.1
|
||||
• If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.
|
||||
|
||||
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
|
||||
• Android SDK at /home/elias/Android/Sdk
|
||||
• Platform android-33, build-tools 33.0.0
|
||||
• Java binary at: /home/elias/.local/share/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9123335/jre/bin/java
|
||||
• Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)
|
||||
• All Android licenses accepted.
|
||||
|
||||
[✗] Chrome - develop for the web (Cannot find Chrome executable at google-chrome)
|
||||
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
|
||||
|
||||
[✓] Linux toolchain - develop for Linux desktop
|
||||
• clang version 10.0.0-4ubuntu1
|
||||
• cmake version 3.16.3
|
||||
• ninja version 1.10.0
|
||||
• pkg-config version 0.29.1
|
||||
|
||||
[✓] Android Studio (version 2021.3)
|
||||
• Android Studio at /home/elias/.local/share/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9123335
|
||||
• Flutter plugin version 71.0.3
|
||||
• Dart plugin version 213.7433
|
||||
• Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)
|
||||
|
||||
[✓] Connected device (2 available)
|
||||
• SM G800F (mobile) • 5200de3d4dd02295 • android-arm • Android 6.0.1 (API 23)
|
||||
• Linux (desktop) • linux • linux-x64 • Linux Mint 20.3 5.15.0-60-generic
|
||||
|
||||
[✓] HTTP Host Availability
|
||||
• All required HTTP hosts are available
|
||||
|
||||
! Doctor found issues in 2 categories.
|
||||
```
|
@ -4,36 +4,5 @@ import 'package:http/http.dart' as http;
|
||||
import 'package:marianum_mobile/api/apiError.dart';
|
||||
|
||||
class ApiRequest {
|
||||
Uri endpoint;
|
||||
|
||||
ApiRequest(this.endpoint);
|
||||
|
||||
Future<http.Response> get(Map<String, String>? headers) async {
|
||||
return await http.get(endpoint, headers: headers);
|
||||
}
|
||||
|
||||
Future<http.Response> post(String data, Map<String, String>? headers) async {
|
||||
log("Fetching: ${data}");
|
||||
try {
|
||||
http.Response response = await http
|
||||
.post(endpoint, body: data, headers: headers)
|
||||
.timeout(
|
||||
const Duration(seconds: 10),
|
||||
onTimeout: () {
|
||||
log("timeout!");
|
||||
throw ApiError("Network timeout");
|
||||
}
|
||||
);
|
||||
|
||||
if(response.statusCode != 200) {
|
||||
log("Got ${response.statusCode}");
|
||||
throw ApiError("Service response invalid, got status ${response.statusCode}");
|
||||
}
|
||||
return response;
|
||||
|
||||
} on Exception catch(e) {
|
||||
throw ApiError("Http: ${e.toString()}");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
26
lib/api/marianumcloud/talk/chat/getChat.dart
Normal file
26
lib/api/marianumcloud/talk/chat/getChat.dart
Normal file
@ -0,0 +1,26 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/src/response.dart';
|
||||
import 'package:marianum_mobile/api/marianumcloud/talk/chat/getChatResponse.dart';
|
||||
import 'package:marianum_mobile/api/marianumcloud/talk/talkApi.dart';
|
||||
|
||||
import 'getChatParams.dart';
|
||||
|
||||
class GetChat extends TalkApi<GetChatResponse> {
|
||||
String chatToken;
|
||||
|
||||
GetChatParams params;
|
||||
GetChat(this.chatToken, this.params) : super("v1/chat/$chatToken", null, getParameters: params.toJson());
|
||||
|
||||
@override
|
||||
assemble(String raw) {
|
||||
return GetChatResponse.fromJson(jsonDecode(raw)['ocs']); // TODO move "ocs" to superclass
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Response> request(Uri uri, Object? body, Map<String, String>? headers) {
|
||||
return http.get(uri, headers: headers);
|
||||
}
|
||||
|
||||
}
|
30
lib/api/marianumcloud/talk/chat/getChatCache.dart
Normal file
30
lib/api/marianumcloud/talk/chat/getChatCache.dart
Normal file
@ -0,0 +1,30 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:marianum_mobile/api/marianumcloud/talk/chat/getChat.dart';
|
||||
import 'package:marianum_mobile/api/marianumcloud/talk/chat/getChatParams.dart';
|
||||
import 'package:marianum_mobile/api/marianumcloud/talk/chat/getChatResponse.dart';
|
||||
import 'package:marianum_mobile/api/requestCache.dart';
|
||||
|
||||
class GetChatCache extends RequestCache<GetChatResponse> {
|
||||
String chatToken;
|
||||
|
||||
GetChatCache({required onUpdate, required this.chatToken}) : super(RequestCache.cacheNothing, onUpdate) {
|
||||
start("MarianumMobile", "nc-chat-$chatToken");
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GetChatResponse> onLoad() {
|
||||
return GetChat(
|
||||
chatToken,
|
||||
GetChatParams(
|
||||
lookIntoFuture: GetChatParamsSwitch.off
|
||||
)
|
||||
).run();
|
||||
}
|
||||
|
||||
@override
|
||||
GetChatResponse onLocalData(String json) {
|
||||
return GetChatResponse.fromJson(jsonDecode(json));
|
||||
}
|
||||
|
||||
}
|
33
lib/api/marianumcloud/talk/chat/getChatParams.dart
Normal file
33
lib/api/marianumcloud/talk/chat/getChatParams.dart
Normal file
@ -0,0 +1,33 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:marianum_mobile/api/apiParams.dart';
|
||||
|
||||
part 'getChatParams.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true, includeIfNull: false)
|
||||
class GetChatParams extends ApiParams {
|
||||
GetChatParamsSwitch lookIntoFuture;
|
||||
int? limit;
|
||||
int? lastKnownMessageId;
|
||||
int? lastCommonReadId;
|
||||
int? timeout;
|
||||
GetChatParamsSwitch? setReadMarker;
|
||||
GetChatParamsSwitch? includeLastKnown;
|
||||
|
||||
GetChatParams({
|
||||
required this.lookIntoFuture,
|
||||
this.limit,
|
||||
this.lastKnownMessageId,
|
||||
this.lastCommonReadId,
|
||||
this.timeout,
|
||||
this.setReadMarker,
|
||||
this.includeLastKnown
|
||||
});
|
||||
|
||||
factory GetChatParams.fromJson(Map<String, dynamic> json) => _$GetChatParamsFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$GetChatParamsToJson(this);
|
||||
}
|
||||
|
||||
enum GetChatParamsSwitch {
|
||||
@JsonValue(1) on,
|
||||
@JsonValue(0) off,
|
||||
}
|
48
lib/api/marianumcloud/talk/chat/getChatParams.g.dart
Normal file
48
lib/api/marianumcloud/talk/chat/getChatParams.g.dart
Normal file
@ -0,0 +1,48 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'getChatParams.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
GetChatParams _$GetChatParamsFromJson(Map<String, dynamic> json) =>
|
||||
GetChatParams(
|
||||
lookIntoFuture:
|
||||
$enumDecode(_$GetChatParamsSwitchEnumMap, json['lookIntoFuture']),
|
||||
limit: json['limit'] as int?,
|
||||
lastKnownMessageId: json['lastKnownMessageId'] as int?,
|
||||
lastCommonReadId: json['lastCommonReadId'] as int?,
|
||||
timeout: json['timeout'] as int?,
|
||||
setReadMarker: $enumDecodeNullable(
|
||||
_$GetChatParamsSwitchEnumMap, json['setReadMarker']),
|
||||
includeLastKnown: $enumDecodeNullable(
|
||||
_$GetChatParamsSwitchEnumMap, json['includeLastKnown']),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GetChatParamsToJson(GetChatParams instance) {
|
||||
final val = <String, dynamic>{
|
||||
'lookIntoFuture': _$GetChatParamsSwitchEnumMap[instance.lookIntoFuture]!,
|
||||
};
|
||||
|
||||
void writeNotNull(String key, dynamic value) {
|
||||
if (value != null) {
|
||||
val[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
writeNotNull('limit', instance.limit);
|
||||
writeNotNull('lastKnownMessageId', instance.lastKnownMessageId);
|
||||
writeNotNull('lastCommonReadId', instance.lastCommonReadId);
|
||||
writeNotNull('timeout', instance.timeout);
|
||||
writeNotNull(
|
||||
'setReadMarker', _$GetChatParamsSwitchEnumMap[instance.setReadMarker]);
|
||||
writeNotNull('includeLastKnown',
|
||||
_$GetChatParamsSwitchEnumMap[instance.includeLastKnown]);
|
||||
return val;
|
||||
}
|
||||
|
||||
const _$GetChatParamsSwitchEnumMap = {
|
||||
GetChatParamsSwitch.on: 1,
|
||||
GetChatParamsSwitch.off: 0,
|
||||
};
|
53
lib/api/marianumcloud/talk/chat/getChatResponse.dart
Normal file
53
lib/api/marianumcloud/talk/chat/getChatResponse.dart
Normal file
@ -0,0 +1,53 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:marianum_mobile/api/apiResponse.dart';
|
||||
import 'package:marianum_mobile/api/marianumcloud/talk/room/getRoomResponse.dart';
|
||||
|
||||
part 'getChatResponse.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class GetChatResponse extends ApiResponse {
|
||||
Set<GetChatResponseObject> data;
|
||||
|
||||
GetChatResponse(this.data);
|
||||
|
||||
factory GetChatResponse.fromJson(Map<String, dynamic> json) => _$GetChatResponseFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$GetChatResponseToJson(this);
|
||||
|
||||
List<GetChatResponseObject> sortByTimestamp() {
|
||||
List<GetChatResponseObject> sorted = data.toList();
|
||||
sorted.sort((a, b) => a.timestamp.compareTo(b.timestamp));
|
||||
return sorted;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class GetChatResponseObject {
|
||||
int id;
|
||||
String token;
|
||||
GetRoomResponseObjectMessageActorType actorType;
|
||||
String actorId;
|
||||
String actorDisplayName;
|
||||
int timestamp;
|
||||
String systemMessage;
|
||||
GetRoomResponseObjectMessageType messageType;
|
||||
bool isReplyable;
|
||||
String referenceId;
|
||||
String message;
|
||||
|
||||
GetChatResponseObject(
|
||||
this.id,
|
||||
this.token,
|
||||
this.actorType,
|
||||
this.actorId,
|
||||
this.actorDisplayName,
|
||||
this.timestamp,
|
||||
this.systemMessage,
|
||||
this.messageType,
|
||||
this.isReplyable,
|
||||
this.referenceId,
|
||||
this.message);
|
||||
|
||||
factory GetChatResponseObject.fromJson(Map<String, dynamic> json) => _$GetChatResponseObjectFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$GetChatResponseObjectToJson(this);
|
||||
}
|
||||
|
69
lib/api/marianumcloud/talk/chat/getChatResponse.g.dart
Normal file
69
lib/api/marianumcloud/talk/chat/getChatResponse.g.dart
Normal file
@ -0,0 +1,69 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'getChatResponse.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
GetChatResponse _$GetChatResponseFromJson(Map<String, dynamic> json) =>
|
||||
GetChatResponse(
|
||||
(json['data'] as List<dynamic>)
|
||||
.map((e) => GetChatResponseObject.fromJson(e as Map<String, dynamic>))
|
||||
.toSet(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GetChatResponseToJson(GetChatResponse instance) =>
|
||||
<String, dynamic>{
|
||||
'data': instance.data.map((e) => e.toJson()).toList(),
|
||||
};
|
||||
|
||||
GetChatResponseObject _$GetChatResponseObjectFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GetChatResponseObject(
|
||||
json['id'] as int,
|
||||
json['token'] as String,
|
||||
$enumDecode(
|
||||
_$GetRoomResponseObjectMessageActorTypeEnumMap, json['actorType']),
|
||||
json['actorId'] as String,
|
||||
json['actorDisplayName'] as String,
|
||||
json['timestamp'] as int,
|
||||
json['systemMessage'] as String,
|
||||
$enumDecode(
|
||||
_$GetRoomResponseObjectMessageTypeEnumMap, json['messageType']),
|
||||
json['isReplyable'] as bool,
|
||||
json['referenceId'] as String,
|
||||
json['message'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GetChatResponseObjectToJson(
|
||||
GetChatResponseObject instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'token': instance.token,
|
||||
'actorType':
|
||||
_$GetRoomResponseObjectMessageActorTypeEnumMap[instance.actorType]!,
|
||||
'actorId': instance.actorId,
|
||||
'actorDisplayName': instance.actorDisplayName,
|
||||
'timestamp': instance.timestamp,
|
||||
'systemMessage': instance.systemMessage,
|
||||
'messageType':
|
||||
_$GetRoomResponseObjectMessageTypeEnumMap[instance.messageType]!,
|
||||
'isReplyable': instance.isReplyable,
|
||||
'referenceId': instance.referenceId,
|
||||
'message': instance.message,
|
||||
};
|
||||
|
||||
const _$GetRoomResponseObjectMessageActorTypeEnumMap = {
|
||||
GetRoomResponseObjectMessageActorType.user: 'users',
|
||||
GetRoomResponseObjectMessageActorType.guest: 'guests',
|
||||
GetRoomResponseObjectMessageActorType.bot: 'bots',
|
||||
GetRoomResponseObjectMessageActorType.bridge: 'bridged',
|
||||
};
|
||||
|
||||
const _$GetRoomResponseObjectMessageTypeEnumMap = {
|
||||
GetRoomResponseObjectMessageType.comment: 'comment',
|
||||
GetRoomResponseObjectMessageType.deletedComment: 'comment_deleted',
|
||||
GetRoomResponseObjectMessageType.system: 'system',
|
||||
GetRoomResponseObjectMessageType.command: 'command',
|
||||
};
|
32
lib/api/marianumcloud/talk/room/getRoom.dart
Normal file
32
lib/api/marianumcloud/talk/room/getRoom.dart
Normal file
@ -0,0 +1,32 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:marianum_mobile/api/marianumcloud/talk/room/getRoomResponse.dart';
|
||||
import 'package:marianum_mobile/api/marianumcloud/talk/talkApi.dart';
|
||||
|
||||
import 'getRoomParams.dart';
|
||||
|
||||
|
||||
class GetRoom extends TalkApi<GetRoomResponse> {
|
||||
GetRoomParams params;
|
||||
GetRoom(this.params) : super("v4/room", null, getParameters: params.toJson());
|
||||
|
||||
|
||||
|
||||
@override
|
||||
GetRoomResponse assemble(String raw) {
|
||||
log("ASSEMBLING");
|
||||
log(raw);
|
||||
return GetRoomResponse.fromJson(jsonDecode(raw)['ocs']);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<http.Response> request(Uri uri, Object? body, Map<String, String>? headers) {
|
||||
log("REQUSTING...");
|
||||
log(uri.toString());
|
||||
log(headers.toString());
|
||||
return http.get(uri, headers: headers);
|
||||
}
|
||||
|
||||
}
|
30
lib/api/marianumcloud/talk/room/getRoomCache.dart
Normal file
30
lib/api/marianumcloud/talk/room/getRoomCache.dart
Normal file
@ -0,0 +1,30 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:marianum_mobile/api/marianumcloud/talk/room/getRoomParams.dart';
|
||||
import 'package:marianum_mobile/api/marianumcloud/talk/room/getRoomResponse.dart';
|
||||
import 'package:marianum_mobile/api/requestCache.dart';
|
||||
|
||||
import 'getRoom.dart';
|
||||
|
||||
class GetRoomCache extends RequestCache<GetRoomResponse> {
|
||||
GetRoomCache({onUpdate}) : super(RequestCache.cacheMinute, onUpdate) {
|
||||
start("MarianumMobile", "nc-rooms");
|
||||
}
|
||||
|
||||
@override
|
||||
GetRoomResponse onLocalData(String json) {
|
||||
log("LOCAL DATA FOUND");
|
||||
return GetRoomResponse.fromJson(jsonDecode(json));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GetRoomResponse> onLoad() {
|
||||
log("FETCHING DATA");
|
||||
return GetRoom(
|
||||
GetRoomParams(
|
||||
includeStatus: true,
|
||||
)
|
||||
).run();
|
||||
}
|
||||
}
|
26
lib/api/marianumcloud/talk/room/getRoomParams.dart
Normal file
26
lib/api/marianumcloud/talk/room/getRoomParams.dart
Normal file
@ -0,0 +1,26 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../../apiParams.dart';
|
||||
|
||||
part 'getRoomParams.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class GetRoomParams extends ApiParams {
|
||||
GetRoomParamsStatusUpdate? noStatusUpdate;
|
||||
@JsonKey(toJson: _format) bool? includeStatus;
|
||||
int? modifiedSince;
|
||||
|
||||
GetRoomParams({this.noStatusUpdate, this.includeStatus, this.modifiedSince});
|
||||
|
||||
factory GetRoomParams.fromJson(Map<String, dynamic> json) => _$GetRoomParamsFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$GetRoomParamsToJson(this);
|
||||
|
||||
static String _format(bool? v) => v.toString();
|
||||
}
|
||||
|
||||
enum GetRoomParamsStatusUpdate {
|
||||
@JsonValue(0) defaults,
|
||||
@JsonValue(1) keepAlive,
|
||||
}
|
28
lib/api/marianumcloud/talk/room/getRoomParams.g.dart
Normal file
28
lib/api/marianumcloud/talk/room/getRoomParams.g.dart
Normal file
@ -0,0 +1,28 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'getRoomParams.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
GetRoomParams _$GetRoomParamsFromJson(Map<String, dynamic> json) =>
|
||||
GetRoomParams(
|
||||
noStatusUpdate: $enumDecodeNullable(
|
||||
_$GetRoomParamsStatusUpdateEnumMap, json['noStatusUpdate']),
|
||||
includeStatus: json['includeStatus'] as bool?,
|
||||
modifiedSince: json['modifiedSince'] as int?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GetRoomParamsToJson(GetRoomParams instance) =>
|
||||
<String, dynamic>{
|
||||
'noStatusUpdate':
|
||||
_$GetRoomParamsStatusUpdateEnumMap[instance.noStatusUpdate],
|
||||
'includeStatus': GetRoomParams._format(instance.includeStatus),
|
||||
'modifiedSince': instance.modifiedSince,
|
||||
};
|
||||
|
||||
const _$GetRoomParamsStatusUpdateEnumMap = {
|
||||
GetRoomParamsStatusUpdate.defaults: 0,
|
||||
GetRoomParamsStatusUpdate.keepAlive: 1,
|
||||
};
|
151
lib/api/marianumcloud/talk/room/getRoomResponse.dart
Normal file
151
lib/api/marianumcloud/talk/room/getRoomResponse.dart
Normal file
@ -0,0 +1,151 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:marianum_mobile/api/apiResponse.dart';
|
||||
|
||||
part 'getRoomResponse.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class GetRoomResponse extends ApiResponse {
|
||||
Set<GetRoomResponseObject> data;
|
||||
|
||||
GetRoomResponse(this.data);
|
||||
|
||||
factory GetRoomResponse.fromJson(Map<String, dynamic> json) => _$GetRoomResponseFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$GetRoomResponseToJson(this);
|
||||
|
||||
List<GetRoomResponseObject> sortByLastActivity() {
|
||||
List<GetRoomResponseObject> sorted = data.toList();
|
||||
sorted.sort((a, b) => -a.lastActivity.compareTo(b.lastActivity));
|
||||
return sorted;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class GetRoomResponseObject {
|
||||
int id;
|
||||
String token;
|
||||
GetRoomResponseObjectConversationType type;
|
||||
String name;
|
||||
String displayName;
|
||||
String description;
|
||||
int participantType;
|
||||
int participantFlags;
|
||||
int readOnly;
|
||||
int listable;
|
||||
int lastPing;
|
||||
String sessionId;
|
||||
bool hasPassword;
|
||||
bool hasCall;
|
||||
int callFlag;
|
||||
bool canStartCall;
|
||||
bool canDeleteConversation;
|
||||
bool canLeaveConversation;
|
||||
int lastActivity;
|
||||
bool isFavorite;
|
||||
GetRoomResponseObjectParticipantNotificationLevel notificationLevel;
|
||||
int unreadMessages;
|
||||
bool unreadMention;
|
||||
bool unreadMentionDirect;
|
||||
int lastReadMessage;
|
||||
int lastCommonReadMessage;
|
||||
GetRoomResponseObjectMessage lastMessage;
|
||||
String? status;
|
||||
String? statusIcon;
|
||||
String? statusMessage;
|
||||
|
||||
GetRoomResponseObject(
|
||||
this.id,
|
||||
this.token,
|
||||
this.type,
|
||||
this.name,
|
||||
this.displayName,
|
||||
this.description,
|
||||
this.participantType,
|
||||
this.participantFlags,
|
||||
this.readOnly,
|
||||
this.listable,
|
||||
this.lastPing,
|
||||
this.sessionId,
|
||||
this.hasPassword,
|
||||
this.hasCall,
|
||||
this.callFlag,
|
||||
this.canStartCall,
|
||||
this.canDeleteConversation,
|
||||
this.canLeaveConversation,
|
||||
this.lastActivity,
|
||||
this.isFavorite,
|
||||
this.notificationLevel,
|
||||
this.unreadMessages,
|
||||
this.unreadMention,
|
||||
this.unreadMentionDirect,
|
||||
this.lastReadMessage,
|
||||
this.lastCommonReadMessage,
|
||||
this.lastMessage,
|
||||
this.status,
|
||||
this.statusIcon,
|
||||
this.statusMessage);
|
||||
|
||||
factory GetRoomResponseObject.fromJson(Map<String, dynamic> json) => _$GetRoomResponseObjectFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$GetRoomResponseObjectToJson(this);
|
||||
}
|
||||
|
||||
enum GetRoomResponseObjectConversationType {
|
||||
@JsonValue(1) oneToOne,
|
||||
@JsonValue(2) group,
|
||||
@JsonValue(3) public,
|
||||
@JsonValue(4) changelog,
|
||||
@JsonValue(5) deleted,
|
||||
}
|
||||
|
||||
enum GetRoomResponseObjectParticipantNotificationLevel {
|
||||
@JsonValue(0) defaultLevel,
|
||||
@JsonValue(1) alwaysNotify,
|
||||
@JsonValue(2) notifyOnMention,
|
||||
@JsonValue(3) neverNotify,
|
||||
}
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class GetRoomResponseObjectMessage {
|
||||
int id;
|
||||
String token;
|
||||
GetRoomResponseObjectMessageActorType actorType;
|
||||
String actorId;
|
||||
String actorDisplayName;
|
||||
int timestamp;
|
||||
String message;
|
||||
String systemMessage;
|
||||
GetRoomResponseObjectMessageType messageType;
|
||||
bool isReplyable;
|
||||
String referenceId;
|
||||
|
||||
|
||||
GetRoomResponseObjectMessage(
|
||||
this.id,
|
||||
this.token,
|
||||
this.actorType,
|
||||
this.actorId,
|
||||
this.actorDisplayName,
|
||||
this.timestamp,
|
||||
this.message,
|
||||
this.systemMessage,
|
||||
this.messageType,
|
||||
this.isReplyable,
|
||||
this.referenceId);
|
||||
|
||||
factory GetRoomResponseObjectMessage.fromJson(Map<String, dynamic> json) => _$GetRoomResponseObjectMessageFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$GetRoomResponseObjectMessageToJson(this);
|
||||
}
|
||||
|
||||
enum GetRoomResponseObjectMessageActorType {
|
||||
@JsonValue("users") user,
|
||||
@JsonValue("guests") guest,
|
||||
@JsonValue("bots") bot,
|
||||
@JsonValue("bridged") bridge,
|
||||
}
|
||||
|
||||
enum GetRoomResponseObjectMessageType {
|
||||
@JsonValue("comment") comment,
|
||||
@JsonValue("comment_deleted") deletedComment,
|
||||
@JsonValue("system") system,
|
||||
@JsonValue("command") command,
|
||||
}
|
158
lib/api/marianumcloud/talk/room/getRoomResponse.g.dart
Normal file
158
lib/api/marianumcloud/talk/room/getRoomResponse.g.dart
Normal file
@ -0,0 +1,158 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'getRoomResponse.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
GetRoomResponse _$GetRoomResponseFromJson(Map<String, dynamic> json) =>
|
||||
GetRoomResponse(
|
||||
(json['data'] as List<dynamic>)
|
||||
.map((e) => GetRoomResponseObject.fromJson(e as Map<String, dynamic>))
|
||||
.toSet(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GetRoomResponseToJson(GetRoomResponse instance) =>
|
||||
<String, dynamic>{
|
||||
'data': instance.data.map((e) => e.toJson()).toList(),
|
||||
};
|
||||
|
||||
GetRoomResponseObject _$GetRoomResponseObjectFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GetRoomResponseObject(
|
||||
json['id'] as int,
|
||||
json['token'] as String,
|
||||
$enumDecode(_$GetRoomResponseObjectConversationTypeEnumMap, json['type']),
|
||||
json['name'] as String,
|
||||
json['displayName'] as String,
|
||||
json['description'] as String,
|
||||
json['participantType'] as int,
|
||||
json['participantFlags'] as int,
|
||||
json['readOnly'] as int,
|
||||
json['listable'] as int,
|
||||
json['lastPing'] as int,
|
||||
json['sessionId'] as String,
|
||||
json['hasPassword'] as bool,
|
||||
json['hasCall'] as bool,
|
||||
json['callFlag'] as int,
|
||||
json['canStartCall'] as bool,
|
||||
json['canDeleteConversation'] as bool,
|
||||
json['canLeaveConversation'] as bool,
|
||||
json['lastActivity'] as int,
|
||||
json['isFavorite'] as bool,
|
||||
$enumDecode(_$GetRoomResponseObjectParticipantNotificationLevelEnumMap,
|
||||
json['notificationLevel']),
|
||||
json['unreadMessages'] as int,
|
||||
json['unreadMention'] as bool,
|
||||
json['unreadMentionDirect'] as bool,
|
||||
json['lastReadMessage'] as int,
|
||||
json['lastCommonReadMessage'] as int,
|
||||
GetRoomResponseObjectMessage.fromJson(
|
||||
json['lastMessage'] as Map<String, dynamic>),
|
||||
json['status'] as String?,
|
||||
json['statusIcon'] as String?,
|
||||
json['statusMessage'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GetRoomResponseObjectToJson(
|
||||
GetRoomResponseObject instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'token': instance.token,
|
||||
'type': _$GetRoomResponseObjectConversationTypeEnumMap[instance.type]!,
|
||||
'name': instance.name,
|
||||
'displayName': instance.displayName,
|
||||
'description': instance.description,
|
||||
'participantType': instance.participantType,
|
||||
'participantFlags': instance.participantFlags,
|
||||
'readOnly': instance.readOnly,
|
||||
'listable': instance.listable,
|
||||
'lastPing': instance.lastPing,
|
||||
'sessionId': instance.sessionId,
|
||||
'hasPassword': instance.hasPassword,
|
||||
'hasCall': instance.hasCall,
|
||||
'callFlag': instance.callFlag,
|
||||
'canStartCall': instance.canStartCall,
|
||||
'canDeleteConversation': instance.canDeleteConversation,
|
||||
'canLeaveConversation': instance.canLeaveConversation,
|
||||
'lastActivity': instance.lastActivity,
|
||||
'isFavorite': instance.isFavorite,
|
||||
'notificationLevel':
|
||||
_$GetRoomResponseObjectParticipantNotificationLevelEnumMap[
|
||||
instance.notificationLevel]!,
|
||||
'unreadMessages': instance.unreadMessages,
|
||||
'unreadMention': instance.unreadMention,
|
||||
'unreadMentionDirect': instance.unreadMentionDirect,
|
||||
'lastReadMessage': instance.lastReadMessage,
|
||||
'lastCommonReadMessage': instance.lastCommonReadMessage,
|
||||
'lastMessage': instance.lastMessage.toJson(),
|
||||
'status': instance.status,
|
||||
'statusIcon': instance.statusIcon,
|
||||
'statusMessage': instance.statusMessage,
|
||||
};
|
||||
|
||||
const _$GetRoomResponseObjectConversationTypeEnumMap = {
|
||||
GetRoomResponseObjectConversationType.oneToOne: 1,
|
||||
GetRoomResponseObjectConversationType.group: 2,
|
||||
GetRoomResponseObjectConversationType.public: 3,
|
||||
GetRoomResponseObjectConversationType.changelog: 4,
|
||||
GetRoomResponseObjectConversationType.deleted: 5,
|
||||
};
|
||||
|
||||
const _$GetRoomResponseObjectParticipantNotificationLevelEnumMap = {
|
||||
GetRoomResponseObjectParticipantNotificationLevel.defaultLevel: 0,
|
||||
GetRoomResponseObjectParticipantNotificationLevel.alwaysNotify: 1,
|
||||
GetRoomResponseObjectParticipantNotificationLevel.notifyOnMention: 2,
|
||||
GetRoomResponseObjectParticipantNotificationLevel.neverNotify: 3,
|
||||
};
|
||||
|
||||
GetRoomResponseObjectMessage _$GetRoomResponseObjectMessageFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GetRoomResponseObjectMessage(
|
||||
json['id'] as int,
|
||||
json['token'] as String,
|
||||
$enumDecode(
|
||||
_$GetRoomResponseObjectMessageActorTypeEnumMap, json['actorType']),
|
||||
json['actorId'] as String,
|
||||
json['actorDisplayName'] as String,
|
||||
json['timestamp'] as int,
|
||||
json['message'] as String,
|
||||
json['systemMessage'] as String,
|
||||
$enumDecode(
|
||||
_$GetRoomResponseObjectMessageTypeEnumMap, json['messageType']),
|
||||
json['isReplyable'] as bool,
|
||||
json['referenceId'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GetRoomResponseObjectMessageToJson(
|
||||
GetRoomResponseObjectMessage instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'token': instance.token,
|
||||
'actorType':
|
||||
_$GetRoomResponseObjectMessageActorTypeEnumMap[instance.actorType]!,
|
||||
'actorId': instance.actorId,
|
||||
'actorDisplayName': instance.actorDisplayName,
|
||||
'timestamp': instance.timestamp,
|
||||
'message': instance.message,
|
||||
'systemMessage': instance.systemMessage,
|
||||
'messageType':
|
||||
_$GetRoomResponseObjectMessageTypeEnumMap[instance.messageType]!,
|
||||
'isReplyable': instance.isReplyable,
|
||||
'referenceId': instance.referenceId,
|
||||
};
|
||||
|
||||
const _$GetRoomResponseObjectMessageActorTypeEnumMap = {
|
||||
GetRoomResponseObjectMessageActorType.user: 'users',
|
||||
GetRoomResponseObjectMessageActorType.guest: 'guests',
|
||||
GetRoomResponseObjectMessageActorType.bot: 'bots',
|
||||
GetRoomResponseObjectMessageActorType.bridge: 'bridged',
|
||||
};
|
||||
|
||||
const _$GetRoomResponseObjectMessageTypeEnumMap = {
|
||||
GetRoomResponseObjectMessageType.comment: 'comment',
|
||||
GetRoomResponseObjectMessageType.deletedComment: 'comment_deleted',
|
||||
GetRoomResponseObjectMessageType.system: 'system',
|
||||
GetRoomResponseObjectMessageType.command: 'command',
|
||||
};
|
51
lib/api/marianumcloud/talk/talkApi.dart
Normal file
51
lib/api/marianumcloud/talk/talkApi.dart
Normal file
@ -0,0 +1,51 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:marianum_mobile/api/apiRequest.dart';
|
||||
import 'package:marianum_mobile/api/apiResponse.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import '../../apiParams.dart';
|
||||
|
||||
enum TalkApiMethod {
|
||||
get,
|
||||
post,
|
||||
put,
|
||||
delete,
|
||||
}
|
||||
|
||||
abstract class TalkApi<T> extends ApiRequest {
|
||||
String path;
|
||||
ApiParams? body;
|
||||
Map<String, String>? headers = {};
|
||||
Map<String, dynamic>? getParameters;
|
||||
|
||||
http.Response? response;
|
||||
|
||||
TalkApi(this.path, this.body, {this.headers, this.getParameters});
|
||||
|
||||
Future<http.Response> request(Uri uri, Object? body, Map<String, String>? headers);
|
||||
T assemble(String raw);
|
||||
|
||||
Future<T> run() async {
|
||||
getParameters?.forEach((key, value) {
|
||||
getParameters?.update(key, (value) => value.toString());
|
||||
});
|
||||
|
||||
SharedPreferences preferences = await SharedPreferences.getInstance();
|
||||
|
||||
Uri endpoint = Uri.https("${preferences.getString("username")!}:${preferences.getString("password")!}@cloud.marianum-fulda.de", "/ocs/v2.php/apps/spreed/api/$path", getParameters);
|
||||
|
||||
headers ??= {};
|
||||
headers?.putIfAbsent("Accept", () => "application/json");
|
||||
headers?.putIfAbsent("OCS-APIRequest", () => "true");
|
||||
|
||||
http.Response data = await request(endpoint, body, headers);
|
||||
dynamic jsonData = jsonDecode(data.body);
|
||||
|
||||
|
||||
return assemble(data.body);
|
||||
}
|
||||
|
||||
}
|
12
lib/api/marianumcloud/talk/talkError.dart
Normal file
12
lib/api/marianumcloud/talk/talkError.dart
Normal file
@ -0,0 +1,12 @@
|
||||
class TalkError {
|
||||
String status;
|
||||
int code;
|
||||
String message;
|
||||
|
||||
TalkError(this.status, this.code, this.message);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "Talk - $status - ($code): $message";
|
||||
}
|
||||
}
|
9
lib/api/marianumcloud/webdav/webdavApi.dart
Normal file
9
lib/api/marianumcloud/webdav/webdavApi.dart
Normal file
@ -0,0 +1,9 @@
|
||||
import 'package:marianum_mobile/api/apiRequest.dart';
|
||||
|
||||
class WebdavApi extends ApiRequest {
|
||||
String basePath;
|
||||
|
||||
WebdavApi(this.basePath);
|
||||
|
||||
|
||||
}
|
@ -3,6 +3,11 @@ import 'dart:convert';
|
||||
import 'package:localstore/localstore.dart';
|
||||
|
||||
abstract class RequestCache<T> {
|
||||
static const int cacheNothing = 0;
|
||||
static const int cacheMinute = 60;
|
||||
static const int cacheHour = 60 * 60;
|
||||
static const int cacheDay = 60 * 60 * 24;
|
||||
|
||||
int maxCacheTime;
|
||||
Function(T) onUpdate;
|
||||
|
||||
@ -29,4 +34,5 @@ abstract class RequestCache<T> {
|
||||
|
||||
T onLocalData(String json);
|
||||
Future<T> onLoad();
|
||||
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
import 'package:marianum_mobile/api/apiRequest.dart';
|
||||
|
||||
class RequestLoginTest extends ApiRequest {
|
||||
RequestLoginTest(super.endpoint);
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/apiParams.dart';
|
||||
import 'package:marianum_mobile/api/apiParams.dart';
|
||||
|
||||
part 'authenticateParams.g.dart';
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/apiResponse.dart';
|
||||
import 'package:marianum_mobile/api/apiResponse.dart';
|
||||
|
||||
part 'authenticateResponse.g.dart';
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:marianum_mobile/api/webuntis/apiResponse.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:marianum_mobile/api/apiResponse.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/webuntisApi.dart';
|
||||
|
||||
import 'getHolidaysResponse.dart';
|
||||
@ -14,4 +16,17 @@ class GetHolidays extends WebuntisApi {
|
||||
return finalize(GetHolidaysResponse.fromJson(jsonDecode(rawAnswer)));
|
||||
}
|
||||
|
||||
static GetHolidaysResponseObject? find(GetHolidaysResponse holidaysResponse, {DateTime? time}) {
|
||||
time ??= DateTime.now();
|
||||
time = DateTime(time.year, time.month, time.day, 0, 0, 0, 0, 0);
|
||||
|
||||
for (var element in holidaysResponse.result) {
|
||||
DateTime start = DateTime.parse(element.startDate.toString());
|
||||
DateTime end = DateTime.parse(element.endDate.toString());
|
||||
|
||||
if(!start.isAfter(time) && !end.isBefore(time)) return element;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -5,8 +5,8 @@ import 'package:marianum_mobile/api/webuntis/queries/getHolidays/getHolidays.dar
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getHolidays/getHolidaysResponse.dart';
|
||||
|
||||
class GetHolidaysCache extends RequestCache<GetHolidaysResponse> {
|
||||
GetHolidaysCache({onUpdate}) : super(60 * 60, onUpdate) {
|
||||
start("holidays", "data");
|
||||
GetHolidaysCache({onUpdate}) : super(RequestCache.cacheDay, onUpdate) {
|
||||
start("MarianumMobile", "wu-holidays");
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/apiResponse.dart';
|
||||
import 'package:marianum_mobile/api/apiResponse.dart';
|
||||
|
||||
part 'getHolidaysResponse.g.dart';
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:marianum_mobile/api/webuntis/apiResponse.dart';
|
||||
import 'package:marianum_mobile/api/apiResponse.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/webuntisApi.dart';
|
||||
|
||||
import 'getRoomsResponse.dart';
|
||||
|
@ -6,8 +6,8 @@ import 'package:marianum_mobile/api/webuntis/queries/getRooms/getRoomsResponse.d
|
||||
import 'getRooms.dart';
|
||||
|
||||
class GetRoomsCache extends RequestCache<GetRoomsResponse> {
|
||||
GetRoomsCache({onUpdate}) : super(60 * 60, onUpdate) {
|
||||
start("rooms", "data");
|
||||
GetRoomsCache({onUpdate}) : super(RequestCache.cacheHour, onUpdate) {
|
||||
start("MarianumMobile", "wu-rooms");
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/apiResponse.dart';
|
||||
import 'package:marianum_mobile/api/apiResponse.dart';
|
||||
|
||||
part 'getRoomsResponse.g.dart';
|
||||
|
||||
@ -21,7 +21,6 @@ class GetRoomsResponseObject {
|
||||
bool active;
|
||||
String building;
|
||||
|
||||
|
||||
GetRoomsResponseObject(this.id, this.name, this.longName, this.active, this.building);
|
||||
|
||||
factory GetRoomsResponseObject.fromJson(Map<String, dynamic> json) => _$GetRoomsResponseObjectFromJson(json);
|
||||
|
@ -2,7 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:marianum_mobile/api/webuntis/webuntisApi.dart';
|
||||
|
||||
import '../../apiResponse.dart';
|
||||
import '../../../apiResponse.dart';
|
||||
import 'getSubjectsResponse.dart';
|
||||
|
||||
class GetSubjects extends WebuntisApi {
|
||||
|
@ -6,8 +6,8 @@ import 'package:marianum_mobile/api/webuntis/queries/getSubjects/getSubjectsResp
|
||||
import 'getSubjects.dart';
|
||||
|
||||
class GetSubjectsCache extends RequestCache<GetSubjectsResponse> {
|
||||
GetSubjectsCache({onUpdate}) : super(60 * 60, onUpdate) {
|
||||
start("subjects", "data");
|
||||
GetSubjectsCache({onUpdate}) : super(RequestCache.cacheHour, onUpdate) {
|
||||
start("MarianumMobile", "wu-subjects");
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/apiResponse.dart';
|
||||
import 'package:marianum_mobile/api/apiResponse.dart';
|
||||
|
||||
part 'getSubjectsResponse.g.dart';
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:marianum_mobile/api/webuntis/apiResponse.dart';
|
||||
import 'package:marianum_mobile/api/apiResponse.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/webuntisApi.dart';
|
||||
|
||||
import 'getTimetableParams.dart';
|
||||
|
@ -12,8 +12,8 @@ import 'getTimetableResponse.dart';
|
||||
class GetTimetableCache extends RequestCache<GetTimetableResponse> {
|
||||
int day;
|
||||
|
||||
GetTimetableCache({required onUpdate, required this.day}) : super(30, onUpdate) {
|
||||
start("timetable", "$day");
|
||||
GetTimetableCache({required onUpdate, required this.day}) : super(RequestCache.cacheMinute, onUpdate) {
|
||||
start("MarianumMobile", "wu-timetable-$day");
|
||||
}
|
||||
|
||||
@override
|
||||
@ -25,14 +25,18 @@ class GetTimetableCache extends RequestCache<GetTimetableResponse> {
|
||||
Future<GetTimetableResponse> onLoad() async {
|
||||
return GetTimetable(
|
||||
GetTimetableParams(
|
||||
options: GetTimetableParamsOptions(
|
||||
element: GetTimetableParamsOptionsElement(
|
||||
id: (await Authenticate.getSession()).personId,
|
||||
type: 5,
|
||||
keyType: GetTimetableParamsOptionsElementKeyType.id,
|
||||
),
|
||||
startDate: day,
|
||||
endDate: day,
|
||||
options: GetTimetableParamsOptions(
|
||||
element: GetTimetableParamsOptionsElement(
|
||||
id: (await Authenticate.getSession()).personId,
|
||||
type: 5,
|
||||
keyType: GetTimetableParamsOptionsElementKeyType.id,
|
||||
),
|
||||
startDate: day,
|
||||
endDate: day,
|
||||
teacherFields: GetTimetableParamsOptionsFields.all,
|
||||
subjectFields: GetTimetableParamsOptionsFields.all,
|
||||
roomFields: GetTimetableParamsOptionsFields.all,
|
||||
klasseFields: GetTimetableParamsOptionsFields.all,
|
||||
)
|
||||
)
|
||||
).run();
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/apiParams.dart';
|
||||
import 'package:marianum_mobile/api/apiParams.dart';
|
||||
|
||||
part 'getTimetableParams.g.dart';
|
||||
|
||||
@ -36,13 +36,13 @@ class GetTimetableParamsOptions {
|
||||
@JsonKey(includeIfNull: false)
|
||||
bool? showStudentgroup;
|
||||
@JsonKey(includeIfNull: false)
|
||||
GetTimetableParamsOptionsFields? klasseFields;
|
||||
List<GetTimetableParamsOptionsFields>? klasseFields;
|
||||
@JsonKey(includeIfNull: false)
|
||||
GetTimetableParamsOptionsFields? roomFields;
|
||||
List<GetTimetableParamsOptionsFields>? roomFields;
|
||||
@JsonKey(includeIfNull: false)
|
||||
GetTimetableParamsOptionsFields? subjectFields;
|
||||
List<GetTimetableParamsOptionsFields>? subjectFields;
|
||||
@JsonKey(includeIfNull: false)
|
||||
GetTimetableParamsOptionsFields? teacherFields;
|
||||
List<GetTimetableParamsOptionsFields>? teacherFields;
|
||||
|
||||
GetTimetableParamsOptions({
|
||||
required this.element,
|
||||
@ -69,7 +69,9 @@ enum GetTimetableParamsOptionsFields {
|
||||
@JsonValue("id") id,
|
||||
@JsonValue("name") name,
|
||||
@JsonValue("longname") longname,
|
||||
@JsonValue("externalkey") externalkey,
|
||||
@JsonValue("externalkey") externalkey;
|
||||
|
||||
static List<GetTimetableParamsOptionsFields> all = [id, name, longname, externalkey];
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
|
@ -31,14 +31,18 @@ GetTimetableParamsOptions _$GetTimetableParamsOptionsFromJson(
|
||||
showLsText: json['showLsText'] as bool?,
|
||||
showLsNumber: json['showLsNumber'] as bool?,
|
||||
showStudentgroup: json['showStudentgroup'] as bool?,
|
||||
klasseFields: $enumDecodeNullable(
|
||||
_$GetTimetableParamsOptionsFieldsEnumMap, json['klasseFields']),
|
||||
roomFields: $enumDecodeNullable(
|
||||
_$GetTimetableParamsOptionsFieldsEnumMap, json['roomFields']),
|
||||
subjectFields: $enumDecodeNullable(
|
||||
_$GetTimetableParamsOptionsFieldsEnumMap, json['subjectFields']),
|
||||
teacherFields: $enumDecodeNullable(
|
||||
_$GetTimetableParamsOptionsFieldsEnumMap, json['teacherFields']),
|
||||
klasseFields: (json['klasseFields'] as List<dynamic>?)
|
||||
?.map((e) => $enumDecode(_$GetTimetableParamsOptionsFieldsEnumMap, e))
|
||||
.toList(),
|
||||
roomFields: (json['roomFields'] as List<dynamic>?)
|
||||
?.map((e) => $enumDecode(_$GetTimetableParamsOptionsFieldsEnumMap, e))
|
||||
.toList(),
|
||||
subjectFields: (json['subjectFields'] as List<dynamic>?)
|
||||
?.map((e) => $enumDecode(_$GetTimetableParamsOptionsFieldsEnumMap, e))
|
||||
.toList(),
|
||||
teacherFields: (json['teacherFields'] as List<dynamic>?)
|
||||
?.map((e) => $enumDecode(_$GetTimetableParamsOptionsFieldsEnumMap, e))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GetTimetableParamsOptionsToJson(
|
||||
@ -62,14 +66,26 @@ Map<String, dynamic> _$GetTimetableParamsOptionsToJson(
|
||||
writeNotNull('showLsText', instance.showLsText);
|
||||
writeNotNull('showLsNumber', instance.showLsNumber);
|
||||
writeNotNull('showStudentgroup', instance.showStudentgroup);
|
||||
writeNotNull('klasseFields',
|
||||
_$GetTimetableParamsOptionsFieldsEnumMap[instance.klasseFields]);
|
||||
writeNotNull('roomFields',
|
||||
_$GetTimetableParamsOptionsFieldsEnumMap[instance.roomFields]);
|
||||
writeNotNull('subjectFields',
|
||||
_$GetTimetableParamsOptionsFieldsEnumMap[instance.subjectFields]);
|
||||
writeNotNull('teacherFields',
|
||||
_$GetTimetableParamsOptionsFieldsEnumMap[instance.teacherFields]);
|
||||
writeNotNull(
|
||||
'klasseFields',
|
||||
instance.klasseFields
|
||||
?.map((e) => _$GetTimetableParamsOptionsFieldsEnumMap[e]!)
|
||||
.toList());
|
||||
writeNotNull(
|
||||
'roomFields',
|
||||
instance.roomFields
|
||||
?.map((e) => _$GetTimetableParamsOptionsFieldsEnumMap[e]!)
|
||||
.toList());
|
||||
writeNotNull(
|
||||
'subjectFields',
|
||||
instance.subjectFields
|
||||
?.map((e) => _$GetTimetableParamsOptionsFieldsEnumMap[e]!)
|
||||
.toList());
|
||||
writeNotNull(
|
||||
'teacherFields',
|
||||
instance.teacherFields
|
||||
?.map((e) => _$GetTimetableParamsOptionsFieldsEnumMap[e]!)
|
||||
.toList());
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/apiResponse.dart';
|
||||
import 'package:marianum_mobile/api/apiResponse.dart';
|
||||
|
||||
part 'getTimetableResponse.g.dart';
|
||||
|
||||
|
@ -3,19 +3,20 @@ import 'dart:developer';
|
||||
import 'package:marianum_mobile/api/apiRequest.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:marianum_mobile/api/webuntis/webuntisError.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/apiResponse.dart';
|
||||
import 'package:marianum_mobile/api/apiResponse.dart';
|
||||
|
||||
import 'apiParams.dart';
|
||||
import '../apiParams.dart';
|
||||
import 'queries/authenticate/authenticate.dart';
|
||||
|
||||
abstract class WebuntisApi extends ApiRequest {
|
||||
Uri endpoint = Uri.parse("https://peleus.webuntis.com/WebUntis/jsonrpc.do?school=marianum-fulda");
|
||||
String method;
|
||||
ApiParams? genericParam;
|
||||
http.Response? response;
|
||||
|
||||
bool authenticatedResponse;
|
||||
|
||||
WebuntisApi(this.method, this.genericParam, {this.authenticatedResponse = true}) : super(Uri.parse("https://peleus.webuntis.com/WebUntis/jsonrpc.do?school=marianum-fulda"));
|
||||
WebuntisApi(this.method, this.genericParam, {this.authenticatedResponse = true});
|
||||
|
||||
|
||||
Future<String> query(WebuntisApi untis) async {
|
||||
@ -50,4 +51,14 @@ abstract class WebuntisApi extends ApiRequest {
|
||||
String _body() {
|
||||
return genericParam == null ? "{}" : jsonEncode(genericParam);
|
||||
}
|
||||
|
||||
Future<http.Response> post(String data, Map<String, String>? headers) async {
|
||||
log("POST: $endpoint\n$data");
|
||||
return await http
|
||||
.post(endpoint, body: data, headers: headers)
|
||||
.timeout(
|
||||
const Duration(seconds: 10),
|
||||
onTimeout: () => throw WebuntisError("Timeout", 1)
|
||||
);
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ class WebuntisError {
|
||||
|
||||
WebuntisError(this.message, this.code);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "WebUntis ($code): $message";
|
||||
}
|
||||
|
50
lib/app.dart
50
lib/app.dart
@ -1,6 +1,6 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:marianum_mobile/screen/pages/timetable/storedTimetable.dart';
|
||||
import 'package:marianum_mobile/screen/pages/timetable/timetable.dart';
|
||||
import 'package:marianum_mobile/screen/pages/timetable/testTimetable.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
@ -8,8 +8,8 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'dataOld/incommingPackets/talkNotificationsPacket.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/pages/talk/chatList.dart';
|
||||
import 'screen/pages/timetable/timetableOld.dart';
|
||||
import 'screen/settings/settings.dart';
|
||||
|
||||
class App extends StatefulWidget {
|
||||
@ -26,6 +26,7 @@ class _AppState extends State<App> {
|
||||
Widget build(BuildContext context) {
|
||||
final PageController pageController = PageController();
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: AppBar(
|
||||
title: const Text("Marianum Fulda"),
|
||||
actions: <Widget>[
|
||||
@ -38,27 +39,32 @@ class _AppState extends State<App> {
|
||||
)
|
||||
],
|
||||
),
|
||||
body: Stack(
|
||||
body: Column(
|
||||
children: [
|
||||
PageView(
|
||||
controller: pageController,
|
||||
children: const [
|
||||
StoredTimetable(),
|
||||
Talk(),
|
||||
Files(),
|
||||
Overhang(),
|
||||
],
|
||||
onPageChanged: (page) {
|
||||
setState(() {
|
||||
currentPage = page;
|
||||
});
|
||||
},
|
||||
Visibility(
|
||||
visible: false,
|
||||
child: LinearProgressIndicator(
|
||||
backgroundColor: Colors.transparent,
|
||||
valueColor: AlwaysStoppedAnimation(Theme.of(context).primaryColor),
|
||||
minHeight: 5,
|
||||
),
|
||||
),
|
||||
// LinearProgressIndicator(
|
||||
// backgroundColor: Colors.transparent,
|
||||
// valueColor: AlwaysStoppedAnimation(Theme.of(context).primaryColor),
|
||||
// minHeight: 5,
|
||||
// ),
|
||||
Flexible(
|
||||
child: PageView(
|
||||
controller: pageController,
|
||||
children: [
|
||||
Timetable(),
|
||||
ChatList(),
|
||||
Files(),
|
||||
Overhang(),
|
||||
],
|
||||
onPageChanged: (page) {
|
||||
setState(() {
|
||||
currentPage = page;
|
||||
});
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
||||
|
29
lib/data/chatList/chatListProps.dart
Normal file
29
lib/data/chatList/chatListProps.dart
Normal file
@ -0,0 +1,29 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:marianum_mobile/api/marianumcloud/talk/room/getRoomCache.dart';
|
||||
import 'package:marianum_mobile/api/marianumcloud/talk/room/getRoomResponse.dart';
|
||||
import 'package:marianum_mobile/data/dataHolder.dart';
|
||||
|
||||
import '../../api/apiResponse.dart';
|
||||
|
||||
class ChatListProps extends DataHolder {
|
||||
GetRoomResponse? _getRoomResponse;
|
||||
GetRoomResponse get getRoomsResponse => _getRoomResponse!;
|
||||
|
||||
@override
|
||||
List<ApiResponse?> properties() {
|
||||
return [_getRoomResponse];
|
||||
}
|
||||
|
||||
@override
|
||||
void run() {
|
||||
log("RUN CACHE");
|
||||
GetRoomCache(
|
||||
onUpdate: (GetRoomResponse data) => {
|
||||
_getRoomResponse = data,
|
||||
notifyListeners(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
35
lib/data/chatList/chatProps.dart
Normal file
35
lib/data/chatList/chatProps.dart
Normal file
@ -0,0 +1,35 @@
|
||||
import 'package:marianum_mobile/api/apiResponse.dart';
|
||||
import 'package:marianum_mobile/api/marianumcloud/talk/chat/getChatCache.dart';
|
||||
import 'package:marianum_mobile/api/marianumcloud/talk/chat/getChatResponse.dart';
|
||||
import 'package:marianum_mobile/data/dataHolder.dart';
|
||||
|
||||
class ChatProps extends DataHolder {
|
||||
String _queryToken = "";
|
||||
|
||||
GetChatResponse? _getChatResponse;
|
||||
GetChatResponse get getChatResponse => _getChatResponse!;
|
||||
|
||||
@override
|
||||
List<ApiResponse?> properties() {
|
||||
return [_getChatResponse];
|
||||
}
|
||||
|
||||
@override
|
||||
void run() {
|
||||
notifyListeners();
|
||||
GetChatCache(
|
||||
chatToken: _queryToken,
|
||||
onUpdate: (GetChatResponse data) => {
|
||||
_getChatResponse = data,
|
||||
notifyListeners(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void setQueryToken(String token) {
|
||||
_queryToken = token;
|
||||
_getChatResponse = null;
|
||||
run();
|
||||
}
|
||||
|
||||
}
|
@ -1,11 +1,18 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:localstore/localstore.dart';
|
||||
|
||||
import '../api/apiResponse.dart';
|
||||
|
||||
abstract class DataHolder extends ChangeNotifier {
|
||||
|
||||
CollectionRef storage(String path) {
|
||||
return Localstore.instance.collection(path);
|
||||
}
|
||||
|
||||
Future<void> run();
|
||||
void run();
|
||||
List<ApiResponse?> properties();
|
||||
|
||||
bool primaryLoading() {
|
||||
return properties().where((element) => element != null).isEmpty;
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:path/path.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
class PersistantTimetable {
|
||||
final int id;
|
||||
final String json;
|
||||
|
||||
PersistantTimetable(this.id, this.json);
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
import 'dart:collection';
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/authenticate/authenticate.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/authenticate/authenticateResponse.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getRooms/getRoomsCache.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getRooms/getRoomsResponse.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getSubjects/getSubjectsCache.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getSubjects/getSubjectsResponse.dart';
|
||||
import 'package:marianum_mobile/data/dataHolder.dart';
|
||||
|
||||
import '../../api/webuntis/queries/getTimetable/getTimetable.dart';
|
||||
import '../../api/webuntis/queries/getTimetable/getTimetableCache.dart';
|
||||
import '../../api/webuntis/queries/getTimetable/getTimetableParams.dart';
|
||||
import '../../api/webuntis/queries/getTimetable/getTimetableResponse.dart';
|
||||
|
||||
class Timetable extends DataHolder {
|
||||
int day = int.parse(DateFormat("yyyyMMdd").format(DateTime.now()));
|
||||
|
||||
Timetable() : super();
|
||||
|
||||
GetTimetableResponse? _getTimetableResponse;
|
||||
GetTimetableResponse? get getTimetableResponse => _getTimetableResponse;
|
||||
|
||||
GetRoomsResponse? _getRoomsResponse;
|
||||
GetRoomsResponse? get getRoomsResponse => _getRoomsResponse;
|
||||
|
||||
GetSubjectsResponse? _getSubjectsResponse;
|
||||
GetSubjectsResponse? get getSubjectsResponse => _getSubjectsResponse;
|
||||
|
||||
@override
|
||||
Future<void> run() async {
|
||||
GetTimetableCache(
|
||||
day: day,
|
||||
onUpdate: (data) =>
|
||||
{
|
||||
_getTimetableResponse = data,
|
||||
notifyListeners(),
|
||||
}
|
||||
);
|
||||
|
||||
GetRoomsCache(
|
||||
onUpdate: (data) =>
|
||||
{
|
||||
_getRoomsResponse = data,
|
||||
notifyListeners(),
|
||||
}
|
||||
);
|
||||
|
||||
GetSubjectsCache(
|
||||
onUpdate: (data) =>
|
||||
{
|
||||
_getSubjectsResponse = data,
|
||||
notifyListeners(),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
101
lib/data/timetable/timetableProps.dart
Normal file
101
lib/data/timetable/timetableProps.dart
Normal file
@ -0,0 +1,101 @@
|
||||
import 'dart:collection';
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:marianum_mobile/api/apiResponse.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/authenticate/authenticate.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/authenticate/authenticateResponse.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getHolidays/getHolidaysCache.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getHolidays/getHolidaysResponse.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getRooms/getRoomsCache.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getRooms/getRoomsResponse.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getSubjects/getSubjectsCache.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getSubjects/getSubjectsResponse.dart';
|
||||
import 'package:marianum_mobile/data/dataHolder.dart';
|
||||
|
||||
import '../../api/webuntis/queries/getTimetable/getTimetable.dart';
|
||||
import '../../api/webuntis/queries/getTimetable/getTimetableCache.dart';
|
||||
import '../../api/webuntis/queries/getTimetable/getTimetableParams.dart';
|
||||
import '../../api/webuntis/queries/getTimetable/getTimetableResponse.dart';
|
||||
|
||||
class TimetableProps extends DataHolder {
|
||||
late DateTime queryDate;
|
||||
|
||||
GetTimetableResponse? _getTimetableResponse;
|
||||
GetTimetableResponse get getTimetableResponse => _getTimetableResponse!;
|
||||
|
||||
GetRoomsResponse? _getRoomsResponse;
|
||||
GetRoomsResponse get getRoomsResponse => _getRoomsResponse!;
|
||||
|
||||
GetSubjectsResponse? _getSubjectsResponse;
|
||||
GetSubjectsResponse get getSubjectsResponse => _getSubjectsResponse!;
|
||||
|
||||
GetHolidaysResponse? _getHolidaysResponse;
|
||||
GetHolidaysResponse get getHolidaysResponse => _getHolidaysResponse!;
|
||||
|
||||
|
||||
TimetableProps() {
|
||||
nearest();
|
||||
}
|
||||
|
||||
@override
|
||||
List<ApiResponse?> properties() {
|
||||
return [_getTimetableResponse, _getRoomsResponse, _getSubjectsResponse, _getHolidaysResponse];
|
||||
}
|
||||
|
||||
@override
|
||||
void run() {
|
||||
GetTimetableCache(
|
||||
day: int.parse(DateFormat("yyyyMMdd").format(queryDate)),
|
||||
onUpdate: (GetTimetableResponse data) => {
|
||||
_getTimetableResponse = data,
|
||||
notifyListeners(),
|
||||
}
|
||||
);
|
||||
|
||||
GetRoomsCache(
|
||||
onUpdate: (GetRoomsResponse data) => {
|
||||
_getRoomsResponse = data,
|
||||
notifyListeners(),
|
||||
}
|
||||
);
|
||||
|
||||
GetSubjectsCache(
|
||||
onUpdate: (GetSubjectsResponse data) => {
|
||||
_getSubjectsResponse = data,
|
||||
notifyListeners(),
|
||||
}
|
||||
);
|
||||
|
||||
GetHolidaysCache(
|
||||
onUpdate: (GetHolidaysResponse data) => {
|
||||
_getHolidaysResponse = data,
|
||||
notifyListeners(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void nearest() {
|
||||
queryDate = DateTime.now();
|
||||
while(isWeekend(queryDate)) {
|
||||
next();
|
||||
}
|
||||
run();
|
||||
}
|
||||
|
||||
void next({previous = false}) {
|
||||
do {
|
||||
if(previous) {
|
||||
queryDate = queryDate.subtract(const Duration(days: 1));
|
||||
} else {
|
||||
queryDate = queryDate.add(const Duration(days: 1));
|
||||
}
|
||||
} while(isWeekend(queryDate));
|
||||
run();
|
||||
}
|
||||
|
||||
bool isWeekend(DateTime queryDate) {
|
||||
return queryDate.weekday == DateTime.saturday || queryDate.weekday == DateTime.sunday;
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:marianum_mobile/data/timetable/timetable.dart';
|
||||
import 'package:marianum_mobile/data/timetable/timetableProps.dart';
|
||||
import 'package:marianum_mobile/screen/login/login.dart';
|
||||
import 'package:marianum_mobile/widget/loadingSpinner.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
@ -10,6 +10,8 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||
|
||||
import 'app.dart';
|
||||
import 'data/chatList/chatListProps.dart';
|
||||
import 'data/chatList/chatProps.dart';
|
||||
import 'dataOld/accountModel.dart';
|
||||
import 'dataOld/incommingPackets/authenticatePacket.dart';
|
||||
import 'dataOld/incommingPackets/errorPacket.dart';
|
||||
@ -39,7 +41,9 @@ Future<void> main() async {
|
||||
// ChangeNotifierProvider(create: (context) => FileListPacket()),
|
||||
// ChangeNotifierProvider(create: (context) => TalkChatPacket()),
|
||||
// ChangeNotifierProvider(create: (context) => TimetablePacket()),
|
||||
ChangeNotifierProvider(create: (context) => Timetable()),
|
||||
ChangeNotifierProvider(create: (context) => TimetableProps()),
|
||||
ChangeNotifierProvider(create: (context) => ChatListProps()),
|
||||
ChangeNotifierProvider(create: (context) => ChatProps()),
|
||||
],
|
||||
child: const Main(),
|
||||
)
|
||||
@ -54,7 +58,7 @@ class Main extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _MainState extends State<Main> {
|
||||
static const Color red = Color.fromARGB(255, 153, 51, 51);
|
||||
static const Color marianumRed = Color.fromARGB(255, 153, 51, 51);
|
||||
|
||||
final Future<SharedPreferences> _storage = SharedPreferences.getInstance();
|
||||
|
||||
@ -79,12 +83,16 @@ class _MainState extends State<Main> {
|
||||
title: 'Marianum Fulda',
|
||||
theme: ThemeData(
|
||||
brightness: Brightness.light,
|
||||
primaryColor: red,
|
||||
primaryColor: marianumRed,
|
||||
hintColor: marianumRed,
|
||||
inputDecorationTheme: const InputDecorationTheme(
|
||||
border: UnderlineInputBorder(borderSide: BorderSide(color: marianumRed)),
|
||||
),
|
||||
appBarTheme: const AppBarTheme(
|
||||
backgroundColor: red,
|
||||
backgroundColor: marianumRed,
|
||||
),
|
||||
progressIndicatorTheme: const ProgressIndicatorThemeData(
|
||||
color: red,
|
||||
color: marianumRed,
|
||||
),
|
||||
),
|
||||
|
||||
@ -93,30 +101,16 @@ class _MainState extends State<Main> {
|
||||
builder: (BuildContext context, AsyncSnapshot<SharedPreferences> snapshot) {
|
||||
|
||||
if(snapshot.hasData) {
|
||||
|
||||
return Consumer2<AccountModel, ErrorPacket>(
|
||||
builder: (context, accountModel, errorPacket, child) {
|
||||
if(errorPacket.errorDismissed) {
|
||||
return accountModel.isLoggedIn ? const App() : const Login();
|
||||
} else {
|
||||
return AlertDialog(title: const Text("Serverseitige Fehlermeldung"), content: Text(errorPacket.errorText), actions: [
|
||||
TextButton(onPressed: () {
|
||||
Provider.of<ErrorPacket>(context, listen: false).errorDismissed = true;
|
||||
}, child: const Text("Weiter"))
|
||||
]);
|
||||
}
|
||||
return Consumer<AccountModel>(
|
||||
builder: (context, accountModel, child) {
|
||||
return accountModel.isLoggedIn ? const App() : const Login();
|
||||
},
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
return const LoadingSpinner();
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
)
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
101
lib/screen/pages/talk/chatList.dart
Normal file
101
lib/screen/pages/talk/chatList.dart
Normal file
@ -0,0 +1,101 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:jiffy/jiffy.dart';
|
||||
import 'package:marianum_mobile/api/marianumcloud/talk/room/getRoomResponse.dart';
|
||||
import 'package:marianum_mobile/data/chatList/chatListProps.dart';
|
||||
import 'package:marianum_mobile/widget/loadingPacket.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'chatView.dart';
|
||||
|
||||
class ChatList extends StatefulWidget {
|
||||
const ChatList({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<ChatList> createState() => _ChatListState();
|
||||
}
|
||||
|
||||
class _ChatListState extends State<ChatList> {
|
||||
late String username;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
SharedPreferences.getInstance().then((value) => {
|
||||
username = value.getString("username")!
|
||||
});
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
Provider.of<ChatListProps>(context, listen: false).run();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return Consumer<ChatListProps>(
|
||||
builder: (context, data, child) {
|
||||
|
||||
if(data.primaryLoading()) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
List<ListTile> chats = List<ListTile>.empty(growable: true);
|
||||
|
||||
for (var chatRoom in data.getRoomsResponse.sortByLastActivity()) {
|
||||
|
||||
CircleAvatar _circleAvatar = CircleAvatar(
|
||||
foregroundImage: chatRoom.type == GetRoomResponseObjectConversationType.oneToOne ? Image.network("https://cloud.marianum-fulda.de/avatar/${chatRoom.name}/128").image : null,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
foregroundColor: Colors.white,
|
||||
child: chatRoom.type == GetRoomResponseObjectConversationType.group ? const Icon(Icons.group) : const Icon(Icons.person),
|
||||
);
|
||||
|
||||
chats.add(ListTile(
|
||||
title: Text(chatRoom.displayName),
|
||||
subtitle: Text("${Jiffy.unixFromSecondsSinceEpoch(chatRoom.lastMessage.timestamp).fromNow()}: ${chatRoom.lastMessage.message.replaceAll("\n", " ")}", overflow: TextOverflow.ellipsis),
|
||||
trailing: Visibility(
|
||||
visible: chatRoom.unreadMessages > 0,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(1),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).primaryColor,
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
),
|
||||
constraints: const BoxConstraints(
|
||||
minWidth: 20,
|
||||
minHeight: 20,
|
||||
),
|
||||
child: Text(
|
||||
"${chatRoom.unreadMessages}",
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 15,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
leading: _circleAvatar,
|
||||
onTap: () async {
|
||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
|
||||
return ChatView(
|
||||
user: chatRoom,
|
||||
selfId: username,
|
||||
avatar: _circleAvatar,
|
||||
);
|
||||
}));
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
return ListView(children: chats);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:marianum_mobile/widget/loadingPacket.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../../dataOld/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,
|
||||
// );
|
||||
// }
|
||||
// }
|
@ -1,14 +1,18 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:bubble/bubble.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:marianum_mobile/widget/loadingPacket.dart';
|
||||
import 'package:jiffy/jiffy.dart';
|
||||
import 'package:marianum_mobile/api/marianumcloud/talk/room/getRoomResponse.dart';
|
||||
import 'package:marianum_mobile/data/chatList/chatProps.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../../dataOld/incommingPackets/talkChatPacket.dart';
|
||||
|
||||
class ChatView extends StatefulWidget {
|
||||
final String userToken;
|
||||
const ChatView({Key? key, required this.userToken}) : super(key: key);
|
||||
final GetRoomResponseObject user;
|
||||
final String selfId;
|
||||
final CircleAvatar avatar;
|
||||
|
||||
const ChatView({Key? key, required this.user, required this.selfId, required this.avatar}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<ChatView> createState() => _ChatViewState();
|
||||
@ -16,7 +20,7 @@ class ChatView extends StatefulWidget {
|
||||
|
||||
class _ChatViewState extends State<ChatView> {
|
||||
static const styleSystem = BubbleStyle(
|
||||
color: Color.fromRGBO(212, 234, 244, 1.0),
|
||||
color: Color(0xffd4eaf4),
|
||||
borderWidth: 1,
|
||||
elevation: 2,
|
||||
margin: BubbleEdges.only(top: 15),
|
||||
@ -24,79 +28,151 @@ class _ChatViewState extends State<ChatView> {
|
||||
);
|
||||
|
||||
static const styleOther = BubbleStyle(
|
||||
nip: BubbleNip.leftBottom,
|
||||
nip: BubbleNip.leftTop,
|
||||
color: Colors.white,
|
||||
borderWidth: 1,
|
||||
elevation: 2,
|
||||
margin: BubbleEdges.only(top: 15, left: 10),
|
||||
elevation: 1,
|
||||
margin: BubbleEdges.only(top: 15, left: 10, right: 50),
|
||||
alignment: Alignment.topLeft,
|
||||
);
|
||||
|
||||
static const styleSelf = BubbleStyle(
|
||||
nip: BubbleNip.rightBottom,
|
||||
color: Color.fromRGBO(225, 255, 199, 1.0),
|
||||
color: Color(0xffd9fdd3),
|
||||
borderWidth: 1,
|
||||
elevation: 2,
|
||||
margin: BubbleEdges.only(top: 15, right: 10),
|
||||
elevation: 1,
|
||||
margin: BubbleEdges.only(top: 15, right: 10, left: 50),
|
||||
alignment: Alignment.topRight,
|
||||
);
|
||||
|
||||
final ScrollController _listController = ScrollController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
Provider.of<TalkChatPacket>(context, listen: false).invoke(
|
||||
data: {
|
||||
"token": widget.userToken
|
||||
},
|
||||
indicateLoading: true,
|
||||
allowNotifyListeners: false,
|
||||
);
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
Provider.of<ChatProps>(context, listen: false).setQueryToken(widget.user.token);
|
||||
});
|
||||
}
|
||||
|
||||
@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);
|
||||
return Consumer<ChatProps>(
|
||||
builder: (context, data, child) {
|
||||
List<Bubble> messages = List<Bubble>.empty(growable: true);
|
||||
|
||||
if(!data.primaryLoading()) {
|
||||
String lastActor = "";
|
||||
bool showMetadata = true;
|
||||
|
||||
data.getChatResponse.sortByTimestamp().forEach((element) {
|
||||
|
||||
showMetadata = element.messageType == GetRoomResponseObjectMessageType.comment;
|
||||
|
||||
BubbleStyle currentStyle;
|
||||
if(element.messageType == GetRoomResponseObjectMessageType.comment) {
|
||||
if(element.actorId == widget.selfId) {
|
||||
currentStyle = styleSelf;
|
||||
} else {
|
||||
currentStyle = styleOther;
|
||||
}
|
||||
} else {
|
||||
currentStyle = styleSystem;
|
||||
}
|
||||
|
||||
|
||||
data.messages.forEach((element) {
|
||||
messages.add(Bubble(
|
||||
style: styleSelf,
|
||||
child: Text(element.content),
|
||||
margin: BubbleEdges.only(bottom: element == data.getChatResponse.sortByTimestamp().last ? 20 : 0),
|
||||
|
||||
style: currentStyle,
|
||||
child: Stack(
|
||||
children: [
|
||||
Visibility(
|
||||
visible: showMetadata,
|
||||
child: Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
child: Text("${element.actorDisplayName}", style: TextStyle(fontWeight: FontWeight.bold, color: Theme.of(context).primaryColor)),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: showMetadata ? 18 : 0),
|
||||
child: Text(element.message),
|
||||
),
|
||||
Visibility(
|
||||
visible: showMetadata,
|
||||
child: Positioned(
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
child: Text(
|
||||
"${Jiffy.unixFromSecondsSinceEpoch(element.timestamp).yMMMMd} - ${Jiffy.unixFromSecondsSinceEpoch(element.timestamp).format("HH:mm")}",
|
||||
style: TextStyle(color: Theme.of(context).disabledColor),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
));
|
||||
|
||||
lastActor = element.actorId;
|
||||
});
|
||||
}
|
||||
|
||||
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),
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xffefeae2),
|
||||
appBar: AppBar(
|
||||
title: Row(
|
||||
children: [
|
||||
widget.avatar,
|
||||
const SizedBox(width: 10),
|
||||
Text(widget.user.displayName, overflow: TextOverflow.ellipsis, maxLines: 1),
|
||||
],
|
||||
),
|
||||
),
|
||||
body: Container(
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage("assets/background/chat.png"),
|
||||
scale: 1.5,
|
||||
opacity: 0.5,
|
||||
repeat: ImageRepeat.repeat,
|
||||
colorFilter: ColorFilter.linearToSrgbGamma()
|
||||
)
|
||||
),
|
||||
child: data.primaryLoading() ? const Center(child: CircularProgressIndicator()) : Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ListView(
|
||||
reverse: true,
|
||||
controller: _listController,
|
||||
children: messages.reversed.toList(),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
color: Theme.of(context).dividerColor,
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Row(
|
||||
children: [
|
||||
const Expanded(
|
||||
child: TextField(
|
||||
maxLines: null,
|
||||
decoration: InputDecoration(
|
||||
hintText: "Nachricht",
|
||||
border: OutlineInputBorder(),
|
||||
labelText: "",
|
||||
),
|
||||
),
|
||||
),
|
||||
IconButton(onPressed: () {}, icon: const Icon(Icons.send))
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
139
lib/screen/pages/timetable/dayListView.dart
Normal file
139
lib/screen/pages/timetable/dayListView.dart
Normal file
@ -0,0 +1,139 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:jiffy/jiffy.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getHolidays/getHolidaysResponse.dart';
|
||||
import 'package:timetable_view/timetable_view.dart';
|
||||
|
||||
import '../../../api/webuntis/queries/getHolidays/getHolidays.dart';
|
||||
import '../../../api/webuntis/queries/getRooms/getRoomsResponse.dart';
|
||||
import '../../../api/webuntis/queries/getSubjects/getSubjectsResponse.dart';
|
||||
import '../../../api/webuntis/queries/getTimetable/getTimetableResponse.dart';
|
||||
import '../../../data/timetable/timetableProps.dart';
|
||||
|
||||
class DayListView extends StatefulWidget {
|
||||
final TimetableProps value;
|
||||
const DayListView(this.value, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<DayListView> createState() => _DayListViewState();
|
||||
}
|
||||
|
||||
class _DayListViewState extends State<DayListView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TimetableView(
|
||||
laneEventsList: _buildLaneEvents(widget.value),
|
||||
onEventTap: (TableEvent event) {},
|
||||
timetableStyle: CustomTableStyle(context),
|
||||
onEmptySlotTap: (int laneIndex, TableEventTime start, TableEventTime end) => {},
|
||||
);
|
||||
}
|
||||
|
||||
List<LaneEvents> _buildLaneEvents(TimetableProps data) {
|
||||
List<LaneEvents> laneEvents = List<LaneEvents>.empty(growable: true);
|
||||
Jiffy.locale("de"); // todo move outwards
|
||||
|
||||
GetTimetableResponse timetable = data.getTimetableResponse;
|
||||
GetRoomsResponse rooms = data.getRoomsResponse;
|
||||
GetSubjectsResponse subjects = data.getSubjectsResponse;
|
||||
GetHolidaysResponse holidays = data.getHolidaysResponse;
|
||||
|
||||
GetHolidaysResponseObject? holidayInfo = GetHolidays.find(holidays, time: data.queryDate);
|
||||
if(holidayInfo != null) {
|
||||
laneEvents.add(
|
||||
LaneEvents(
|
||||
lane: Lane(
|
||||
laneIndex: data.queryDate.millisecondsSinceEpoch,
|
||||
name: "${Jiffy(data.queryDate.toString()).format("dd.MM.yy")}\n${Jiffy(data.queryDate.toString()).format("EEEE")}",
|
||||
textStyle: TextStyle(
|
||||
color: Theme.of(context).primaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14
|
||||
)
|
||||
),
|
||||
events: List<TableEvent>.of([
|
||||
TableEvent(
|
||||
title: holidayInfo.name,
|
||||
eventId: holidayInfo.id,
|
||||
laneIndex: data.queryDate.millisecondsSinceEpoch,
|
||||
startTime: parseTime(0800),
|
||||
endTime: parseTime(1500),
|
||||
padding: const EdgeInsets.all(5),
|
||||
backgroundColor: Theme.of(context).disabledColor,
|
||||
location: "\n${holidayInfo.longName}",
|
||||
)
|
||||
]),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
List<int> dayList = timetable.result.map((e) => e.date).toSet().toList();
|
||||
dayList.sort((a, b) => a-b);
|
||||
dayList.forEach((day) {
|
||||
//Every Day
|
||||
laneEvents.add(
|
||||
LaneEvents(
|
||||
lane: Lane(
|
||||
laneIndex: day,
|
||||
name: "${Jiffy(day.toString()).format("dd.MM.yy")}\n${Jiffy(day.toString()).format("EEEE")}",
|
||||
textStyle: TextStyle(
|
||||
color: Theme.of(context).primaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14
|
||||
)
|
||||
),
|
||||
events: List<TableEvent>.generate(
|
||||
timetable.result.where((element) => element.date == day).length,
|
||||
(index) {
|
||||
GetTimetableResponseObject tableEvent = timetable.result.where((element) => element.date == day).elementAt(index);
|
||||
|
||||
GetSubjectsResponseObject subject = subjects.result.firstWhere((subject) => subject.id == tableEvent.su[0]['id']);
|
||||
|
||||
return TableEvent(
|
||||
title: "${subject.alternateName} (${subject.longName})",
|
||||
eventId: tableEvent.id,
|
||||
laneIndex: day,
|
||||
startTime: parseTime(tableEvent.startTime),
|
||||
endTime: parseTime(tableEvent.endTime),
|
||||
padding: const EdgeInsets.all(5),
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
location: "\n${rooms.result.firstWhere((room) => room.id == tableEvent.ro[0]['id']).name} - ${tableEvent.te[0]['longname']} (${tableEvent.te[0]['name']})",
|
||||
);
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
return laneEvents;
|
||||
}
|
||||
|
||||
TableEventTime parseTime(int input) {
|
||||
String time = input.toString().length < 4 ? "0$input" : input.toString();
|
||||
return TableEventTime(hour: int.parse(time.substring(0, 2)), minute: int.parse(time.substring(2, 4)));
|
||||
}
|
||||
}
|
||||
|
||||
class CustomTableStyle extends TimetableStyle {
|
||||
dynamic context;
|
||||
CustomTableStyle(this.context);
|
||||
|
||||
@override
|
||||
int get startHour => 07;
|
||||
@override
|
||||
int get endHour => 17;
|
||||
@override
|
||||
Color get cornerColor => Theme.of(context).primaryColor;
|
||||
@override
|
||||
Color get timeItemTextColor => Theme.of(context).primaryColor;
|
||||
@override
|
||||
double get timeItemHeight => 70;
|
||||
@override
|
||||
double get timeItemWidth => 50;
|
||||
@override
|
||||
double get laneWidth => MediaQuery.of(context).size.width - timeItemWidth;
|
||||
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:jiffy/jiffy.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getRooms/getRoomsResponse.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getSubjects/getSubjectsResponse.dart';
|
||||
import 'package:marianum_mobile/data/timetable/timetable.dart';
|
||||
import 'package:marianum_mobile/screen/pages/timetable/testTimetable.dart';
|
||||
import 'package:marianum_mobile/widget/loadingSpinner.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:timetable_view/timetable_view.dart';
|
||||
|
||||
import '../../../api/webuntis/queries/getTimetable/getTimetableResponse.dart';
|
||||
|
||||
class StoredTimetable extends StatefulWidget {
|
||||
const StoredTimetable({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StoredTimetable> createState() => _StoredTimetableState();
|
||||
}
|
||||
|
||||
class _StoredTimetableState extends State<StoredTimetable> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
Provider.of<Timetable>(context, listen: false).run();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<Timetable>(
|
||||
builder: (context, value, child) {
|
||||
if(value.getTimetableResponse == null) {
|
||||
return const LoadingSpinner();
|
||||
}
|
||||
|
||||
return TimetableView(
|
||||
laneEventsList: _buildLaneEvents(value),
|
||||
onEventTap: (TableEvent event) {},
|
||||
timetableStyle: CustomTableStyle(context),
|
||||
onEmptySlotTap: (int laneIndex, TableEventTime start, TableEventTime end) => {},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
List<LaneEvents> _buildLaneEvents(Timetable data) {
|
||||
List<LaneEvents> laneEvents = List<LaneEvents>.empty(growable: true);
|
||||
Jiffy.locale("de"); // todo move outwards
|
||||
|
||||
GetTimetableResponse timetable = data.getTimetableResponse!;
|
||||
GetRoomsResponse rooms = data.getRoomsResponse!;
|
||||
GetSubjectsResponse subjects = data.getSubjectsResponse!;
|
||||
|
||||
List<int> dayList = timetable.result.map((e) => e.date).toSet().toList();
|
||||
dayList.sort((a, b) => a-b);
|
||||
dayList.forEach((day) {
|
||||
//Every Day
|
||||
|
||||
laneEvents.add(
|
||||
LaneEvents(
|
||||
lane: Lane(
|
||||
laneIndex: day,
|
||||
name: "${Jiffy(day.toString()).format("dd.MM.yy")}\n${Jiffy(day.toString()).format("EEEE")}",
|
||||
textStyle: TextStyle(
|
||||
color: Theme.of(context).primaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14
|
||||
)
|
||||
),
|
||||
events: List<TableEvent>.generate(
|
||||
timetable.result.where((element) => element.date == day).length,
|
||||
(index) {
|
||||
GetTimetableResponseObject tableEvent = timetable.result.where((element) => element.date == day).elementAt(index);
|
||||
return TableEvent(
|
||||
title: subjects.result.firstWhere((subject) => subject.id == tableEvent.su[0]['id']).longName,
|
||||
eventId: tableEvent.id,
|
||||
laneIndex: day,
|
||||
startTime: parseTime(tableEvent.startTime),
|
||||
endTime: parseTime(tableEvent.endTime),
|
||||
padding: const EdgeInsets.all(5),
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
location: "\n${rooms.result.firstWhere((room) => room.id == tableEvent.ro[0]['id']).name}",
|
||||
);
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
return laneEvents;
|
||||
}
|
||||
|
||||
TableEventTime parseTime(int input) {
|
||||
String time = input.toString().length < 4 ? "0$input" : input.toString();
|
||||
return TableEventTime(hour: int.parse(time.substring(0, 2)), minute: int.parse(time.substring(2, 4)));
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:jiffy/jiffy.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getRooms/getRooms.dart';
|
||||
import 'package:marianum_mobile/data/timetable/timetableProps.dart';
|
||||
import 'package:marianum_mobile/widget/loadingSpinner.dart';
|
||||
import 'package:marianum_mobile/widget/offlineError.dart';
|
||||
import 'package:timetable_view/timetable_view.dart';
|
||||
@ -131,14 +132,14 @@ class CustomTableStyle extends TimetableStyle {
|
||||
@override
|
||||
int get endHour => 17;
|
||||
@override
|
||||
double get laneWidth => 300;
|
||||
@override
|
||||
Color get cornerColor => Theme.of(context).primaryColor;
|
||||
@override
|
||||
Color get timeItemTextColor => Theme.of(context).primaryColor;
|
||||
@override
|
||||
double get timeItemHeight => 80;
|
||||
double get timeItemHeight => 70;
|
||||
@override
|
||||
double get timeItemWidth => 70;
|
||||
double get timeItemWidth => 50;
|
||||
@override
|
||||
double get laneWidth => MediaQuery.of(context).size.width - timeItemWidth;
|
||||
|
||||
}
|
@ -1,13 +1,18 @@
|
||||
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:marianum_mobile/widget/loadingPacket.dart';
|
||||
import 'package:jiffy/jiffy.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getRooms/getRoomsResponse.dart';
|
||||
import 'package:marianum_mobile/api/webuntis/queries/getSubjects/getSubjectsResponse.dart';
|
||||
import 'package:marianum_mobile/data/timetable/timetableProps.dart';
|
||||
import 'package:marianum_mobile/screen/pages/timetable/dayListView.dart';
|
||||
import 'package:marianum_mobile/screen/pages/timetable/testTimetable.dart';
|
||||
import 'package:marianum_mobile/widget/loadingSpinner.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:timetable_view/timetable_view.dart';
|
||||
|
||||
import '../../../dataOld/incommingPackets/timetablePacket.dart';
|
||||
import '../../../api/webuntis/queries/getTimetable/getTimetableResponse.dart';
|
||||
|
||||
class Timetable extends StatefulWidget {
|
||||
const Timetable({Key? key}) : super(key: key);
|
||||
@ -17,90 +22,69 @@ class Timetable extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _TimetableState extends State<Timetable> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
Provider.of<TimetablePacket>(context, listen: false).invoke();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
Provider.of<TimetableProps>(context, listen: false).run();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<TimetablePacket>(
|
||||
builder: (context, data, child) {
|
||||
return Consumer<TimetableProps>(
|
||||
builder: (context, value, child) {
|
||||
if(value.primaryLoading()) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
return LoadingPacket(packet: data, child: TimetableView(
|
||||
laneEventsList: _buildLaneEvents(context, data),
|
||||
onEventTap: (TableEvent event) {},
|
||||
timetableStyle: CustomTableStyle(context),
|
||||
onEmptySlotTap: (int laneIndex, TableEventTime start, TableEventTime end) => {},
|
||||
));
|
||||
TimetableProps timetable = Provider.of<TimetableProps>(context, listen: false);
|
||||
return Column(
|
||||
children: [
|
||||
Flexible(
|
||||
child: DayListView(value),
|
||||
),
|
||||
|
||||
Container(
|
||||
padding: const EdgeInsets.only(top: 5, bottom: 5),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
top: BorderSide(width: 2, color: Theme.of(context).disabledColor)
|
||||
)
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () => timetable.next(previous: true),
|
||||
icon: const Icon(Icons.navigate_before_sharp),
|
||||
color: Theme.of(context).primaryColor,
|
||||
iconSize: 30,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () => timetable.nearest(),
|
||||
icon: const Icon(Icons.home),
|
||||
color: Theme.of(context).primaryColor,
|
||||
iconSize: 30,
|
||||
),
|
||||
],
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => timetable.next(),
|
||||
icon: const Icon(Icons.navigate_next_sharp),
|
||||
color: Theme.of(context).primaryColor,
|
||||
iconSize: 30,
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
List<LaneEvents> _buildLaneEvents(context, TimetablePacket data) {
|
||||
List<LaneEvents> laneEvents = List<LaneEvents>.empty(growable: true);
|
||||
data.timeTable.days.forEach((day) {
|
||||
List<TableEvent> tableEvents = List<TableEvent>.empty(growable: true);
|
||||
|
||||
day.entries.forEach((element) {
|
||||
tableEvents.add(
|
||||
TableEvent(
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
padding: const EdgeInsets.all(5),
|
||||
title: element.subject,
|
||||
location: "\n${element.room}",
|
||||
eventId: tableEvents.length,
|
||||
laneIndex: tableEvents.length,
|
||||
startTime: TableEventTime(hour: element.start.hour, minute: element.start.minute),
|
||||
endTime: TableEventTime(hour: element.end.hour, minute: element.end.minute)
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
laneEvents.add(
|
||||
LaneEvents(
|
||||
lane: Lane(laneIndex: laneEvents.length, name: day.name, textStyle: TextStyle(color: Theme.of(context).primaryColor, fontWeight: FontWeight.bold)),
|
||||
events: tableEvents
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
return laneEvents;
|
||||
}
|
||||
|
||||
void onEventTapCallBack(TableEvent event) {
|
||||
print(
|
||||
"Event Clicked!! LaneIndex ${event.laneIndex} Title: ${event.title} StartHour: ${event.startTime.hour} EndHour: ${event.endTime.hour}");
|
||||
}
|
||||
|
||||
void onTimeSlotTappedCallBack(
|
||||
int laneIndex, TableEventTime start, TableEventTime end) {
|
||||
print(
|
||||
"Empty Slot Clicked !! LaneIndex: $laneIndex StartHour: ${start.hour} EndHour: ${end.hour}");
|
||||
}
|
||||
}
|
||||
|
||||
class CustomTableStyle extends TimetableStyle {
|
||||
dynamic context;
|
||||
CustomTableStyle(context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get startHour => 07;
|
||||
@override
|
||||
int get endHour => 17;
|
||||
@override
|
||||
double get laneWidth => 200;
|
||||
@override
|
||||
Color get cornerColor => Theme.of(this.context).primaryColor;
|
||||
@override
|
||||
Color get timeItemTextColor => Theme.of(this.context).primaryColor;
|
||||
@override
|
||||
// TODO: implement timeItemHeight
|
||||
double get timeItemHeight => 60;
|
||||
}
|
106
lib/screen/pages/timetable/timetableOld.dart
Normal file
106
lib/screen/pages/timetable/timetableOld.dart
Normal file
@ -0,0 +1,106 @@
|
||||
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:marianum_mobile/widget/loadingPacket.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:timetable_view/timetable_view.dart';
|
||||
|
||||
import '../../../dataOld/incommingPackets/timetablePacket.dart';
|
||||
|
||||
class TimetableOld extends StatefulWidget {
|
||||
const TimetableOld({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<TimetableOld> createState() => _TimetableOldState();
|
||||
}
|
||||
|
||||
class _TimetableOldState extends State<TimetableOld> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
Provider.of<TimetablePacket>(context, listen: false).invoke();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<TimetablePacket>(
|
||||
builder: (context, data, child) {
|
||||
|
||||
return LoadingPacket(packet: data, child: TimetableView(
|
||||
laneEventsList: _buildLaneEvents(context, data),
|
||||
onEventTap: (TableEvent event) {},
|
||||
timetableStyle: CustomTableStyle(context),
|
||||
onEmptySlotTap: (int laneIndex, TableEventTime start, TableEventTime end) => {},
|
||||
));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
List<LaneEvents> _buildLaneEvents(context, TimetablePacket data) {
|
||||
List<LaneEvents> laneEvents = List<LaneEvents>.empty(growable: true);
|
||||
data.timeTable.days.forEach((day) {
|
||||
List<TableEvent> tableEvents = List<TableEvent>.empty(growable: true);
|
||||
|
||||
day.entries.forEach((element) {
|
||||
tableEvents.add(
|
||||
TableEvent(
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
padding: const EdgeInsets.all(5),
|
||||
title: element.subject,
|
||||
location: "\n${element.room}",
|
||||
eventId: tableEvents.length,
|
||||
laneIndex: tableEvents.length,
|
||||
startTime: TableEventTime(hour: element.start.hour, minute: element.start.minute),
|
||||
endTime: TableEventTime(hour: element.end.hour, minute: element.end.minute)
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
laneEvents.add(
|
||||
LaneEvents(
|
||||
lane: Lane(laneIndex: laneEvents.length, name: day.name, textStyle: TextStyle(color: Theme.of(context).primaryColor, fontWeight: FontWeight.bold)),
|
||||
events: tableEvents
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
return laneEvents;
|
||||
}
|
||||
|
||||
void onEventTapCallBack(TableEvent event) {
|
||||
print(
|
||||
"Event Clicked!! LaneIndex ${event.laneIndex} Title: ${event.title} StartHour: ${event.startTime.hour} EndHour: ${event.endTime.hour}");
|
||||
}
|
||||
|
||||
void onTimeSlotTappedCallBack(
|
||||
int laneIndex, TableEventTime start, TableEventTime end) {
|
||||
print(
|
||||
"Empty Slot Clicked !! LaneIndex: $laneIndex StartHour: ${start.hour} EndHour: ${end.hour}");
|
||||
}
|
||||
}
|
||||
|
||||
class CustomTableStyle extends TimetableStyle {
|
||||
dynamic context;
|
||||
CustomTableStyle(context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get startHour => 07;
|
||||
@override
|
||||
int get endHour => 17;
|
||||
@override
|
||||
double get laneWidth => 200;
|
||||
@override
|
||||
Color get cornerColor => Theme.of(this.context).primaryColor;
|
||||
@override
|
||||
Color get timeItemTextColor => Theme.of(this.context).primaryColor;
|
||||
@override
|
||||
// TODO: implement timeItemHeight
|
||||
double get timeItemHeight => 60;
|
||||
}
|
90
lib/screen/settings/debug/debugOverview.dart
Normal file
90
lib/screen/settings/debug/debugOverview.dart
Normal file
@ -0,0 +1,90 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:jiffy/jiffy.dart';
|
||||
import 'package:localstore/localstore.dart';
|
||||
import 'package:marianum_mobile/screen/settings/debug/jsonViewer.dart';
|
||||
|
||||
class DebugOverview extends StatefulWidget {
|
||||
const DebugOverview({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<DebugOverview> createState() => _DebugOverviewState();
|
||||
}
|
||||
|
||||
class _DebugOverviewState extends State<DebugOverview> {
|
||||
|
||||
final Localstore storage = Localstore.instance;
|
||||
Future<Map<String, dynamic>?> files = Localstore.instance.collection("MarianumMobile").get();
|
||||
dynamic data;
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("Lokaler cache"),
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: ListView(
|
||||
children: [
|
||||
ListTile(
|
||||
leading: const Icon(Icons.delete_forever),
|
||||
title: const Text("Cache löschen"),
|
||||
onTap: () {
|
||||
storage.collection("MarianumMobile").delete().then((value) => {
|
||||
Navigator.pop(context)
|
||||
});
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
FutureBuilder(
|
||||
future: files,
|
||||
builder: (context, snapshot) {
|
||||
if(snapshot.hasData) {
|
||||
List<String> files = snapshot.data?.keys.map((e) => e.toString()).toList() ?? List<String>.empty();
|
||||
|
||||
Map<String, dynamic> getValue(int index) {
|
||||
return snapshot.data?[files[index]];
|
||||
}
|
||||
|
||||
return Expanded(
|
||||
flex: 5,
|
||||
child: ListView.builder(
|
||||
itemCount: files.length,
|
||||
itemBuilder: (context, index) {
|
||||
String filename = files[index].split("/").last;
|
||||
//String data = getValue(index).toString().replaceAll("{", "{\n ").replaceAll("[", "[\n ").replaceAll(",", ",\n ");
|
||||
String data = getValue(index).toString();
|
||||
|
||||
return ListTile(
|
||||
leading: const Icon(Icons.text_snippet_outlined),
|
||||
title: Text("(${data.length} z) [$filename] ${Jiffy.unixFromMillisecondsSinceEpoch(getValue(index)['lastupdate']).fromNow()}"),
|
||||
textColor: Colors.black,
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) {
|
||||
return JsonViewer(title: filename, data: data);
|
||||
},));
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return snapshot.data == null ? const Text("No data") : const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
21
lib/screen/settings/debug/jsonViewer.dart
Normal file
21
lib/screen/settings/debug/jsonViewer.dart
Normal file
@ -0,0 +1,21 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class JsonViewer extends StatelessWidget {
|
||||
String title;
|
||||
String data;
|
||||
|
||||
JsonViewer({Key? key, required this.title, required this.data}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(title),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Text(data.replaceAllMapped(RegExp(r'[{,}]'), (match) => "${match.group(0)}\n ")),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../../dataOld/accountModel.dart';
|
||||
import '../../dataOld/incommingPackets/serverInfoPacket.dart';
|
||||
import '../../widget/ListItem.dart';
|
||||
import 'debug/debugOverview.dart';
|
||||
|
||||
class Settings extends StatefulWidget {
|
||||
const Settings({Key? key}) : super(key: key);
|
||||
@ -19,7 +20,6 @@ class _SettingsState extends State<Settings> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
Provider.of<ServerInfoPacket>(context, listen: false).invoke();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -31,56 +31,64 @@ class _SettingsState extends State<Settings> {
|
||||
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"),
|
||||
title: const Text("Konto 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)),
|
||||
});
|
||||
}
|
||||
),
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return 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);
|
||||
},
|
||||
),
|
||||
],
|
||||
)));
|
||||
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"
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.info),
|
||||
title: const Text("Informationen und Lizenzen"),
|
||||
onTap: () {
|
||||
showAboutDialog(
|
||||
context: context,
|
||||
applicationIcon: const Icon(Icons.send_time_extension_outlined),
|
||||
applicationName: "MarianumMobile",
|
||||
applicationVersion: "Development Build",
|
||||
applicationLegalese: "Marianum Fulda 2023 Elias Müller",
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
ListTile(
|
||||
leading: const Icon(Icons.bug_report_outlined),
|
||||
title: const Text("Speicheransicht"),
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) {
|
||||
return const DebugOverview();
|
||||
}));
|
||||
},
|
||||
)
|
||||
|
||||
],
|
||||
|
@ -7,12 +7,10 @@ import Foundation
|
||||
|
||||
import path_provider_foundation
|
||||
import shared_preferences_foundation
|
||||
import sqflite
|
||||
import url_launcher_macos
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
}
|
||||
|
@ -47,7 +47,6 @@ dependencies:
|
||||
jiffy: ^5.0.0
|
||||
timetable_view: ^0.3.0
|
||||
json_annotation: ^4.8.0
|
||||
sqflite: ^2.2.4+1
|
||||
localstore: ^1.2.3
|
||||
intl: ^0.17.0
|
||||
|
||||
@ -82,6 +81,7 @@ flutter:
|
||||
|
||||
assets:
|
||||
- assets/ca/
|
||||
- assets/background/
|
||||
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/assets-and-images/#resolution-aware
|
||||
|
Loading…
x
Reference in New Issue
Block a user