wip: bloc for files
This commit is contained in:
		| @@ -35,7 +35,7 @@ GetHolidaysResponseObject _$GetHolidaysResponseObjectFromJson( | |||||||
|     GetHolidaysResponseObject( |     GetHolidaysResponseObject( | ||||||
|       start: json['start'] as String, |       start: json['start'] as String, | ||||||
|       end: json['end'] as String, |       end: json['end'] as String, | ||||||
|       year: json['year'] as int, |       year: (json['year'] as num).toInt(), | ||||||
|       stateCode: json['stateCode'] as String, |       stateCode: json['stateCode'] as String, | ||||||
|       name: json['name'] as String, |       name: json['name'] as String, | ||||||
|       slug: json['slug'] as String, |       slug: json['slug'] as String, | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ part of 'fileSharingApiParams.dart'; | |||||||
| FileSharingApiParams _$FileSharingApiParamsFromJson( | FileSharingApiParams _$FileSharingApiParamsFromJson( | ||||||
|         Map<String, dynamic> json) => |         Map<String, dynamic> json) => | ||||||
|     FileSharingApiParams( |     FileSharingApiParams( | ||||||
|       shareType: json['shareType'] as int, |       shareType: (json['shareType'] as num).toInt(), | ||||||
|       shareWith: json['shareWith'] as String, |       shareWith: json['shareWith'] as String, | ||||||
|       path: json['path'] as String, |       path: json['path'] as String, | ||||||
|       referenceId: json['referenceId'] as String?, |       referenceId: json['referenceId'] as String?, | ||||||
|   | |||||||
| @@ -10,10 +10,10 @@ GetChatParams _$GetChatParamsFromJson(Map<String, dynamic> json) => | |||||||
|     GetChatParams( |     GetChatParams( | ||||||
|       lookIntoFuture: |       lookIntoFuture: | ||||||
|           $enumDecode(_$GetChatParamsSwitchEnumMap, json['lookIntoFuture']), |           $enumDecode(_$GetChatParamsSwitchEnumMap, json['lookIntoFuture']), | ||||||
|       limit: json['limit'] as int?, |       limit: (json['limit'] as num?)?.toInt(), | ||||||
|       lastKnownMessageId: json['lastKnownMessageId'] as int?, |       lastKnownMessageId: (json['lastKnownMessageId'] as num?)?.toInt(), | ||||||
|       lastCommonReadId: json['lastCommonReadId'] as int?, |       lastCommonReadId: (json['lastCommonReadId'] as num?)?.toInt(), | ||||||
|       timeout: json['timeout'] as int?, |       timeout: (json['timeout'] as num?)?.toInt(), | ||||||
|       setReadMarker: $enumDecodeNullable( |       setReadMarker: $enumDecodeNullable( | ||||||
|           _$GetChatParamsSwitchEnumMap, json['setReadMarker']), |           _$GetChatParamsSwitchEnumMap, json['setReadMarker']), | ||||||
|       includeLastKnown: $enumDecodeNullable( |       includeLastKnown: $enumDecodeNullable( | ||||||
|   | |||||||
| @@ -32,13 +32,13 @@ Map<String, dynamic> _$GetChatResponseToJson(GetChatResponse instance) { | |||||||
| GetChatResponseObject _$GetChatResponseObjectFromJson( | GetChatResponseObject _$GetChatResponseObjectFromJson( | ||||||
|         Map<String, dynamic> json) => |         Map<String, dynamic> json) => | ||||||
|     GetChatResponseObject( |     GetChatResponseObject( | ||||||
|       json['id'] as int, |       (json['id'] as num).toInt(), | ||||||
|       json['token'] as String, |       json['token'] as String, | ||||||
|       $enumDecode( |       $enumDecode( | ||||||
|           _$GetRoomResponseObjectMessageActorTypeEnumMap, json['actorType']), |           _$GetRoomResponseObjectMessageActorTypeEnumMap, json['actorType']), | ||||||
|       json['actorId'] as String, |       json['actorId'] as String, | ||||||
|       json['actorDisplayName'] as String, |       json['actorDisplayName'] as String, | ||||||
|       json['timestamp'] as int, |       (json['timestamp'] as num).toInt(), | ||||||
|       json['systemMessage'] as String, |       json['systemMessage'] as String, | ||||||
|       $enumDecode( |       $enumDecode( | ||||||
|           _$GetRoomResponseObjectMessageTypeEnumMap, json['messageType']), |           _$GetRoomResponseObjectMessageTypeEnumMap, json['messageType']), | ||||||
| @@ -47,7 +47,7 @@ GetChatResponseObject _$GetChatResponseObjectFromJson( | |||||||
|       json['message'] as String, |       json['message'] as String, | ||||||
|       _fromJson(json['messageParameters']), |       _fromJson(json['messageParameters']), | ||||||
|       (json['reactions'] as Map<String, dynamic>?)?.map( |       (json['reactions'] as Map<String, dynamic>?)?.map( | ||||||
|         (k, e) => MapEntry(k, e as int), |         (k, e) => MapEntry(k, (e as num).toInt()), | ||||||
|       ), |       ), | ||||||
|       (json['reactionsSelf'] as List<dynamic>?) |       (json['reactionsSelf'] as List<dynamic>?) | ||||||
|           ?.map((e) => e as String) |           ?.map((e) => e as String) | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ part of 'createRoomParams.dart'; | |||||||
|  |  | ||||||
| CreateRoomParams _$CreateRoomParamsFromJson(Map<String, dynamic> json) => | CreateRoomParams _$CreateRoomParamsFromJson(Map<String, dynamic> json) => | ||||||
|     CreateRoomParams( |     CreateRoomParams( | ||||||
|       roomType: json['roomType'] as int, |       roomType: (json['roomType'] as num).toInt(), | ||||||
|       invite: json['invite'] as String, |       invite: json['invite'] as String, | ||||||
|       source: json['source'] as String?, |       source: json['source'] as String?, | ||||||
|       roomName: json['roomName'] as String?, |       roomName: json['roomName'] as String?, | ||||||
|   | |||||||
| @@ -35,17 +35,17 @@ Map<String, dynamic> _$GetParticipantsResponseToJson( | |||||||
| GetParticipantsResponseObject _$GetParticipantsResponseObjectFromJson( | GetParticipantsResponseObject _$GetParticipantsResponseObjectFromJson( | ||||||
|         Map<String, dynamic> json) => |         Map<String, dynamic> json) => | ||||||
|     GetParticipantsResponseObject( |     GetParticipantsResponseObject( | ||||||
|       json['attendeeId'] as int, |       (json['attendeeId'] as num).toInt(), | ||||||
|       json['actorType'] as String, |       json['actorType'] as String, | ||||||
|       json['actorId'] as String, |       json['actorId'] as String, | ||||||
|       json['displayName'] as String, |       json['displayName'] as String, | ||||||
|       $enumDecode(_$GetParticipantsResponseObjectParticipantTypeEnumMap, |       $enumDecode(_$GetParticipantsResponseObjectParticipantTypeEnumMap, | ||||||
|           json['participantType']), |           json['participantType']), | ||||||
|       json['lastPing'] as int, |       (json['lastPing'] as num).toInt(), | ||||||
|       $enumDecode(_$GetParticipantsResponseObjectParticipantsInCallFlagsEnumMap, |       $enumDecode(_$GetParticipantsResponseObjectParticipantsInCallFlagsEnumMap, | ||||||
|           json['inCall']), |           json['inCall']), | ||||||
|       json['permissions'] as int, |       (json['permissions'] as num).toInt(), | ||||||
|       json['attendeePermissions'] as int, |       (json['attendeePermissions'] as num).toInt(), | ||||||
|       json['sessionId'] as String?, |       json['sessionId'] as String?, | ||||||
|       (json['sessionIds'] as List<dynamic>).map((e) => e as String).toList(), |       (json['sessionIds'] as List<dynamic>).map((e) => e as String).toList(), | ||||||
|       json['status'] as String?, |       json['status'] as String?, | ||||||
|   | |||||||
| @@ -44,7 +44,7 @@ GetReactionsResponseObject _$GetReactionsResponseObjectFromJson( | |||||||
|           _$GetReactionsResponseObjectActorTypeEnumMap, json['actorType']), |           _$GetReactionsResponseObjectActorTypeEnumMap, json['actorType']), | ||||||
|       json['actorId'] as String, |       json['actorId'] as String, | ||||||
|       json['actorDisplayName'] as String, |       json['actorDisplayName'] as String, | ||||||
|       json['timestamp'] as int, |       (json['timestamp'] as num).toInt(), | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
| Map<String, dynamic> _$GetReactionsResponseObjectToJson( | Map<String, dynamic> _$GetReactionsResponseObjectToJson( | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ GetRoomParams _$GetRoomParamsFromJson(Map<String, dynamic> json) => | |||||||
|       noStatusUpdate: $enumDecodeNullable( |       noStatusUpdate: $enumDecodeNullable( | ||||||
|           _$GetRoomParamsStatusUpdateEnumMap, json['noStatusUpdate']), |           _$GetRoomParamsStatusUpdateEnumMap, json['noStatusUpdate']), | ||||||
|       includeStatus: json['includeStatus'] as bool?, |       includeStatus: json['includeStatus'] as bool?, | ||||||
|       modifiedSince: json['modifiedSince'] as int?, |       modifiedSince: (json['modifiedSince'] as num?)?.toInt(), | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
| Map<String, dynamic> _$GetRoomParamsToJson(GetRoomParams instance) => | Map<String, dynamic> _$GetRoomParamsToJson(GetRoomParams instance) => | ||||||
|   | |||||||
| @@ -32,33 +32,33 @@ Map<String, dynamic> _$GetRoomResponseToJson(GetRoomResponse instance) { | |||||||
| GetRoomResponseObject _$GetRoomResponseObjectFromJson( | GetRoomResponseObject _$GetRoomResponseObjectFromJson( | ||||||
|         Map<String, dynamic> json) => |         Map<String, dynamic> json) => | ||||||
|     GetRoomResponseObject( |     GetRoomResponseObject( | ||||||
|       json['id'] as int, |       (json['id'] as num).toInt(), | ||||||
|       json['token'] as String, |       json['token'] as String, | ||||||
|       $enumDecode(_$GetRoomResponseObjectConversationTypeEnumMap, json['type']), |       $enumDecode(_$GetRoomResponseObjectConversationTypeEnumMap, json['type']), | ||||||
|       json['name'] as String, |       json['name'] as String, | ||||||
|       json['displayName'] as String, |       json['displayName'] as String, | ||||||
|       json['description'] as String, |       json['description'] as String, | ||||||
|       json['participantType'] as int, |       (json['participantType'] as num).toInt(), | ||||||
|       json['participantFlags'] as int, |       (json['participantFlags'] as num).toInt(), | ||||||
|       json['readOnly'] as int, |       (json['readOnly'] as num).toInt(), | ||||||
|       json['listable'] as int, |       (json['listable'] as num).toInt(), | ||||||
|       json['lastPing'] as int, |       (json['lastPing'] as num).toInt(), | ||||||
|       json['sessionId'] as String, |       json['sessionId'] as String, | ||||||
|       json['hasPassword'] as bool, |       json['hasPassword'] as bool, | ||||||
|       json['hasCall'] as bool, |       json['hasCall'] as bool, | ||||||
|       json['callFlag'] as int, |       (json['callFlag'] as num).toInt(), | ||||||
|       json['canStartCall'] as bool, |       json['canStartCall'] as bool, | ||||||
|       json['canDeleteConversation'] as bool, |       json['canDeleteConversation'] as bool, | ||||||
|       json['canLeaveConversation'] as bool, |       json['canLeaveConversation'] as bool, | ||||||
|       json['lastActivity'] as int, |       (json['lastActivity'] as num).toInt(), | ||||||
|       json['isFavorite'] as bool, |       json['isFavorite'] as bool, | ||||||
|       $enumDecode(_$GetRoomResponseObjectParticipantNotificationLevelEnumMap, |       $enumDecode(_$GetRoomResponseObjectParticipantNotificationLevelEnumMap, | ||||||
|           json['notificationLevel']), |           json['notificationLevel']), | ||||||
|       json['unreadMessages'] as int, |       (json['unreadMessages'] as num).toInt(), | ||||||
|       json['unreadMention'] as bool, |       json['unreadMention'] as bool, | ||||||
|       json['unreadMentionDirect'] as bool, |       json['unreadMentionDirect'] as bool, | ||||||
|       json['lastReadMessage'] as int, |       (json['lastReadMessage'] as num).toInt(), | ||||||
|       json['lastCommonReadMessage'] as int, |       (json['lastCommonReadMessage'] as num).toInt(), | ||||||
|       GetChatResponseObject.fromJson( |       GetChatResponseObject.fromJson( | ||||||
|           json['lastMessage'] as Map<String, dynamic>), |           json['lastMessage'] as Map<String, dynamic>), | ||||||
|       json['status'] as String?, |       json['status'] as String?, | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ part of 'setReadMarkerParams.dart'; | |||||||
|  |  | ||||||
| SetReadMarkerParams _$SetReadMarkerParamsFromJson(Map<String, dynamic> json) => | SetReadMarkerParams _$SetReadMarkerParamsFromJson(Map<String, dynamic> json) => | ||||||
|     SetReadMarkerParams( |     SetReadMarkerParams( | ||||||
|       lastReadMessage: json['lastReadMessage'] as int?, |       lastReadMessage: (json['lastReadMessage'] as num?)?.toInt(), | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
| Map<String, dynamic> _$SetReadMarkerParamsToJson( | Map<String, dynamic> _$SetReadMarkerParamsToJson( | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ CacheableFile _$CacheableFileFromJson(Map<String, dynamic> json) => | |||||||
|       isDirectory: json['isDirectory'] as bool, |       isDirectory: json['isDirectory'] as bool, | ||||||
|       name: json['name'] as String, |       name: json['name'] as String, | ||||||
|       mimeType: json['mimeType'] as String?, |       mimeType: json['mimeType'] as String?, | ||||||
|       size: json['size'] as int?, |       size: (json['size'] as num?)?.toInt(), | ||||||
|       eTag: json['eTag'] as String?, |       eTag: json['eTag'] as String?, | ||||||
|       createdAt: json['createdAt'] == null |       createdAt: json['createdAt'] == null | ||||||
|           ? null |           ? null | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ AddFeedbackParams _$AddFeedbackParamsFromJson(Map<String, dynamic> json) => | |||||||
|       user: json['user'] as String, |       user: json['user'] as String, | ||||||
|       feedback: json['feedback'] as String, |       feedback: json['feedback'] as String, | ||||||
|       screenshot: json['screenshot'] as String?, |       screenshot: json['screenshot'] as String?, | ||||||
|       appVersion: json['appVersion'] as int, |       appVersion: (json['appVersion'] as num).toInt(), | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
| Map<String, dynamic> _$AddFeedbackParamsToJson(AddFeedbackParams instance) => | Map<String, dynamic> _$AddFeedbackParamsToJson(AddFeedbackParams instance) => | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ UpdateUserIndexParams _$UpdateUserIndexParamsFromJson( | |||||||
|       user: json['user'] as String, |       user: json['user'] as String, | ||||||
|       username: json['username'] as String, |       username: json['username'] as String, | ||||||
|       device: json['device'] as String, |       device: json['device'] as String, | ||||||
|       appVersion: json['appVersion'] as int, |       appVersion: (json['appVersion'] as num).toInt(), | ||||||
|       deviceInfo: json['deviceInfo'] as String, |       deviceInfo: json['deviceInfo'] as String, | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,9 +10,9 @@ AuthenticateResponse _$AuthenticateResponseFromJson( | |||||||
|         Map<String, dynamic> json) => |         Map<String, dynamic> json) => | ||||||
|     AuthenticateResponse( |     AuthenticateResponse( | ||||||
|       json['sessionId'] as String, |       json['sessionId'] as String, | ||||||
|       json['personType'] as int, |       (json['personType'] as num).toInt(), | ||||||
|       json['personId'] as int, |       (json['personId'] as num).toInt(), | ||||||
|       json['klasseId'] as int, |       (json['klasseId'] as num).toInt(), | ||||||
|     )..headers = (json['headers'] as Map<String, dynamic>?)?.map( |     )..headers = (json['headers'] as Map<String, dynamic>?)?.map( | ||||||
|         (k, e) => MapEntry(k, e as String), |         (k, e) => MapEntry(k, e as String), | ||||||
|       ); |       ); | ||||||
|   | |||||||
| @@ -33,11 +33,11 @@ Map<String, dynamic> _$GetHolidaysResponseToJson(GetHolidaysResponse instance) { | |||||||
| GetHolidaysResponseObject _$GetHolidaysResponseObjectFromJson( | GetHolidaysResponseObject _$GetHolidaysResponseObjectFromJson( | ||||||
|         Map<String, dynamic> json) => |         Map<String, dynamic> json) => | ||||||
|     GetHolidaysResponseObject( |     GetHolidaysResponseObject( | ||||||
|       json['id'] as int, |       (json['id'] as num).toInt(), | ||||||
|       json['name'] as String, |       json['name'] as String, | ||||||
|       json['longName'] as String, |       json['longName'] as String, | ||||||
|       json['startDate'] as int, |       (json['startDate'] as num).toInt(), | ||||||
|       json['endDate'] as int, |       (json['endDate'] as num).toInt(), | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
| Map<String, dynamic> _$GetHolidaysResponseObjectToJson( | Map<String, dynamic> _$GetHolidaysResponseObjectToJson( | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ Map<String, dynamic> _$GetRoomsResponseToJson(GetRoomsResponse instance) { | |||||||
| GetRoomsResponseObject _$GetRoomsResponseObjectFromJson( | GetRoomsResponseObject _$GetRoomsResponseObjectFromJson( | ||||||
|         Map<String, dynamic> json) => |         Map<String, dynamic> json) => | ||||||
|     GetRoomsResponseObject( |     GetRoomsResponseObject( | ||||||
|       json['id'] as int, |       (json['id'] as num).toInt(), | ||||||
|       json['name'] as String, |       json['name'] as String, | ||||||
|       json['longName'] as String, |       json['longName'] as String, | ||||||
|       json['active'] as bool, |       json['active'] as bool, | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ Map<String, dynamic> _$GetSubjectsResponseToJson(GetSubjectsResponse instance) { | |||||||
| GetSubjectsResponseObject _$GetSubjectsResponseObjectFromJson( | GetSubjectsResponseObject _$GetSubjectsResponseObjectFromJson( | ||||||
|         Map<String, dynamic> json) => |         Map<String, dynamic> json) => | ||||||
|     GetSubjectsResponseObject( |     GetSubjectsResponseObject( | ||||||
|       json['id'] as int, |       (json['id'] as num).toInt(), | ||||||
|       json['name'] as String, |       json['name'] as String, | ||||||
|       json['longName'] as String, |       json['longName'] as String, | ||||||
|       json['alternateName'] as String, |       json['alternateName'] as String, | ||||||
|   | |||||||
| @@ -22,8 +22,8 @@ GetTimetableParamsOptions _$GetTimetableParamsOptionsFromJson( | |||||||
|     GetTimetableParamsOptions( |     GetTimetableParamsOptions( | ||||||
|       element: GetTimetableParamsOptionsElement.fromJson( |       element: GetTimetableParamsOptionsElement.fromJson( | ||||||
|           json['element'] as Map<String, dynamic>), |           json['element'] as Map<String, dynamic>), | ||||||
|       startDate: json['startDate'] as int?, |       startDate: (json['startDate'] as num?)?.toInt(), | ||||||
|       endDate: json['endDate'] as int?, |       endDate: (json['endDate'] as num?)?.toInt(), | ||||||
|       onlyBaseTimetable: json['onlyBaseTimetable'] as bool?, |       onlyBaseTimetable: json['onlyBaseTimetable'] as bool?, | ||||||
|       showBooking: json['showBooking'] as bool?, |       showBooking: json['showBooking'] as bool?, | ||||||
|       showInfo: json['showInfo'] as bool?, |       showInfo: json['showInfo'] as bool?, | ||||||
| @@ -99,8 +99,8 @@ const _$GetTimetableParamsOptionsFieldsEnumMap = { | |||||||
| GetTimetableParamsOptionsElement _$GetTimetableParamsOptionsElementFromJson( | GetTimetableParamsOptionsElement _$GetTimetableParamsOptionsElementFromJson( | ||||||
|         Map<String, dynamic> json) => |         Map<String, dynamic> json) => | ||||||
|     GetTimetableParamsOptionsElement( |     GetTimetableParamsOptionsElement( | ||||||
|       id: json['id'] as int, |       id: (json['id'] as num).toInt(), | ||||||
|       type: json['type'] as int, |       type: (json['type'] as num).toInt(), | ||||||
|       keyType: $enumDecodeNullable( |       keyType: $enumDecodeNullable( | ||||||
|           _$GetTimetableParamsOptionsElementKeyTypeEnumMap, json['keyType']), |           _$GetTimetableParamsOptionsElementKeyTypeEnumMap, json['keyType']), | ||||||
|     ); |     ); | ||||||
|   | |||||||
| @@ -35,16 +35,16 @@ Map<String, dynamic> _$GetTimetableResponseToJson( | |||||||
| GetTimetableResponseObject _$GetTimetableResponseObjectFromJson( | GetTimetableResponseObject _$GetTimetableResponseObjectFromJson( | ||||||
|         Map<String, dynamic> json) => |         Map<String, dynamic> json) => | ||||||
|     GetTimetableResponseObject( |     GetTimetableResponseObject( | ||||||
|       id: json['id'] as int, |       id: (json['id'] as num).toInt(), | ||||||
|       date: json['date'] as int, |       date: (json['date'] as num).toInt(), | ||||||
|       startTime: json['startTime'] as int, |       startTime: (json['startTime'] as num).toInt(), | ||||||
|       endTime: json['endTime'] as int, |       endTime: (json['endTime'] as num).toInt(), | ||||||
|       lstype: json['lstype'] as String?, |       lstype: json['lstype'] as String?, | ||||||
|       code: json['code'] as String?, |       code: json['code'] as String?, | ||||||
|       info: json['info'] as String?, |       info: json['info'] as String?, | ||||||
|       substText: json['substText'] as String?, |       substText: json['substText'] as String?, | ||||||
|       lstext: json['lstext'] as String?, |       lstext: json['lstext'] as String?, | ||||||
|       lsnumber: json['lsnumber'] as int?, |       lsnumber: (json['lsnumber'] as num?)?.toInt(), | ||||||
|       statflags: json['statflags'] as String?, |       statflags: json['statflags'] as String?, | ||||||
|       activityType: json['activityType'] as String?, |       activityType: json['activityType'] as String?, | ||||||
|       sg: json['sg'] as String?, |       sg: json['sg'] as String?, | ||||||
| @@ -110,7 +110,7 @@ GetTimetableResponseObjectFieldsObject | |||||||
|     _$GetTimetableResponseObjectFieldsObjectFromJson( |     _$GetTimetableResponseObjectFieldsObjectFromJson( | ||||||
|             Map<String, dynamic> json) => |             Map<String, dynamic> json) => | ||||||
|         GetTimetableResponseObjectFieldsObject( |         GetTimetableResponseObjectFieldsObject( | ||||||
|           id: json['id'] as int?, |           id: (json['id'] as num?)?.toInt(), | ||||||
|           name: json['name'] as String?, |           name: json['name'] as String?, | ||||||
|           longname: json['longname'] as String?, |           longname: json['longname'] as String?, | ||||||
|           externalkey: json['externalkey'] as String?, |           externalkey: json['externalkey'] as String?, | ||||||
| @@ -128,7 +128,7 @@ Map<String, dynamic> _$GetTimetableResponseObjectFieldsObjectToJson( | |||||||
| GetTimetableResponseObjectClass _$GetTimetableResponseObjectClassFromJson( | GetTimetableResponseObjectClass _$GetTimetableResponseObjectClassFromJson( | ||||||
|         Map<String, dynamic> json) => |         Map<String, dynamic> json) => | ||||||
|     GetTimetableResponseObjectClass( |     GetTimetableResponseObjectClass( | ||||||
|       json['id'] as int, |       (json['id'] as num).toInt(), | ||||||
|       json['name'] as String, |       json['name'] as String, | ||||||
|       json['longname'] as String, |       json['longname'] as String, | ||||||
|       json['externalkey'] as String?, |       json['externalkey'] as String?, | ||||||
| @@ -146,10 +146,10 @@ Map<String, dynamic> _$GetTimetableResponseObjectClassToJson( | |||||||
| GetTimetableResponseObjectTeacher _$GetTimetableResponseObjectTeacherFromJson( | GetTimetableResponseObjectTeacher _$GetTimetableResponseObjectTeacherFromJson( | ||||||
|         Map<String, dynamic> json) => |         Map<String, dynamic> json) => | ||||||
|     GetTimetableResponseObjectTeacher( |     GetTimetableResponseObjectTeacher( | ||||||
|       json['id'] as int, |       (json['id'] as num).toInt(), | ||||||
|       json['name'] as String, |       json['name'] as String, | ||||||
|       json['longname'] as String, |       json['longname'] as String, | ||||||
|       json['orgid'] as int?, |       (json['orgid'] as num?)?.toInt(), | ||||||
|       json['orgname'] as String?, |       json['orgname'] as String?, | ||||||
|       json['externalkey'] as String?, |       json['externalkey'] as String?, | ||||||
|     ); |     ); | ||||||
| @@ -168,7 +168,7 @@ Map<String, dynamic> _$GetTimetableResponseObjectTeacherToJson( | |||||||
| GetTimetableResponseObjectSubject _$GetTimetableResponseObjectSubjectFromJson( | GetTimetableResponseObjectSubject _$GetTimetableResponseObjectSubjectFromJson( | ||||||
|         Map<String, dynamic> json) => |         Map<String, dynamic> json) => | ||||||
|     GetTimetableResponseObjectSubject( |     GetTimetableResponseObjectSubject( | ||||||
|       json['id'] as int, |       (json['id'] as num).toInt(), | ||||||
|       json['name'] as String, |       json['name'] as String, | ||||||
|       json['longname'] as String, |       json['longname'] as String, | ||||||
|     ); |     ); | ||||||
| @@ -184,7 +184,7 @@ Map<String, dynamic> _$GetTimetableResponseObjectSubjectToJson( | |||||||
| GetTimetableResponseObjectRoom _$GetTimetableResponseObjectRoomFromJson( | GetTimetableResponseObjectRoom _$GetTimetableResponseObjectRoomFromJson( | ||||||
|         Map<String, dynamic> json) => |         Map<String, dynamic> json) => | ||||||
|     GetTimetableResponseObjectRoom( |     GetTimetableResponseObjectRoom( | ||||||
|       json['id'] as int, |       (json['id'] as num).toInt(), | ||||||
|       json['name'] as String, |       json['name'] as String, | ||||||
|       json['longname'] as String, |       json['longname'] as String, | ||||||
|     ); |     ); | ||||||
|   | |||||||
							
								
								
									
										93
									
								
								lib/app.dart
									
									
									
									
									
								
							
							
						
						
									
										93
									
								
								lib/app.dart
									
									
									
									
									
								
							| @@ -94,55 +94,56 @@ class _AppState extends State<App> with WidgetsBindingObserver { | |||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) => PersistentTabView( |   Widget build(BuildContext context) => PersistentTabView( | ||||||
|       controller: Main.bottomNavigator, |     controller: Main.bottomNavigator, | ||||||
|       navBarOverlap: const NavBarOverlap.none(), |     navBarOverlap: const NavBarOverlap.none(), | ||||||
|       backgroundColor: Theme.of(context).colorScheme.primary, |     backgroundColor: Theme.of(context).colorScheme.primary, | ||||||
|       handleAndroidBackButtonPress: false, |     handleAndroidBackButtonPress: false, | ||||||
|  |  | ||||||
|       screenTransitionAnimation: const ScreenTransitionAnimation(curve: Curves.easeOutQuad, duration: Duration(milliseconds: 200)), |     screenTransitionAnimation: const ScreenTransitionAnimation(curve: Curves.easeOutQuad, duration: Duration(milliseconds: 200)), | ||||||
|       tabs: [ |     tabs: [ | ||||||
|         AppModule.getModule(Modules.timetable).toBottomTab(context), |       AppModule.getModule(Modules.timetable).toBottomTab(context), | ||||||
|         AppModule.getModule(Modules.talk).toBottomTab( |       AppModule.getModule(Modules.talk).toBottomTab( | ||||||
|           context, |         context, | ||||||
|           itemBuilder: (icon) => Consumer<ChatListProps>( |         itemBuilder: (icon) => Consumer<ChatListProps>( | ||||||
|             builder: (context, value, child) { |           builder: (context, value, child) { | ||||||
|               if(value.primaryLoading()) return Icon(icon); |             if(value.primaryLoading()) return Icon(icon); | ||||||
|               var messages = value.getRoomsResponse.data.map((e) => e.unreadMessages).reduce((a, b) => a+b); |             var messages = value.getRoomsResponse.data.map((e) => e.unreadMessages).reduce((a, b) => a+b); | ||||||
|               return badges.Badge( |             return badges.Badge( | ||||||
|                 showBadge: messages > 0, |               showBadge: messages > 0, | ||||||
|                 position: badges.BadgePosition.topEnd(top: -3, end: -3), |               position: badges.BadgePosition.topEnd(top: -3, end: -3), | ||||||
|                 stackFit: StackFit.loose, |               stackFit: StackFit.loose, | ||||||
|                 badgeStyle: badges.BadgeStyle( |               badgeStyle: badges.BadgeStyle( | ||||||
|                   padding: const EdgeInsets.all(3), |                 padding: const EdgeInsets.all(3), | ||||||
|                   badgeColor: Theme.of(context).primaryColor, |                 badgeColor: Theme.of(context).primaryColor, | ||||||
|                   elevation: 1, |                 elevation: 1, | ||||||
|                 ), |               ), | ||||||
|                 badgeContent: Text('$messages', style: const TextStyle(color: Colors.white, fontSize: 10, fontWeight: FontWeight.bold)), |               badgeContent: Text('$messages', style: const TextStyle(color: Colors.white, fontSize: 10, fontWeight: FontWeight.bold)), | ||||||
|                 child: Icon(icon), |               child: Icon(icon), | ||||||
|               ); |             ); | ||||||
|             }, |           }, | ||||||
|           ), |  | ||||||
|         ), |  | ||||||
|         AppModule.getModule(Modules.files).toBottomTab(context), |  | ||||||
|  |  | ||||||
|         PersistentTabConfig( |  | ||||||
|           screen: const Breaker(breaker: BreakerArea.more, child: Overhang()), |  | ||||||
|           item: ItemConfig( |  | ||||||
|               activeForegroundColor: Theme.of(context).primaryColor, |  | ||||||
|               inactiveForegroundColor: Theme.of(context).colorScheme.secondary, |  | ||||||
|               icon: const Icon(Icons.apps), |  | ||||||
|               title: 'Mehr' |  | ||||||
|           ), |  | ||||||
|         ), |  | ||||||
|       ], |  | ||||||
|       navBarBuilder: (config) => Style6BottomNavBar( |  | ||||||
|         navBarConfig: config, |  | ||||||
|         navBarDecoration: NavBarDecoration( |  | ||||||
|           border: const Border(top: BorderSide(width: 1, color: Colors.grey)), |  | ||||||
|           color: Theme.of(context).colorScheme.surface, |  | ||||||
|         ), |         ), | ||||||
|       ), |       ), | ||||||
|     ); |       AppModule.getModule(Modules.blocFiles).toBottomTab(context), | ||||||
|  |       AppModule.getModule(Modules.files).toBottomTab(context), | ||||||
|  |  | ||||||
|  |       PersistentTabConfig( | ||||||
|  |         screen: const Breaker(breaker: BreakerArea.more, child: Overhang()), | ||||||
|  |         item: ItemConfig( | ||||||
|  |             activeForegroundColor: Theme.of(context).primaryColor, | ||||||
|  |             inactiveForegroundColor: Theme.of(context).colorScheme.secondary, | ||||||
|  |             icon: const Icon(Icons.apps), | ||||||
|  |             title: 'Mehr' | ||||||
|  |         ), | ||||||
|  |       ), | ||||||
|  |     ], | ||||||
|  |     navBarBuilder: (config) => Style6BottomNavBar( | ||||||
|  |       navBarConfig: config, | ||||||
|  |       navBarDecoration: NavBarDecoration( | ||||||
|  |         border: const Border(top: BorderSide(width: 1, color: Colors.grey)), | ||||||
|  |         color: Theme.of(context).colorScheme.surface, | ||||||
|  |       ), | ||||||
|  |     ), | ||||||
|  |   ); | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   void dispose() { |   void dispose() { | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ Future<void> main() async { | |||||||
|   var initialisationTasks = [ |   var initialisationTasks = [ | ||||||
|     Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform) |     Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform) | ||||||
|       .then((value) async => log("Firebase token: ${await FirebaseMessaging.instance.getToken() ?? "Error: no Firebase token!"}")) |       .then((value) async => log("Firebase token: ${await FirebaseMessaging.instance.getToken() ?? "Error: no Firebase token!"}")) | ||||||
|       .onError((error, stackTrace) => log('Error initializing Firebase: $error')), |       .onError((error, stackTrace) => log('Error initializing Firebase: $error', stackTrace: stackTrace)), | ||||||
|  |  | ||||||
|     PlatformAssetBundle().load('assets/ca/lets-encrypt-r3.pem').then(addCertificateAsTrusted), |     PlatformAssetBundle().load('assets/ca/lets-encrypt-r3.pem').then(addCertificateAsTrusted), | ||||||
|     PlatformAssetBundle().load('assets/ca/lets-encrypt-r10.pem').then(addCertificateAsTrusted), |     PlatformAssetBundle().load('assets/ca/lets-encrypt-r10.pem').then(addCertificateAsTrusted), | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| import 'package:dio/dio.dart'; | import 'package:dio/dio.dart'; | ||||||
|  |  | ||||||
| import '../../infrastructure/dataLoader/data_loader.dart'; | import '../../infrastructure/dataLoader/http_data_loader.dart'; | ||||||
|  |  | ||||||
| abstract class HolidayDataLoader<TResult> extends DataLoader<TResult> { | abstract class HolidayDataLoader<TResult> extends HttpDataLoader<TResult> { | ||||||
|   HolidayDataLoader() : super(Dio(BaseOptions( |   HolidayDataLoader() : super(Dio(BaseOptions( | ||||||
|     baseUrl: 'https://ferien-api.de/api/v1/', |     baseUrl: 'https://ferien-api.de/api/v1/', | ||||||
|   ))); |   ))); | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| import 'package:dio/dio.dart'; | import 'package:dio/dio.dart'; | ||||||
|  |  | ||||||
| import '../../infrastructure/dataLoader/data_loader.dart'; | import '../../infrastructure/dataLoader/http_data_loader.dart'; | ||||||
|  |  | ||||||
| abstract class MhslDataLoader<TResult> extends DataLoader<TResult> { | abstract class MhslDataLoader<TResult> extends HttpDataLoader<TResult> { | ||||||
|   MhslDataLoader() : super(Dio(BaseOptions( |   MhslDataLoader() : super(Dio(BaseOptions( | ||||||
|     baseUrl: 'https://mhsl.eu/marianum/marianummobile/' |     baseUrl: 'https://mhsl.eu/marianum/marianummobile/' | ||||||
|   ))); |   ))); | ||||||
|   | |||||||
| @@ -2,26 +2,21 @@ import 'dart:convert'; | |||||||
| import 'dart:developer'; | import 'dart:developer'; | ||||||
| 
 | 
 | ||||||
| import 'package:dio/dio.dart'; | import 'package:dio/dio.dart'; | ||||||
|  | import 'package:flutter/foundation.dart'; | ||||||
| 
 | 
 | ||||||
| abstract class DataLoader<TResult> { | abstract class HttpDataLoader<TResult> { | ||||||
|   final Dio dio; |   final Dio dio; | ||||||
|   DataLoader(this.dio) { |   HttpDataLoader(this.dio) { | ||||||
|     dio.options.connectTimeout = const Duration(seconds: 10).inMilliseconds; |     dio.options.connectTimeout = const Duration(seconds: 10).inMilliseconds; | ||||||
|     dio.options.sendTimeout = const Duration(seconds: 30).inMilliseconds; |     dio.options.sendTimeout = const Duration(seconds: 30).inMilliseconds; | ||||||
|     dio.options.receiveTimeout = const Duration(seconds: 30).inMilliseconds; |     dio.options.receiveTimeout = const Duration(seconds: 30).inMilliseconds; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Future<TResult> run() async { |   Future<TResult> run() async { | ||||||
|     var fetcher = fetch(); |     var response = await fetch(); | ||||||
|     await Future.wait([ |  | ||||||
|       fetcher, |  | ||||||
|       Future.delayed(const Duration(milliseconds: 500)) // TODO tune or remove |  | ||||||
|     ]); |  | ||||||
| 
 |  | ||||||
|     var response = await fetcher; |  | ||||||
|     try { |     try { | ||||||
|       return assemble(DataLoaderResult( |       return assemble(DataLoaderResult( | ||||||
|         json: jsonDecode(response.data!), |         json: await compute(jsonDecode, response.data!), | ||||||
|         headers: response.headers.map.map((key, value) => MapEntry(key, value.join(';'))), |         headers: response.headers.map.map((key, value) => MapEntry(key, value.join(';'))), | ||||||
|       )); |       )); | ||||||
|     } catch(trace, e) { |     } catch(trace, e) { | ||||||
| @@ -166,27 +166,22 @@ class __$$LoadableStateImplCopyWithImpl<TState, $Res> | |||||||
|  |  | ||||||
| class _$LoadableStateImpl<TState> extends _LoadableState<TState> { | class _$LoadableStateImpl<TState> extends _LoadableState<TState> { | ||||||
|   const _$LoadableStateImpl( |   const _$LoadableStateImpl( | ||||||
|       {this.isLoading = true, |       {required this.isLoading, | ||||||
|       this.data = null, |       required this.data, | ||||||
|       this.lastFetch = null, |       required this.lastFetch, | ||||||
|       this.reFetch = null, |       required this.reFetch, | ||||||
|       this.error = null}) |       required this.error}) | ||||||
|       : super._(); |       : super._(); | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   @JsonKey() |  | ||||||
|   final bool isLoading; |   final bool isLoading; | ||||||
|   @override |   @override | ||||||
|   @JsonKey() |  | ||||||
|   final TState? data; |   final TState? data; | ||||||
|   @override |   @override | ||||||
|   @JsonKey() |  | ||||||
|   final int? lastFetch; |   final int? lastFetch; | ||||||
|   @override |   @override | ||||||
|   @JsonKey() |  | ||||||
|   final void Function()? reFetch; |   final void Function()? reFetch; | ||||||
|   @override |   @override | ||||||
|   @JsonKey() |  | ||||||
|   final LoadingError? error; |   final LoadingError? error; | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
| @@ -222,11 +217,11 @@ class _$LoadableStateImpl<TState> extends _LoadableState<TState> { | |||||||
|  |  | ||||||
| abstract class _LoadableState<TState> extends LoadableState<TState> { | abstract class _LoadableState<TState> extends LoadableState<TState> { | ||||||
|   const factory _LoadableState( |   const factory _LoadableState( | ||||||
|       {final bool isLoading, |       {required final bool isLoading, | ||||||
|       final TState? data, |       required final TState? data, | ||||||
|       final int? lastFetch, |       required final int? lastFetch, | ||||||
|       final void Function()? reFetch, |       required final void Function()? reFetch, | ||||||
|       final LoadingError? error}) = _$LoadableStateImpl<TState>; |       required final LoadingError? error}) = _$LoadableStateImpl<TState>; | ||||||
|   const _LoadableState._() : super._(); |   const _LoadableState._() : super._(); | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   | |||||||
| @@ -30,16 +30,17 @@ abstract class LoadableHydratedBloc< | |||||||
|         isLoading: state.isLoading, |         isLoading: state.isLoading, | ||||||
|         data: event.state(innerState ?? fromNothing()), |         data: event.state(innerState ?? fromNothing()), | ||||||
|         lastFetch: state.lastFetch, |         lastFetch: state.lastFetch, | ||||||
|         reFetch: retry, |         reFetch: fetch, | ||||||
|         error: state.error, |         error: state.error, | ||||||
|       )); |       )); | ||||||
|  |       if(event.fetch) fetch(); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     on<DataGathered<TState>>((event, emit) => emit(LoadableState( |     on<DataGathered<TState>>((event, emit) => emit(LoadableState( | ||||||
|       isLoading: false, |       isLoading: false, | ||||||
|       data: event.state(innerState ?? fromNothing()), |       data: event.state(innerState ?? fromNothing()), | ||||||
|       lastFetch: DateTime.now().millisecondsSinceEpoch, |       lastFetch: DateTime.now().millisecondsSinceEpoch, | ||||||
|       reFetch: retry, |       reFetch: fetch, | ||||||
|       error: null, |       error: null, | ||||||
|     ))); |     ))); | ||||||
|  |  | ||||||
| @@ -55,7 +56,7 @@ abstract class LoadableHydratedBloc< | |||||||
|         isLoading: false, |         isLoading: false, | ||||||
|         data: innerState, |         data: innerState, | ||||||
|         lastFetch: state.lastFetch, |         lastFetch: state.lastFetch, | ||||||
|         reFetch: retry, |         reFetch: fetch, | ||||||
|         error: event.error |         error: event.error | ||||||
|     ))); |     ))); | ||||||
|  |  | ||||||
| @@ -66,19 +67,14 @@ abstract class LoadableHydratedBloc< | |||||||
|   TState? get innerState => state.data; |   TState? get innerState => state.data; | ||||||
|   TRepository get repo => _repository; |   TRepository get repo => _repository; | ||||||
|  |  | ||||||
|   void retry() { |  | ||||||
|     log('Fetch retry triggered for ${TState.toString()}'); |  | ||||||
|     add(RefetchStarted<TState>()); |  | ||||||
|     fetch(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   void fetch() { |   void fetch() { | ||||||
|     log('Fetching data for ${TState.toString()}'); |     log('Fetching data for ${TState.toString()}'); | ||||||
|  |     add(RefetchStarted<TState>()); | ||||||
|     gatherData().catchError( |     gatherData().catchError( | ||||||
|       (e) { |       (e) { | ||||||
|         log('Error while fetching ${TState.toString()}: ${e.toString()}'); |         log('Error while fetching ${TState.toString()}: ${e.toString()}'); | ||||||
|         add(Error(LoadingError( |         add(Error(LoadingError( | ||||||
|           message: e.message ?? e.toString(), |           message: e.toString(), | ||||||
|           allowRetry: true, |           allowRetry: true, | ||||||
|         ))); |         ))); | ||||||
|       }, |       }, | ||||||
| @@ -92,7 +88,7 @@ abstract class LoadableHydratedBloc< | |||||||
|     var rawData = LoadableSaveContext.unwrap(json); |     var rawData = LoadableSaveContext.unwrap(json); | ||||||
|     return LoadableState( |     return LoadableState( | ||||||
|       isLoading: true, |       isLoading: true, | ||||||
|       data: fromStorage(rawData.data), |       data: fromStorage(rawData.data), // TODO fromStorage in isolate | ||||||
|       lastFetch: rawData.meta.timestamp, |       lastFetch: rawData.meta.timestamp, | ||||||
|       reFetch: null, |       reFetch: null, | ||||||
|       error: null, |       error: null, | ||||||
| @@ -103,7 +99,7 @@ abstract class LoadableHydratedBloc< | |||||||
|   Map<String, dynamic>? toJson(LoadableState<TState> state) { |   Map<String, dynamic>? toJson(LoadableState<TState> state) { | ||||||
|     Map<String, dynamic>? data; |     Map<String, dynamic>? data; | ||||||
|     try { |     try { | ||||||
|       data = state.data == null ? null : toStorage(state.data); |       data = state.data == null ? null : toStorage(state.data); // TODO toStorage in isolate | ||||||
|     } catch(e) { |     } catch(e) { | ||||||
|       log('Failed to save state ${TState.toString()}: ${e.toString()}'); |       log('Failed to save state ${TState.toString()}: ${e.toString()}'); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -3,7 +3,8 @@ import '../../loadableState/loading_error.dart'; | |||||||
| class LoadableHydratedBlocEvent<TState> {} | class LoadableHydratedBlocEvent<TState> {} | ||||||
| class Emit<TState> extends LoadableHydratedBlocEvent<TState> { | class Emit<TState> extends LoadableHydratedBlocEvent<TState> { | ||||||
|   final TState Function(TState state) state; |   final TState Function(TState state) state; | ||||||
|   Emit(this.state); |   final bool fetch; | ||||||
|  |   Emit(this.state, {this.fetch = false}); | ||||||
| } | } | ||||||
| class DataGathered<TState> extends LoadableHydratedBlocEvent<TState> { | class DataGathered<TState> extends LoadableHydratedBlocEvent<TState> { | ||||||
|   final TState Function(TState state) state; |   final TState Function(TState state) state; | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ part of 'loadable_save_context.dart'; | |||||||
| _$LoadableSaveContextImpl _$$LoadableSaveContextImplFromJson( | _$LoadableSaveContextImpl _$$LoadableSaveContextImplFromJson( | ||||||
|         Map<String, dynamic> json) => |         Map<String, dynamic> json) => | ||||||
|     _$LoadableSaveContextImpl( |     _$LoadableSaveContextImpl( | ||||||
|       timestamp: json['timestamp'] as int, |       timestamp: (json['timestamp'] as num).toInt(), | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
| Map<String, dynamic> _$$LoadableSaveContextImplToJson( | Map<String, dynamic> _$$LoadableSaveContextImplToJson( | ||||||
|   | |||||||
| @@ -0,0 +1,48 @@ | |||||||
|  | import 'dart:async'; | ||||||
|  |  | ||||||
|  | import 'package:bloc/bloc.dart'; | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  |  | ||||||
|  | import 'bloc_module.dart'; | ||||||
|  |  | ||||||
|  | class SwappingBloc<TBloc> { | ||||||
|  |   final TBloc initialBloc; | ||||||
|  |   final StreamController<TBloc> updater = StreamController<TBloc>(); | ||||||
|  |  | ||||||
|  |   SwappingBloc(this.initialBloc); | ||||||
|  |  | ||||||
|  |   void swap(TBloc bloc) { | ||||||
|  |     updater.add(bloc); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class SwappingBlocModule<TBloc extends StateStreamableSource<TState>, TState> extends StatefulWidget { | ||||||
|  |   final SwappingBloc<TBloc> bloc; | ||||||
|  |   final Widget Function(BuildContext context, TBloc bloc, TState state) child; | ||||||
|  |   const SwappingBlocModule({super.key, required this.bloc, required this.child}); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   State<SwappingBlocModule<TBloc, TState>> createState() => _SwappingBlocModuleState<TBloc, TState>(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class _SwappingBlocModuleState<TBloc extends StateStreamableSource<TState>, TState> extends State<SwappingBlocModule<TBloc, TState>> { | ||||||
|  |   late TBloc bloc; | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   void initState() { | ||||||
|  |     super.initState(); | ||||||
|  |     bloc = widget.bloc.initialBloc; | ||||||
|  |     widget.bloc.updater.stream.listen((event) { | ||||||
|  |       setState(() { | ||||||
|  |         bloc = event; | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) => BlocModule<TBloc, TState>( | ||||||
|  |     autoRebuild: true, | ||||||
|  |     create: (context) => bloc, | ||||||
|  |     child: (context, bloc, state) => widget.child(context, bloc, state), | ||||||
|  |   ); | ||||||
|  | } | ||||||
| @@ -8,6 +8,7 @@ import '../../../view/pages/more/roomplan/roomplan.dart'; | |||||||
| import '../../../view/pages/talk/chatList.dart'; | import '../../../view/pages/talk/chatList.dart'; | ||||||
| import '../../../view/pages/timetable/timetable.dart'; | import '../../../view/pages/timetable/timetable.dart'; | ||||||
| import '../../../widget/centeredLeading.dart'; | import '../../../widget/centeredLeading.dart'; | ||||||
|  | import 'files/view/files_view.dart'; | ||||||
| import 'gradeAverages/view/grade_averages_view.dart'; | import 'gradeAverages/view/grade_averages_view.dart'; | ||||||
| import 'holidays/view/holidays_view.dart'; | import 'holidays/view/holidays_view.dart'; | ||||||
| import 'marianumMessage/view/marianum_message_list_view.dart'; | import 'marianumMessage/view/marianum_message_list_view.dart'; | ||||||
| @@ -23,6 +24,7 @@ class AppModule { | |||||||
|     Modules.timetable: AppModule('Vertretung', Icons.calendar_month, Timetable.new), |     Modules.timetable: AppModule('Vertretung', Icons.calendar_month, Timetable.new), | ||||||
|     Modules.talk: AppModule('Talk', Icons.chat, ChatList.new), |     Modules.talk: AppModule('Talk', Icons.chat, ChatList.new), | ||||||
|     Modules.files: AppModule('Files', Icons.folder, Files.new), |     Modules.files: AppModule('Files', Icons.folder, Files.new), | ||||||
|  |     Modules.blocFiles: AppModule('BlocFiles', Icons.folder, FilesView.new), | ||||||
|     Modules.marianumMessage: AppModule('Marianum Message', Icons.newspaper, MarianumMessageListView.new), |     Modules.marianumMessage: AppModule('Marianum Message', Icons.newspaper, MarianumMessageListView.new), | ||||||
|     Modules.roomPlan: AppModule('Raumplan', Icons.location_pin, Roomplan.new), |     Modules.roomPlan: AppModule('Raumplan', Icons.location_pin, Roomplan.new), | ||||||
|     Modules.gradeAveragesCalculator: AppModule('Notendurschnittsrechner', Icons.calculate, GradeAveragesView.new), |     Modules.gradeAveragesCalculator: AppModule('Notendurschnittsrechner', Icons.calculate, GradeAveragesView.new), | ||||||
| @@ -53,6 +55,7 @@ enum Modules { | |||||||
|   timetable, |   timetable, | ||||||
|   talk, |   talk, | ||||||
|   files, |   files, | ||||||
|  |   blocFiles, | ||||||
|   marianumMessage, |   marianumMessage, | ||||||
|   roomPlan, |   roomPlan, | ||||||
|   gradeAveragesCalculator, |   gradeAveragesCalculator, | ||||||
|   | |||||||
							
								
								
									
										65
									
								
								lib/state/app/modules/files/bloc/files_bloc.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								lib/state/app/modules/files/bloc/files_bloc.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | |||||||
|  |  | ||||||
|  | import 'dart:developer'; | ||||||
|  |  | ||||||
|  | import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc.dart'; | ||||||
|  | import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc_event.dart'; | ||||||
|  | import '../repository/files_repository.dart'; | ||||||
|  | import 'files_event.dart'; | ||||||
|  | import 'files_state.dart'; | ||||||
|  |  | ||||||
|  | class FilesBloc extends LoadableHydratedBloc<FilesEvent, FilesState, FilesRepository> { | ||||||
|  |   static const String basePath = '/'; | ||||||
|  |  | ||||||
|  |   FilesBloc() { | ||||||
|  |     add(Emit((state) => state.copyWith(currentFolder: basePath))); | ||||||
|  |     on<EnterFolder>((event, emit) { | ||||||
|  |       add(Emit((state) { | ||||||
|  |         log('setFolder'); | ||||||
|  |         return state.copyWith(currentFolder: event.absolutePath); | ||||||
|  |       }, fetch: true)); | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   List<File>? getVisibleFiles() => innerState?.files[innerState?.currentFolder]; | ||||||
|  |   String getCurrentFolder() => innerState?.currentFolder ?? basePath; | ||||||
|  |   String getCurrentFolderName() { | ||||||
|  |     var folder = innerState?.currentFolder.split('/').reversed.elementAt(1); | ||||||
|  |     return folder!.isEmpty ? 'Dateien' : folder; | ||||||
|  |   } | ||||||
|  |   bool canGoBack() => innerState?.currentFolder != basePath; | ||||||
|  |   String goBackLocation() { | ||||||
|  |     var pathSegments = innerState?.currentFolder.split(basePath) ?? []; | ||||||
|  |     if (pathSegments.isNotEmpty) { | ||||||
|  |       pathSegments.removeLast(); | ||||||
|  |       pathSegments.removeLast(); | ||||||
|  |     } | ||||||
|  |     return pathSegments.join(basePath) + basePath; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   FilesState fromNothing() => const FilesState(currentFolder: basePath, files: {}); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   FilesState fromStorage(Map<String, dynamic> json) => FilesState.fromJson(json); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Future<void> gatherData() async { | ||||||
|  |     var fetchFolder = getCurrentFolder(); | ||||||
|  |     log(fetchFolder); | ||||||
|  |     var files = await repo.getFileList(fetchFolder); | ||||||
|  |     var newFileMap = Map.of(innerState?.files ?? <String, List<File>>{}); | ||||||
|  |     newFileMap[fetchFolder] = files; | ||||||
|  |     if(fetchFolder != getCurrentFolder()) { | ||||||
|  |       log('Fetch aborted due to folder change (expected "$fetchFolder" got "${getCurrentFolder()}")'); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     add(DataGathered((state) => state.copyWith(files: newFileMap))); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   FilesRepository repository() => FilesRepository(); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Map<String, dynamic>? toStorage(FilesState state) => state.toJson(); | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										10
									
								
								lib/state/app/modules/files/bloc/files_event.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								lib/state/app/modules/files/bloc/files_event.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  |  | ||||||
|  | import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc_event.dart'; | ||||||
|  | import 'files_state.dart'; | ||||||
|  |  | ||||||
|  | sealed class FilesEvent extends LoadableHydratedBlocEvent<FilesState> {} | ||||||
|  | class EnterFolder extends FilesEvent { | ||||||
|  |   String absolutePath; | ||||||
|  |   EnterFolder(this.absolutePath); | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										29
									
								
								lib/state/app/modules/files/bloc/files_state.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								lib/state/app/modules/files/bloc/files_state.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | import 'package:freezed_annotation/freezed_annotation.dart'; | ||||||
|  |  | ||||||
|  | part 'files_state.freezed.dart'; | ||||||
|  | part 'files_state.g.dart'; | ||||||
|  |  | ||||||
|  | @freezed | ||||||
|  | class FilesState with _$FilesState { | ||||||
|  |   const factory FilesState({ | ||||||
|  |     required String currentFolder, | ||||||
|  |     required Map<String, List<File>> files, | ||||||
|  |   }) = _FilesState; | ||||||
|  |  | ||||||
|  |   factory FilesState.fromJson(Map<String, Object?> json) => _$FilesStateFromJson(json); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @freezed | ||||||
|  | class File with _$File { | ||||||
|  |   const factory File({ | ||||||
|  |     required String path, | ||||||
|  |     required bool isFolder, | ||||||
|  |     required String name, | ||||||
|  |     required DateTime? createdAt, | ||||||
|  |     required DateTime? updatedAt, | ||||||
|  |     required int? size, | ||||||
|  |     required String? mimeType, | ||||||
|  |   }) = _File; | ||||||
|  |  | ||||||
|  |   factory File.fromJson(Map<String, Object?> json) => _$FileFromJson(json); | ||||||
|  | } | ||||||
							
								
								
									
										439
									
								
								lib/state/app/modules/files/bloc/files_state.freezed.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										439
									
								
								lib/state/app/modules/files/bloc/files_state.freezed.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,439 @@ | |||||||
|  | // coverage:ignore-file | ||||||
|  | // GENERATED CODE - DO NOT MODIFY BY HAND | ||||||
|  | // ignore_for_file: type=lint | ||||||
|  | // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark | ||||||
|  |  | ||||||
|  | part of 'files_state.dart'; | ||||||
|  |  | ||||||
|  | // ************************************************************************** | ||||||
|  | // FreezedGenerator | ||||||
|  | // ************************************************************************** | ||||||
|  |  | ||||||
|  | T _$identity<T>(T value) => value; | ||||||
|  |  | ||||||
|  | final _privateConstructorUsedError = UnsupportedError( | ||||||
|  |     'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); | ||||||
|  |  | ||||||
|  | FilesState _$FilesStateFromJson(Map<String, dynamic> json) { | ||||||
|  |   return _FilesState.fromJson(json); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// @nodoc | ||||||
|  | mixin _$FilesState { | ||||||
|  |   String get currentFolder => throw _privateConstructorUsedError; | ||||||
|  |   Map<String, List<File>> get files => throw _privateConstructorUsedError; | ||||||
|  |  | ||||||
|  |   Map<String, dynamic> toJson() => throw _privateConstructorUsedError; | ||||||
|  |   @JsonKey(ignore: true) | ||||||
|  |   $FilesStateCopyWith<FilesState> get copyWith => | ||||||
|  |       throw _privateConstructorUsedError; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// @nodoc | ||||||
|  | abstract class $FilesStateCopyWith<$Res> { | ||||||
|  |   factory $FilesStateCopyWith( | ||||||
|  |           FilesState value, $Res Function(FilesState) then) = | ||||||
|  |       _$FilesStateCopyWithImpl<$Res, FilesState>; | ||||||
|  |   @useResult | ||||||
|  |   $Res call({String currentFolder, Map<String, List<File>> files}); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// @nodoc | ||||||
|  | class _$FilesStateCopyWithImpl<$Res, $Val extends FilesState> | ||||||
|  |     implements $FilesStateCopyWith<$Res> { | ||||||
|  |   _$FilesStateCopyWithImpl(this._value, this._then); | ||||||
|  |  | ||||||
|  |   // ignore: unused_field | ||||||
|  |   final $Val _value; | ||||||
|  |   // ignore: unused_field | ||||||
|  |   final $Res Function($Val) _then; | ||||||
|  |  | ||||||
|  |   @pragma('vm:prefer-inline') | ||||||
|  |   @override | ||||||
|  |   $Res call({ | ||||||
|  |     Object? currentFolder = null, | ||||||
|  |     Object? files = null, | ||||||
|  |   }) { | ||||||
|  |     return _then(_value.copyWith( | ||||||
|  |       currentFolder: null == currentFolder | ||||||
|  |           ? _value.currentFolder | ||||||
|  |           : currentFolder // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as String, | ||||||
|  |       files: null == files | ||||||
|  |           ? _value.files | ||||||
|  |           : files // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as Map<String, List<File>>, | ||||||
|  |     ) as $Val); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// @nodoc | ||||||
|  | abstract class _$$FilesStateImplCopyWith<$Res> | ||||||
|  |     implements $FilesStateCopyWith<$Res> { | ||||||
|  |   factory _$$FilesStateImplCopyWith( | ||||||
|  |           _$FilesStateImpl value, $Res Function(_$FilesStateImpl) then) = | ||||||
|  |       __$$FilesStateImplCopyWithImpl<$Res>; | ||||||
|  |   @override | ||||||
|  |   @useResult | ||||||
|  |   $Res call({String currentFolder, Map<String, List<File>> files}); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// @nodoc | ||||||
|  | class __$$FilesStateImplCopyWithImpl<$Res> | ||||||
|  |     extends _$FilesStateCopyWithImpl<$Res, _$FilesStateImpl> | ||||||
|  |     implements _$$FilesStateImplCopyWith<$Res> { | ||||||
|  |   __$$FilesStateImplCopyWithImpl( | ||||||
|  |       _$FilesStateImpl _value, $Res Function(_$FilesStateImpl) _then) | ||||||
|  |       : super(_value, _then); | ||||||
|  |  | ||||||
|  |   @pragma('vm:prefer-inline') | ||||||
|  |   @override | ||||||
|  |   $Res call({ | ||||||
|  |     Object? currentFolder = null, | ||||||
|  |     Object? files = null, | ||||||
|  |   }) { | ||||||
|  |     return _then(_$FilesStateImpl( | ||||||
|  |       currentFolder: null == currentFolder | ||||||
|  |           ? _value.currentFolder | ||||||
|  |           : currentFolder // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as String, | ||||||
|  |       files: null == files | ||||||
|  |           ? _value._files | ||||||
|  |           : files // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as Map<String, List<File>>, | ||||||
|  |     )); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// @nodoc | ||||||
|  | @JsonSerializable() | ||||||
|  | class _$FilesStateImpl implements _FilesState { | ||||||
|  |   const _$FilesStateImpl( | ||||||
|  |       {required this.currentFolder, | ||||||
|  |       required final Map<String, List<File>> files}) | ||||||
|  |       : _files = files; | ||||||
|  |  | ||||||
|  |   factory _$FilesStateImpl.fromJson(Map<String, dynamic> json) => | ||||||
|  |       _$$FilesStateImplFromJson(json); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   final String currentFolder; | ||||||
|  |   final Map<String, List<File>> _files; | ||||||
|  |   @override | ||||||
|  |   Map<String, List<File>> get files { | ||||||
|  |     if (_files is EqualUnmodifiableMapView) return _files; | ||||||
|  |     // ignore: implicit_dynamic_type | ||||||
|  |     return EqualUnmodifiableMapView(_files); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   String toString() { | ||||||
|  |     return 'FilesState(currentFolder: $currentFolder, files: $files)'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   bool operator ==(Object other) { | ||||||
|  |     return identical(this, other) || | ||||||
|  |         (other.runtimeType == runtimeType && | ||||||
|  |             other is _$FilesStateImpl && | ||||||
|  |             (identical(other.currentFolder, currentFolder) || | ||||||
|  |                 other.currentFolder == currentFolder) && | ||||||
|  |             const DeepCollectionEquality().equals(other._files, _files)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @JsonKey(ignore: true) | ||||||
|  |   @override | ||||||
|  |   int get hashCode => Object.hash( | ||||||
|  |       runtimeType, currentFolder, const DeepCollectionEquality().hash(_files)); | ||||||
|  |  | ||||||
|  |   @JsonKey(ignore: true) | ||||||
|  |   @override | ||||||
|  |   @pragma('vm:prefer-inline') | ||||||
|  |   _$$FilesStateImplCopyWith<_$FilesStateImpl> get copyWith => | ||||||
|  |       __$$FilesStateImplCopyWithImpl<_$FilesStateImpl>(this, _$identity); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Map<String, dynamic> toJson() { | ||||||
|  |     return _$$FilesStateImplToJson( | ||||||
|  |       this, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | abstract class _FilesState implements FilesState { | ||||||
|  |   const factory _FilesState( | ||||||
|  |       {required final String currentFolder, | ||||||
|  |       required final Map<String, List<File>> files}) = _$FilesStateImpl; | ||||||
|  |  | ||||||
|  |   factory _FilesState.fromJson(Map<String, dynamic> json) = | ||||||
|  |       _$FilesStateImpl.fromJson; | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   String get currentFolder; | ||||||
|  |   @override | ||||||
|  |   Map<String, List<File>> get files; | ||||||
|  |   @override | ||||||
|  |   @JsonKey(ignore: true) | ||||||
|  |   _$$FilesStateImplCopyWith<_$FilesStateImpl> get copyWith => | ||||||
|  |       throw _privateConstructorUsedError; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | File _$FileFromJson(Map<String, dynamic> json) { | ||||||
|  |   return _File.fromJson(json); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// @nodoc | ||||||
|  | mixin _$File { | ||||||
|  |   String get path => throw _privateConstructorUsedError; | ||||||
|  |   bool get isFolder => throw _privateConstructorUsedError; | ||||||
|  |   String get name => throw _privateConstructorUsedError; | ||||||
|  |   DateTime? get createdAt => throw _privateConstructorUsedError; | ||||||
|  |   DateTime? get updatedAt => throw _privateConstructorUsedError; | ||||||
|  |   int? get size => throw _privateConstructorUsedError; | ||||||
|  |   String? get mimeType => throw _privateConstructorUsedError; | ||||||
|  |  | ||||||
|  |   Map<String, dynamic> toJson() => throw _privateConstructorUsedError; | ||||||
|  |   @JsonKey(ignore: true) | ||||||
|  |   $FileCopyWith<File> get copyWith => throw _privateConstructorUsedError; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// @nodoc | ||||||
|  | abstract class $FileCopyWith<$Res> { | ||||||
|  |   factory $FileCopyWith(File value, $Res Function(File) then) = | ||||||
|  |       _$FileCopyWithImpl<$Res, File>; | ||||||
|  |   @useResult | ||||||
|  |   $Res call( | ||||||
|  |       {String path, | ||||||
|  |       bool isFolder, | ||||||
|  |       String name, | ||||||
|  |       DateTime? createdAt, | ||||||
|  |       DateTime? updatedAt, | ||||||
|  |       int? size, | ||||||
|  |       String? mimeType}); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// @nodoc | ||||||
|  | class _$FileCopyWithImpl<$Res, $Val extends File> | ||||||
|  |     implements $FileCopyWith<$Res> { | ||||||
|  |   _$FileCopyWithImpl(this._value, this._then); | ||||||
|  |  | ||||||
|  |   // ignore: unused_field | ||||||
|  |   final $Val _value; | ||||||
|  |   // ignore: unused_field | ||||||
|  |   final $Res Function($Val) _then; | ||||||
|  |  | ||||||
|  |   @pragma('vm:prefer-inline') | ||||||
|  |   @override | ||||||
|  |   $Res call({ | ||||||
|  |     Object? path = null, | ||||||
|  |     Object? isFolder = null, | ||||||
|  |     Object? name = null, | ||||||
|  |     Object? createdAt = freezed, | ||||||
|  |     Object? updatedAt = freezed, | ||||||
|  |     Object? size = freezed, | ||||||
|  |     Object? mimeType = freezed, | ||||||
|  |   }) { | ||||||
|  |     return _then(_value.copyWith( | ||||||
|  |       path: null == path | ||||||
|  |           ? _value.path | ||||||
|  |           : path // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as String, | ||||||
|  |       isFolder: null == isFolder | ||||||
|  |           ? _value.isFolder | ||||||
|  |           : isFolder // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as bool, | ||||||
|  |       name: null == name | ||||||
|  |           ? _value.name | ||||||
|  |           : name // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as String, | ||||||
|  |       createdAt: freezed == createdAt | ||||||
|  |           ? _value.createdAt | ||||||
|  |           : createdAt // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as DateTime?, | ||||||
|  |       updatedAt: freezed == updatedAt | ||||||
|  |           ? _value.updatedAt | ||||||
|  |           : updatedAt // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as DateTime?, | ||||||
|  |       size: freezed == size | ||||||
|  |           ? _value.size | ||||||
|  |           : size // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as int?, | ||||||
|  |       mimeType: freezed == mimeType | ||||||
|  |           ? _value.mimeType | ||||||
|  |           : mimeType // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as String?, | ||||||
|  |     ) as $Val); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// @nodoc | ||||||
|  | abstract class _$$FileImplCopyWith<$Res> implements $FileCopyWith<$Res> { | ||||||
|  |   factory _$$FileImplCopyWith( | ||||||
|  |           _$FileImpl value, $Res Function(_$FileImpl) then) = | ||||||
|  |       __$$FileImplCopyWithImpl<$Res>; | ||||||
|  |   @override | ||||||
|  |   @useResult | ||||||
|  |   $Res call( | ||||||
|  |       {String path, | ||||||
|  |       bool isFolder, | ||||||
|  |       String name, | ||||||
|  |       DateTime? createdAt, | ||||||
|  |       DateTime? updatedAt, | ||||||
|  |       int? size, | ||||||
|  |       String? mimeType}); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// @nodoc | ||||||
|  | class __$$FileImplCopyWithImpl<$Res> | ||||||
|  |     extends _$FileCopyWithImpl<$Res, _$FileImpl> | ||||||
|  |     implements _$$FileImplCopyWith<$Res> { | ||||||
|  |   __$$FileImplCopyWithImpl(_$FileImpl _value, $Res Function(_$FileImpl) _then) | ||||||
|  |       : super(_value, _then); | ||||||
|  |  | ||||||
|  |   @pragma('vm:prefer-inline') | ||||||
|  |   @override | ||||||
|  |   $Res call({ | ||||||
|  |     Object? path = null, | ||||||
|  |     Object? isFolder = null, | ||||||
|  |     Object? name = null, | ||||||
|  |     Object? createdAt = freezed, | ||||||
|  |     Object? updatedAt = freezed, | ||||||
|  |     Object? size = freezed, | ||||||
|  |     Object? mimeType = freezed, | ||||||
|  |   }) { | ||||||
|  |     return _then(_$FileImpl( | ||||||
|  |       path: null == path | ||||||
|  |           ? _value.path | ||||||
|  |           : path // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as String, | ||||||
|  |       isFolder: null == isFolder | ||||||
|  |           ? _value.isFolder | ||||||
|  |           : isFolder // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as bool, | ||||||
|  |       name: null == name | ||||||
|  |           ? _value.name | ||||||
|  |           : name // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as String, | ||||||
|  |       createdAt: freezed == createdAt | ||||||
|  |           ? _value.createdAt | ||||||
|  |           : createdAt // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as DateTime?, | ||||||
|  |       updatedAt: freezed == updatedAt | ||||||
|  |           ? _value.updatedAt | ||||||
|  |           : updatedAt // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as DateTime?, | ||||||
|  |       size: freezed == size | ||||||
|  |           ? _value.size | ||||||
|  |           : size // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as int?, | ||||||
|  |       mimeType: freezed == mimeType | ||||||
|  |           ? _value.mimeType | ||||||
|  |           : mimeType // ignore: cast_nullable_to_non_nullable | ||||||
|  |               as String?, | ||||||
|  |     )); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// @nodoc | ||||||
|  | @JsonSerializable() | ||||||
|  | class _$FileImpl implements _File { | ||||||
|  |   const _$FileImpl( | ||||||
|  |       {required this.path, | ||||||
|  |       required this.isFolder, | ||||||
|  |       required this.name, | ||||||
|  |       required this.createdAt, | ||||||
|  |       required this.updatedAt, | ||||||
|  |       required this.size, | ||||||
|  |       required this.mimeType}); | ||||||
|  |  | ||||||
|  |   factory _$FileImpl.fromJson(Map<String, dynamic> json) => | ||||||
|  |       _$$FileImplFromJson(json); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   final String path; | ||||||
|  |   @override | ||||||
|  |   final bool isFolder; | ||||||
|  |   @override | ||||||
|  |   final String name; | ||||||
|  |   @override | ||||||
|  |   final DateTime? createdAt; | ||||||
|  |   @override | ||||||
|  |   final DateTime? updatedAt; | ||||||
|  |   @override | ||||||
|  |   final int? size; | ||||||
|  |   @override | ||||||
|  |   final String? mimeType; | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   String toString() { | ||||||
|  |     return 'File(path: $path, isFolder: $isFolder, name: $name, createdAt: $createdAt, updatedAt: $updatedAt, size: $size, mimeType: $mimeType)'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   bool operator ==(Object other) { | ||||||
|  |     return identical(this, other) || | ||||||
|  |         (other.runtimeType == runtimeType && | ||||||
|  |             other is _$FileImpl && | ||||||
|  |             (identical(other.path, path) || other.path == path) && | ||||||
|  |             (identical(other.isFolder, isFolder) || | ||||||
|  |                 other.isFolder == isFolder) && | ||||||
|  |             (identical(other.name, name) || other.name == name) && | ||||||
|  |             (identical(other.createdAt, createdAt) || | ||||||
|  |                 other.createdAt == createdAt) && | ||||||
|  |             (identical(other.updatedAt, updatedAt) || | ||||||
|  |                 other.updatedAt == updatedAt) && | ||||||
|  |             (identical(other.size, size) || other.size == size) && | ||||||
|  |             (identical(other.mimeType, mimeType) || | ||||||
|  |                 other.mimeType == mimeType)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @JsonKey(ignore: true) | ||||||
|  |   @override | ||||||
|  |   int get hashCode => Object.hash( | ||||||
|  |       runtimeType, path, isFolder, name, createdAt, updatedAt, size, mimeType); | ||||||
|  |  | ||||||
|  |   @JsonKey(ignore: true) | ||||||
|  |   @override | ||||||
|  |   @pragma('vm:prefer-inline') | ||||||
|  |   _$$FileImplCopyWith<_$FileImpl> get copyWith => | ||||||
|  |       __$$FileImplCopyWithImpl<_$FileImpl>(this, _$identity); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Map<String, dynamic> toJson() { | ||||||
|  |     return _$$FileImplToJson( | ||||||
|  |       this, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | abstract class _File implements File { | ||||||
|  |   const factory _File( | ||||||
|  |       {required final String path, | ||||||
|  |       required final bool isFolder, | ||||||
|  |       required final String name, | ||||||
|  |       required final DateTime? createdAt, | ||||||
|  |       required final DateTime? updatedAt, | ||||||
|  |       required final int? size, | ||||||
|  |       required final String? mimeType}) = _$FileImpl; | ||||||
|  |  | ||||||
|  |   factory _File.fromJson(Map<String, dynamic> json) = _$FileImpl.fromJson; | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   String get path; | ||||||
|  |   @override | ||||||
|  |   bool get isFolder; | ||||||
|  |   @override | ||||||
|  |   String get name; | ||||||
|  |   @override | ||||||
|  |   DateTime? get createdAt; | ||||||
|  |   @override | ||||||
|  |   DateTime? get updatedAt; | ||||||
|  |   @override | ||||||
|  |   int? get size; | ||||||
|  |   @override | ||||||
|  |   String? get mimeType; | ||||||
|  |   @override | ||||||
|  |   @JsonKey(ignore: true) | ||||||
|  |   _$$FileImplCopyWith<_$FileImpl> get copyWith => | ||||||
|  |       throw _privateConstructorUsedError; | ||||||
|  | } | ||||||
							
								
								
									
										50
									
								
								lib/state/app/modules/files/bloc/files_state.g.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								lib/state/app/modules/files/bloc/files_state.g.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | |||||||
|  | // GENERATED CODE - DO NOT MODIFY BY HAND | ||||||
|  |  | ||||||
|  | part of 'files_state.dart'; | ||||||
|  |  | ||||||
|  | // ************************************************************************** | ||||||
|  | // JsonSerializableGenerator | ||||||
|  | // ************************************************************************** | ||||||
|  |  | ||||||
|  | _$FilesStateImpl _$$FilesStateImplFromJson(Map<String, dynamic> json) => | ||||||
|  |     _$FilesStateImpl( | ||||||
|  |       currentFolder: json['currentFolder'] as String, | ||||||
|  |       files: (json['files'] as Map<String, dynamic>).map( | ||||||
|  |         (k, e) => MapEntry( | ||||||
|  |             k, | ||||||
|  |             (e as List<dynamic>) | ||||||
|  |                 .map((e) => File.fromJson(e as Map<String, dynamic>)) | ||||||
|  |                 .toList()), | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  | Map<String, dynamic> _$$FilesStateImplToJson(_$FilesStateImpl instance) => | ||||||
|  |     <String, dynamic>{ | ||||||
|  |       'currentFolder': instance.currentFolder, | ||||||
|  |       'files': instance.files, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  | _$FileImpl _$$FileImplFromJson(Map<String, dynamic> json) => _$FileImpl( | ||||||
|  |       path: json['path'] as String, | ||||||
|  |       isFolder: json['isFolder'] as bool, | ||||||
|  |       name: json['name'] as String, | ||||||
|  |       createdAt: json['createdAt'] == null | ||||||
|  |           ? null | ||||||
|  |           : DateTime.parse(json['createdAt'] as String), | ||||||
|  |       updatedAt: json['updatedAt'] == null | ||||||
|  |           ? null | ||||||
|  |           : DateTime.parse(json['updatedAt'] as String), | ||||||
|  |       size: (json['size'] as num?)?.toInt(), | ||||||
|  |       mimeType: json['mimeType'] as String?, | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  | Map<String, dynamic> _$$FileImplToJson(_$FileImpl instance) => | ||||||
|  |     <String, dynamic>{ | ||||||
|  |       'path': instance.path, | ||||||
|  |       'isFolder': instance.isFolder, | ||||||
|  |       'name': instance.name, | ||||||
|  |       'createdAt': instance.createdAt?.toIso8601String(), | ||||||
|  |       'updatedAt': instance.updatedAt?.toIso8601String(), | ||||||
|  |       'size': instance.size, | ||||||
|  |       'mimeType': instance.mimeType, | ||||||
|  |     }; | ||||||
							
								
								
									
										31
									
								
								lib/state/app/modules/files/repository/files_repository.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								lib/state/app/modules/files/repository/files_repository.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  |  | ||||||
|  | import 'package:nextcloud/nextcloud.dart'; | ||||||
|  |  | ||||||
|  | import '../../../../../api/marianumcloud/webdav/webdavApi.dart'; | ||||||
|  | import '../../../infrastructure/repository/repository.dart'; | ||||||
|  | import '../bloc/files_state.dart'; | ||||||
|  |  | ||||||
|  | class FilesRepository extends Repository<FilesState> { | ||||||
|  |   Future<List<File>> getFileList(String path) async { | ||||||
|  |     var webdav = await WebdavApi.webdav; | ||||||
|  |     var response = await webdav.propfind(PathUri.parse(path)); // TODO move to custom data loader | ||||||
|  |     var davFiles = response.toWebDavFiles(); | ||||||
|  |  | ||||||
|  |     davFiles.removeWhere((file) { | ||||||
|  |       var filePath = file.path.path; | ||||||
|  |       return filePath.isEmpty || filePath == path; | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     var files = davFiles.map((davFile) => File( | ||||||
|  |       path: davFile.path.path, | ||||||
|  |       isFolder: davFile.isDirectory, | ||||||
|  |       name: davFile.name, | ||||||
|  |       createdAt: davFile.createdDate, | ||||||
|  |       updatedAt: davFile.lastModified, | ||||||
|  |       size: davFile.size, | ||||||
|  |       mimeType: davFile.mimeType | ||||||
|  |     )); | ||||||
|  |  | ||||||
|  |     return files.toList(); | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										67
									
								
								lib/state/app/modules/files/view/files_view.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								lib/state/app/modules/files/view/files_view.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | |||||||
|  | import 'dart:developer'; | ||||||
|  |  | ||||||
|  | import 'package:filesize/filesize.dart'; | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  | import 'package:jiffy/jiffy.dart'; | ||||||
|  |  | ||||||
|  | import '../../../../../widget/centeredLeading.dart'; | ||||||
|  | import '../../../../../widget/list_view_util.dart'; | ||||||
|  | import '../../../infrastructure/loadableState/loadable_state.dart'; | ||||||
|  | import '../../../infrastructure/loadableState/view/loadable_state_consumer.dart'; | ||||||
|  | import '../../../infrastructure/utilityWidgets/bloc_module.dart'; | ||||||
|  | import '../bloc/files_bloc.dart'; | ||||||
|  | import '../bloc/files_event.dart'; | ||||||
|  | import '../bloc/files_state.dart'; | ||||||
|  |  | ||||||
|  | class FilesView extends StatelessWidget { | ||||||
|  |   const FilesView({super.key}); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) => BlocModule<FilesBloc, LoadableState<FilesState>>( | ||||||
|  |     create: (context) => FilesBloc(), | ||||||
|  |     autoRebuild: true, | ||||||
|  |     child: (context, bloc, state) { | ||||||
|  |       var goBackButton = !bloc.canGoBack() ? null : IconButton( | ||||||
|  |         icon: const Icon(Icons.arrow_back), | ||||||
|  |         onPressed: () { | ||||||
|  |           bloc.add(EnterFolder(bloc.goBackLocation())); | ||||||
|  |         }, | ||||||
|  |       ); | ||||||
|  |       return PopScope( | ||||||
|  |         canPop: false, | ||||||
|  |         onPopInvoked: (didPop) => bloc.add(EnterFolder(bloc.goBackLocation())), | ||||||
|  |         child: Scaffold( | ||||||
|  |             appBar: AppBar( | ||||||
|  |               leading: goBackButton, | ||||||
|  |               title: Text(bloc.getCurrentFolderName()), | ||||||
|  |  | ||||||
|  |  | ||||||
|  |               actions: [ | ||||||
|  |                 IconButton(onPressed: () { | ||||||
|  |                   log(bloc.innerState?.toJson().toString() ?? 'leer'); | ||||||
|  |                 }, icon: const Icon(Icons.bug_report)), | ||||||
|  |                 IconButton(onPressed: () { | ||||||
|  |                   bloc.add(EnterFolder('/')); | ||||||
|  |                 }, icon: const Icon(Icons.home)), | ||||||
|  |               ], | ||||||
|  |             ), | ||||||
|  |             body: LoadableStateConsumer<FilesBloc, FilesState>( | ||||||
|  |                 child: (state, loading) => ListViewUtil.fromList<File>(bloc.getVisibleFiles(), (file) => ListTile( | ||||||
|  |                   leading: CenteredLeading(Icon(file.isFolder ? Icons.folder : Icons.description_outlined)), | ||||||
|  |                   title: Text(file.name), | ||||||
|  |                   subtitle: file.isFolder | ||||||
|  |                       ? Text('geändert ${Jiffy.parseFromDateTime(file.updatedAt ?? DateTime.now()).fromNow()}') | ||||||
|  |                       : Text('${filesize(file.size)}, ${Jiffy.parseFromDateTime(file.updatedAt ?? DateTime.now()).fromNow()}'), | ||||||
|  |                   trailing: Icon(file.isFolder ? Icons.arrow_right : null), | ||||||
|  |                   onTap: () { | ||||||
|  |                     log(file.path); | ||||||
|  |                     if(!file.isFolder) return; | ||||||
|  |                     bloc.add(EnterFolder(file.path)); | ||||||
|  |                   }, | ||||||
|  |                 )) | ||||||
|  |             ) | ||||||
|  |         ), | ||||||
|  |       ); | ||||||
|  |     }, | ||||||
|  |   ); | ||||||
|  | } | ||||||
| @@ -11,7 +11,9 @@ _$GradeAveragesStateImpl _$$GradeAveragesStateImplFromJson( | |||||||
|     _$GradeAveragesStateImpl( |     _$GradeAveragesStateImpl( | ||||||
|       gradingSystem: $enumDecode( |       gradingSystem: $enumDecode( | ||||||
|           _$GradeAveragesGradingSystemEnumMap, json['gradingSystem']), |           _$GradeAveragesGradingSystemEnumMap, json['gradingSystem']), | ||||||
|       grades: (json['grades'] as List<dynamic>).map((e) => e as int).toList(), |       grades: (json['grades'] as List<dynamic>) | ||||||
|  |           .map((e) => (e as num).toInt()) | ||||||
|  |           .toList(), | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
| Map<String, dynamic> _$$GradeAveragesStateImplToJson( | Map<String, dynamic> _$$GradeAveragesStateImplToJson( | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ _$HolidayImpl _$$HolidayImplFromJson(Map<String, dynamic> json) => | |||||||
|     _$HolidayImpl( |     _$HolidayImpl( | ||||||
|       start: json['start'] as String, |       start: json['start'] as String, | ||||||
|       end: json['end'] as String, |       end: json['end'] as String, | ||||||
|       year: json['year'] as int, |       year: (json['year'] as num).toInt(), | ||||||
|       stateCode: json['stateCode'] as String, |       stateCode: json['stateCode'] as String, | ||||||
|       name: json['name'] as String, |       name: json['name'] as String, | ||||||
|       slug: json['slug'] as String, |       slug: json['slug'] as String, | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| import 'package:dio/dio.dart'; | import 'package:dio/dio.dart'; | ||||||
|  |  | ||||||
| import '../../../basis/dataloader/holiday_data_loader.dart'; | import '../../../basis/dataloader/holiday_data_loader.dart'; | ||||||
| import '../../../infrastructure/dataLoader/data_loader.dart'; | import '../../../infrastructure/dataLoader/http_data_loader.dart'; | ||||||
| import '../bloc/holidays_state.dart'; | import '../bloc/holidays_state.dart'; | ||||||
|  |  | ||||||
| class HolidaysGetHolidays extends HolidayDataLoader<List<Holiday>> { | class HolidaysGetHolidays extends HolidayDataLoader<List<Holiday>> { | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import 'package:dio/dio.dart'; | import 'package:dio/dio.dart'; | ||||||
|  |  | ||||||
| import '../../../infrastructure/dataLoader/data_loader.dart'; | import '../../../infrastructure/dataLoader/http_data_loader.dart'; | ||||||
| import '../../../basis/dataloader/mhsl_data_loader.dart'; | import '../../../basis/dataloader/mhsl_data_loader.dart'; | ||||||
| import '../bloc/marianum_message_state.dart'; | import '../bloc/marianum_message_state.dart'; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user