api and storage restructure

This commit is contained in:
2026-05-05 22:00:07 +02:00
parent 4f796dac2e
commit 9b5a70b285
53 changed files with 318 additions and 460 deletions
+11 -19
View File
@@ -1,26 +1,18 @@
import 'dart:convert';
import '../requestCache.dart';
import 'getHolidays.dart';
import 'getHolidaysResponse.dart';
class GetHolidaysCache extends RequestCache<GetHolidaysResponse> {
GetHolidaysCache({void Function(GetHolidaysResponse)? onUpdate, bool? renew}) : super(RequestCache.cacheDay, onUpdate, renew: renew) {
class GetHolidaysCache extends SimpleCache<GetHolidaysResponse> {
GetHolidaysCache({super.onUpdate, super.renew})
: super(
cacheTime: RequestCache.cacheDay,
loader: () => GetHolidays().query(),
fromJson: (json) => GetHolidaysResponse(
(json['data'] as List)
.map((i) => GetHolidaysResponseObject.fromJson(i as Map<String, dynamic>))
.toList(),
),
) {
start('state-holidays');
}
@override
GetHolidaysResponse onLocalData(String json) {
List<dynamic> parsedListJson = jsonDecode(json)['data'];
return GetHolidaysResponse(
List<GetHolidaysResponseObject>.from(
parsedListJson.map<GetHolidaysResponseObject>(
(i) => GetHolidaysResponseObject.fromJson(i as Map<String, dynamic>)
)
)
);
}
@override
Future<GetHolidaysResponse> onLoad() => GetHolidays().query();
}
@@ -3,31 +3,25 @@ import 'dart:io';
import 'package:http/http.dart' as http;
import '../../../model/account_data.dart';
import '../../../model/endpoint_data.dart';
import '../nextcloud_ocs.dart';
import 'autocompleteResponse.dart';
class AutocompleteApi {
Future<AutocompleteResponse> find(String query) async {
var getParameters = <String, dynamic>{
final endpoint = NextcloudOcs.uri(
'core/autocomplete/get',
queryParameters: {
'search': query,
'itemType': ' ',
'itemId': ' ',
'shareTypes[]': ['0'],
'limit': '10',
};
var headers = <String, String>{};
headers.putIfAbsent('Accept', () => 'application/json');
headers.putIfAbsent('OCS-APIRequest', () => 'true');
headers.putIfAbsent('Authorization', AccountData().getBasicAuthHeader);
var endpoint = Uri.https(EndpointData().nextcloud().domain, '${EndpointData().nextcloud().path}/ocs/v2.php/core/autocomplete/get', getParameters);
var response = await http.get(endpoint, headers: headers);
if(response.statusCode != HttpStatus.ok) throw Exception('Api call failed with ${response.statusCode}: ${response.body}');
var result = response.body;
return AutocompleteResponse.fromJson(jsonDecode(result)['ocs']);
},
);
final response = await http.get(endpoint, headers: NextcloudOcs.headers());
if (response.statusCode != HttpStatus.ok) {
throw Exception('Api call failed with ${response.statusCode}: ${response.body}');
}
return AutocompleteResponse.fromJson(jsonDecode(response.body)['ocs']);
}
}
@@ -2,21 +2,17 @@ import 'dart:io';
import 'package:http/http.dart' as http;
import '../../../model/account_data.dart';
import '../../../model/endpoint_data.dart';
import '../nextcloud_ocs.dart';
import 'fileSharingApiParams.dart';
class FileSharingApi {
Future<void> share(FileSharingApiParams query) async {
var headers = <String, String>{};
headers.putIfAbsent('Accept', () => 'application/json');
headers.putIfAbsent('OCS-APIRequest', () => 'true');
headers.putIfAbsent('Authorization', AccountData().getBasicAuthHeader);
var endpoint = Uri.https(EndpointData().nextcloud().domain, '${EndpointData().nextcloud().path}/ocs/v2.php/apps/files_sharing/api/v1/shares', query.toJson().map((key, value) => MapEntry(key, value.toString())));
var response = await http.post(endpoint, headers: headers);
if(response.statusCode != HttpStatus.ok) {
final endpoint = NextcloudOcs.uri(
'apps/files_sharing/api/v1/shares',
queryParameters: query.toJson(),
);
final response = await http.post(endpoint, headers: NextcloudOcs.headers());
if (response.statusCode != HttpStatus.ok) {
throw Exception('Api call failed with ${response.statusCode}: ${response.body}');
}
}
+33
View File
@@ -0,0 +1,33 @@
import '../../model/account_data.dart';
import '../../model/endpoint_data.dart';
/// Shared helpers for Nextcloud OCS v2 endpoints.
///
/// Three call sites previously duplicated the same header dictionary and the
/// same URI scaffolding (TalkApi, AutocompleteApi, FileSharingApi). Anything
/// that talks to `https://<domain>/<base>/ocs/v2.php/...` should go through
/// these two helpers so additions like a new header or a different auth
/// scheme only need to change here.
class NextcloudOcs {
NextcloudOcs._();
/// The standard OCS request header set: JSON accept, OCS API marker,
/// HTTP Basic auth from the active [AccountData].
static Map<String, String> headers() => {
'Accept': 'application/json',
'OCS-APIRequest': 'true',
'Authorization': AccountData().getBasicAuthHeader(),
};
/// Builds an OCS URI by appending [pathSuffix] under `/ocs/v2.php/` of
/// the configured Nextcloud endpoint. Query parameters are converted to
/// strings (Uri rejects non-string values).
static Uri uri(String pathSuffix, {Map<String, dynamic>? queryParameters}) {
final endpoint = EndpointData().nextcloud();
return Uri.https(
endpoint.domain,
'${endpoint.path}/ocs/v2.php/$pathSuffix',
queryParameters?.map((key, value) => MapEntry(key, value.toString())),
);
}
}
@@ -0,0 +1,50 @@
import 'package:http/http.dart' as http;
import '../../../apiParams.dart';
import '../../../apiResponse.dart';
import '../talkApi.dart';
/// Small POST/DELETE-only Talk endpoints that have no response payload.
/// Each class extends [TalkApi] with `assemble` returning `null`. They share
/// no state — they're collected here purely to avoid eight near-empty files.
class SetFavorite extends TalkApi {
final String chatToken;
final bool favoriteState;
SetFavorite(this.chatToken, this.favoriteState) : super('v4/room/$chatToken/favorite', null);
@override
ApiResponse? assemble(String raw) => null;
@override
Future<http.Response> request(Uri uri, ApiParams? body, Map<String, String>? headers) =>
favoriteState ? http.post(uri, headers: headers) : http.delete(uri, headers: headers);
}
class LeaveRoom extends TalkApi {
final String chatToken;
LeaveRoom(this.chatToken) : super('v4/room/$chatToken/participants/self', null);
@override
ApiResponse? assemble(String raw) => null;
@override
Future<http.Response> request(Uri uri, ApiParams? body, Map<String, String>? headers) =>
http.delete(uri, headers: headers);
}
class DeleteMessage extends TalkApi {
final String chatToken;
final int messageId;
DeleteMessage(this.chatToken, this.messageId) : super('v1/chat/$chatToken/$messageId', null);
@override
ApiResponse? assemble(String raw) => null;
@override
Future<http.Response> request(Uri uri, ApiParams? body, Map<String, String>? headers) =>
http.delete(uri, headers: headers);
}
@@ -1,36 +1,26 @@
import 'dart:convert';
import '../../../requestCache.dart';
import 'getChat.dart';
import 'getChatParams.dart';
import 'getChatResponse.dart';
class GetChatCache extends RequestCache<GetChatResponse> {
String chatToken;
class GetChatCache extends SimpleCache<GetChatResponse> {
GetChatCache({
required void Function(GetChatResponse) onUpdate,
void Function(Exception)? onError,
required this.chatToken,
super.onError,
required String chatToken,
}) : super(
RequestCache.cacheNothing,
onUpdate,
onError: onError ?? RequestCache.ignore,
) {
start('nc-chat-$chatToken');
}
@override
Future<GetChatResponse> onLoad() => GetChat(
cacheTime: RequestCache.cacheNothing,
loader: () => GetChat(
chatToken,
GetChatParams(
lookIntoFuture: GetChatParamsSwitch.off,
setReadMarker: GetChatParamsSwitch.on,
limit: 200,
)
).run();
@override
GetChatResponse onLocalData(String json) => GetChatResponse.fromJson(jsonDecode(json));
),
).run(),
fromJson: GetChatResponse.fromJson,
onUpdate: onUpdate,
) {
start('nc-chat-$chatToken');
}
}
@@ -1,18 +0,0 @@
import 'package:http/http.dart' as http;
import 'package:http/http.dart';
import '../../../apiParams.dart';
import '../talkApi.dart';
class DeleteMessage extends TalkApi {
String chatToken;
int messageId;
DeleteMessage(this.chatToken, this.messageId) : super('v1/chat/$chatToken/$messageId', null);
@override
assemble(String raw) => null;
@override
Future<Response>? request(Uri uri, ApiParams? body, Map<String, String>? headers) => http.delete(uri, headers: headers);
}
@@ -1,22 +1,17 @@
import 'dart:convert';
import '../../../requestCache.dart';
import 'getParticipants.dart';
import 'getParticipantsResponse.dart';
class GetParticipantsCache extends RequestCache<GetParticipantsResponse> {
String chatToken;
GetParticipantsCache({required void Function(GetParticipantsResponse) onUpdate, required this.chatToken}) : super(RequestCache.cacheNothing, onUpdate) {
class GetParticipantsCache extends SimpleCache<GetParticipantsResponse> {
GetParticipantsCache({
required void Function(GetParticipantsResponse) onUpdate,
required String chatToken,
}) : super(
cacheTime: RequestCache.cacheNothing,
loader: () => GetParticipants(chatToken).run(),
fromJson: GetParticipantsResponse.fromJson,
onUpdate: onUpdate,
) {
start('nc-chat-participants-$chatToken');
}
@override
Future<GetParticipantsResponse> onLoad() => GetParticipants(
chatToken,
).run();
@override
GetParticipantsResponse onLocalData(String json) => GetParticipantsResponse.fromJson(jsonDecode(json));
}
@@ -1,16 +0,0 @@
import 'package:http/http.dart' as http;
import 'package:http/http.dart';
import '../talkApi.dart';
class LeaveRoom extends TalkApi {
String chatToken;
LeaveRoom(this.chatToken) : super('v4/room/$chatToken/participants/self', null);
@override
assemble(String raw) => null;
@override
Future<Response> request(Uri uri, Object? body, Map<String, String>? headers) => http.delete(uri, headers: headers);
}
@@ -1,32 +1,15 @@
import 'dart:convert';
import '../../../requestCache.dart';
import 'getRoom.dart';
import 'getRoomParams.dart';
import 'getRoomResponse.dart';
class GetRoomCache extends RequestCache<GetRoomResponse> {
GetRoomCache({
void Function(GetRoomResponse)? onUpdate,
void Function(Exception)? onError,
bool? renew,
}) : super(
RequestCache.cacheMinute,
onUpdate,
onError: onError ?? RequestCache.ignore,
renew: renew,
class GetRoomCache extends SimpleCache<GetRoomResponse> {
GetRoomCache({super.onUpdate, super.onError, super.renew})
: super(
cacheTime: RequestCache.cacheMinute,
loader: () => GetRoom(GetRoomParams(includeStatus: true)).run(),
fromJson: GetRoomResponse.fromJson,
) {
start('nc-rooms');
}
@override
GetRoomResponse onLocalData(String json) => GetRoomResponse.fromJson(jsonDecode(json));
@override
Future<GetRoomResponse> onLoad() => GetRoom(
GetRoomParams(
includeStatus: true,
)
).run();
}
@@ -1,5 +0,0 @@
import '../../../apiResponse.dart';
class SendMessageResponse extends ApiResponse {
}
@@ -1,25 +0,0 @@
import 'package:http/http.dart' as http;
import 'package:http/http.dart';
import '../talkApi.dart';
class SetFavorite extends TalkApi {
String chatToken;
bool favoriteState;
SetFavorite(this.chatToken, this.favoriteState) : super('v4/room/$chatToken/favorite', null);
@override
assemble(String raw) => null;
@override
Future<Response> request(Uri uri, Object? body, Map<String, String>? headers) {
if(favoriteState) {
return http.post(uri, headers: headers);
} else {
return http.delete(uri, headers: headers);
}
}
}
+13 -22
View File
@@ -2,12 +2,11 @@ import 'dart:developer';
import 'package:http/http.dart' as http;
import '../../../model/account_data.dart';
import '../../../model/endpoint_data.dart';
import '../../apiError.dart';
import '../../apiParams.dart';
import '../../apiRequest.dart';
import '../../apiResponse.dart';
import '../nextcloud_ocs.dart';
enum TalkApiMethod {
get,
@@ -19,7 +18,7 @@ enum TalkApiMethod {
abstract class TalkApi<T extends ApiResponse?> extends ApiRequest {
String path;
ApiParams? body;
Map<String, String>? headers = {};
Map<String, String>? headers;
Map<String, dynamic>? getParameters;
http.Response? response;
@@ -30,36 +29,28 @@ abstract class TalkApi<T extends ApiResponse?> extends ApiRequest {
T assemble(String raw);
Future<T> run() async {
getParameters?.forEach((key, value) {
getParameters?.update(key, (value) => value.toString());
});
var endpoint = Uri.https(EndpointData().nextcloud().domain, '${EndpointData().nextcloud().path}/ocs/v2.php/apps/spreed/api/$path', getParameters);
headers ??= {};
headers?.putIfAbsent('Accept', () => 'application/json');
headers?.putIfAbsent('OCS-APIRequest', () => 'true');
headers?.putIfAbsent('Authorization', AccountData().getBasicAuthHeader);
final endpoint = NextcloudOcs.uri('apps/spreed/api/$path', queryParameters: getParameters);
final mergedHeaders = {...NextcloudOcs.headers(), ...?headers};
http.Response? data;
try {
data = await request(endpoint, body, headers);
if(data == null) throw Exception('No response Data');
if(data.statusCode >= 400 || data.statusCode < 200) throw Exception("Response status code '${data.statusCode}' might indicate an error");
} catch(e) {
data = await request(endpoint, body, mergedHeaders);
if (data == null) throw Exception('No response Data');
if (data.statusCode >= 400 || data.statusCode < 200) {
throw Exception("Response status code '${data.statusCode}' might indicate an error");
}
} catch (e) {
log(e.toString());
throw ApiError('Request $endpoint could not be dispatched: ${e.toString()}');
}
//dynamic jsonData = jsonDecode(data.body);
T assembled;
try {
assembled = assemble(data.body);
final assembled = assemble(data.body);
assembled?.headers = data.headers;
return assembled;
} catch (e) {
var message = 'Error assembling Talk API ${T.toString()} message: ${e.toString()} response with request body: $body and request headers: ${headers.toString()}';
final message = 'Error assembling Talk API ${T.toString()} message: ${e.toString()}'
' response with request body: $body and request headers: $mergedHeaders';
log(message);
throw Exception(message);
}
@@ -1,26 +0,0 @@
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:http/http.dart';
import '../getPoll/getPollStateResponse.dart';
import '../talkApi.dart';
import 'votePollParams.dart';
@Deprecated('VotePoll is broken')
class VotePoll extends TalkApi {
String token;
int pollId;
VotePoll({required this.token, required this.pollId, required VotePollParams params}) : super('v1/poll/$token/$pollId', params);
@override
GetPollStateResponse assemble(String raw) => GetPollStateResponse.fromJson(jsonDecode(raw)['ocs']);
@override
Future<Response>? request(Uri uri, Object? body, Map<String, String>? headers) {
if(body is VotePollParams) {
return http.post(uri, headers: headers, body: body.toJson().toString());
}
return null;
}
}
@@ -1,15 +0,0 @@
import 'package:json_annotation/json_annotation.dart';
import '../../../apiParams.dart';
part 'votePollParams.g.dart';
@JsonSerializable()
@Deprecated('VotePoll is broken')
class VotePollParams extends ApiParams {
List<int> optionIds;
VotePollParams({required this.optionIds});
factory VotePollParams.fromJson(Map<String, dynamic> json) => _$VotePollParamsFromJson(json);
Map<String, dynamic> toJson() => _$VotePollParamsToJson(this);
}
@@ -1,17 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'votePollParams.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
VotePollParams _$VotePollParamsFromJson(Map<String, dynamic> json) =>
VotePollParams(
optionIds: (json['optionIds'] as List<dynamic>)
.map((e) => (e as num).toInt())
.toList(),
);
Map<String, dynamic> _$VotePollParamsToJson(VotePollParams instance) =>
<String, dynamic>{'optionIds': instance.optionIds};
@@ -6,34 +6,20 @@ import 'listFiles.dart';
import 'listFilesParams.dart';
import 'listFilesResponse.dart';
class ListFilesCache extends RequestCache<ListFilesResponse> {
String path;
class ListFilesCache extends SimpleCache<ListFilesResponse> {
ListFilesCache({
required void Function(ListFilesResponse) onUpdate,
void Function(ListFilesResponse)? onCacheData,
void Function(ListFilesResponse)? onNetworkData,
void Function(Exception)? onError,
required this.path,
super.onCacheData,
super.onNetworkData,
super.onError,
required String path,
}) : super(
RequestCache.cacheNothing,
onUpdate,
onError: onError ?? RequestCache.ignore,
onCacheData: onCacheData,
onNetworkData: onNetworkData,
cacheTime: RequestCache.cacheNothing,
loader: () => ListFiles(ListFilesParams(path)).run(),
fromJson: ListFilesResponse.fromJson,
onUpdate: onUpdate,
) {
var bytes = utf8.encode('MarianumMobile-$path');
var cacheName = md5.convert(bytes).toString();
final cacheName = md5.convert(utf8.encode('MarianumMobile-$path')).toString();
start('wd-folder-$cacheName');
}
@override
Future<ListFilesResponse> onLoad() async {
var data = await ListFiles(ListFilesParams(path)).run();
return data;
}
@override
ListFilesResponse onLocalData(String json) => ListFilesResponse.fromJson(jsonDecode(json));
}
@@ -1,17 +1,14 @@
import 'dart:convert';
import '../../../requestCache.dart';
import 'getBreakers.dart';
import 'getBreakersResponse.dart';
class GetBreakersCache extends RequestCache<GetBreakersResponse> {
GetBreakersCache({void Function(GetBreakersResponse)? onUpdate, bool? renew}) : super(RequestCache.cacheMinute, onUpdate, renew: renew) {
class GetBreakersCache extends SimpleCache<GetBreakersResponse> {
GetBreakersCache({super.onUpdate, super.renew})
: super(
cacheTime: RequestCache.cacheMinute,
loader: () => GetBreakers().run(),
fromJson: GetBreakersResponse.fromJson,
) {
start('breakers');
}
@override
GetBreakersResponse onLocalData(String json) => GetBreakersResponse.fromJson(jsonDecode(json));
@override
Future<GetBreakersResponse> onLoad() => GetBreakers().run();
}
@@ -1,30 +1,19 @@
import 'dart:convert';
import '../../../requestCache.dart';
import 'getCustomTimetableEvent.dart';
import 'getCustomTimetableEventParams.dart';
import 'getCustomTimetableEventResponse.dart';
class GetCustomTimetableEventCache extends RequestCache<GetCustomTimetableEventResponse> {
GetCustomTimetableEventParams params;
class GetCustomTimetableEventCache extends SimpleCache<GetCustomTimetableEventResponse> {
GetCustomTimetableEventCache(
this.params, {
void Function(GetCustomTimetableEventResponse)? onUpdate,
void Function(Exception)? onError,
bool? renew,
GetCustomTimetableEventParams params, {
super.onUpdate,
super.onError,
super.renew,
}) : super(
RequestCache.cacheMinute,
onUpdate,
onError: onError ?? RequestCache.ignore,
renew: renew,
cacheTime: RequestCache.cacheMinute,
loader: () => GetCustomTimetableEvent(params).run(),
fromJson: GetCustomTimetableEventResponse.fromJson,
) {
start('customTimetableEvents');
}
@override
Future<GetCustomTimetableEventResponse> onLoad() => GetCustomTimetableEvent(params).run();
@override
GetCustomTimetableEventResponse onLocalData(String json) => GetCustomTimetableEventResponse.fromJson(jsonDecode(json));
}
+35
View File
@@ -79,3 +79,38 @@ abstract class RequestCache<T extends ApiResponse?> {
Future<T> onLoad();
}
/// Concrete [RequestCache] that delegates the two overrides to functions
/// passed in the constructor. Used to collapse the dozens of one-class-per-
/// endpoint cache files that all just forward to `<Endpoint>().run()` and
/// `<Response>.fromJson(jsonDecode(...))`.
class SimpleCache<T extends ApiResponse?> extends RequestCache<T> {
final Future<T> Function() _loader;
final T Function(Map<String, dynamic> json) _fromJson;
SimpleCache({
required int cacheTime,
required Future<T> Function() loader,
required T Function(Map<String, dynamic> json) fromJson,
void Function(T)? onUpdate,
void Function(T)? onCacheData,
void Function(T)? onNetworkData,
void Function(Exception)? onError,
bool? renew,
}) : _loader = loader,
_fromJson = fromJson,
super(
cacheTime,
onUpdate,
onError: onError ?? RequestCache.ignore,
renew: renew,
onCacheData: onCacheData,
onNetworkData: onNetworkData,
);
@override
Future<T> onLoad() => _loader();
@override
T onLocalData(String json) => _fromJson(jsonDecode(json));
}
@@ -1,26 +1,14 @@
import 'dart:convert';
import '../../../requestCache.dart';
import 'getHolidays.dart';
import 'getHolidaysResponse.dart';
class GetHolidaysCache extends RequestCache<GetHolidaysResponse> {
GetHolidaysCache({
void Function(GetHolidaysResponse)? onUpdate,
void Function(Exception)? onError,
bool? renew,
}) : super(
RequestCache.cacheDay,
onUpdate,
onError: onError ?? RequestCache.ignore,
renew: renew,
class GetHolidaysCache extends SimpleCache<GetHolidaysResponse> {
GetHolidaysCache({super.onUpdate, super.onError, super.renew})
: super(
cacheTime: RequestCache.cacheDay,
loader: () => GetHolidays().run(),
fromJson: GetHolidaysResponse.fromJson,
) {
start('wu-holidays');
}
@override
Future<GetHolidaysResponse> onLoad() => GetHolidays().run();
@override
GetHolidaysResponse onLocalData(String json) => GetHolidaysResponse.fromJson(jsonDecode(json));
}
@@ -1,27 +1,14 @@
import 'dart:convert';
import '../../../requestCache.dart';
import 'getRooms.dart';
import 'getRoomsResponse.dart';
class GetRoomsCache extends RequestCache<GetRoomsResponse> {
GetRoomsCache({
void Function(GetRoomsResponse)? onUpdate,
void Function(Exception)? onError,
bool? renew,
}) : super(
RequestCache.cacheHour,
onUpdate,
onError: onError ?? RequestCache.ignore,
renew: renew,
class GetRoomsCache extends SimpleCache<GetRoomsResponse> {
GetRoomsCache({super.onUpdate, super.onError, super.renew})
: super(
cacheTime: RequestCache.cacheHour,
loader: () => GetRooms().run(),
fromJson: GetRoomsResponse.fromJson,
) {
start('wu-rooms');
}
@override
Future<GetRoomsResponse> onLoad() => GetRooms().run();
@override
GetRoomsResponse onLocalData(String json) => GetRoomsResponse.fromJson(jsonDecode(json));
}
@@ -1,27 +1,14 @@
import 'dart:convert';
import '../../../requestCache.dart';
import 'getSubjects.dart';
import 'getSubjectsResponse.dart';
class GetSubjectsCache extends RequestCache<GetSubjectsResponse> {
GetSubjectsCache({
void Function(GetSubjectsResponse)? onUpdate,
void Function(Exception)? onError,
bool? renew,
}) : super(
RequestCache.cacheHour,
onUpdate,
onError: onError ?? RequestCache.ignore,
renew: renew,
class GetSubjectsCache extends SimpleCache<GetSubjectsResponse> {
GetSubjectsCache({super.onUpdate, super.onError, super.renew})
: super(
cacheTime: RequestCache.cacheHour,
loader: () => GetSubjects().run(),
fromJson: GetSubjectsResponse.fromJson,
) {
start('wu-subjects');
}
@override
Future<GetSubjectsResponse> onLoad() => GetSubjects().run();
@override
onLocalData(String json) => GetSubjectsResponse.fromJson(jsonDecode(json));
}
@@ -1,20 +1,14 @@
import 'dart:convert';
import '../../../requestCache.dart';
import 'getTimegridUnits.dart';
import 'getTimegridUnitsResponse.dart';
class GetTimegridUnitsCache extends RequestCache<GetTimegridUnitsResponse> {
GetTimegridUnitsCache({
void Function(GetTimegridUnitsResponse)? onUpdate,
bool? renew,
}) : super(RequestCache.cacheDay, onUpdate, renew: renew) {
class GetTimegridUnitsCache extends SimpleCache<GetTimegridUnitsResponse> {
GetTimegridUnitsCache({super.onUpdate, super.renew})
: super(
cacheTime: RequestCache.cacheDay,
loader: () => GetTimegridUnits().run(),
fromJson: GetTimegridUnitsResponse.fromJson,
) {
start('wu-timegrid');
}
@override
Future<GetTimegridUnitsResponse> onLoad() => GetTimegridUnits().run();
@override
GetTimegridUnitsResponse onLocalData(String json) => GetTimegridUnitsResponse.fromJson(jsonDecode(json));
}
@@ -1,40 +1,33 @@
import 'dart:convert';
import '../../../requestCache.dart';
import '../authenticate/authenticate.dart';
import 'getTimetable.dart';
import 'getTimetableParams.dart';
import 'getTimetableResponse.dart';
class GetTimetableCache extends RequestCache<GetTimetableResponse> {
int startdate;
int enddate;
class GetTimetableCache extends SimpleCache<GetTimetableResponse> {
GetTimetableCache({
required void Function(GetTimetableResponse) onUpdate,
void Function(Exception)? onError,
required this.startdate,
required this.enddate,
bool? renew,
super.onError,
required int startdate,
required int enddate,
super.renew,
}) : super(
RequestCache.cacheMinute,
onUpdate,
onError: onError ?? RequestCache.ignore,
renew: renew,
cacheTime: RequestCache.cacheMinute,
loader: () => _load(startdate, enddate),
fromJson: GetTimetableResponse.fromJson,
onUpdate: onUpdate,
) {
start('wu-timetable-$startdate-$enddate');
}
@override
GetTimetableResponse onLocalData(String json) => GetTimetableResponse.fromJson(jsonDecode(json));
@override
Future<GetTimetableResponse> onLoad() async => GetTimetable(
static Future<GetTimetableResponse> _load(int startdate, int enddate) async {
final session = await Authenticate.getSession();
return GetTimetable(
GetTimetableParams(
options: GetTimetableParamsOptions(
element: GetTimetableParamsOptionsElement(
id: (await Authenticate.getSession()).personId,
type: (await Authenticate.getSession()).personType,
id: session.personId,
type: session.personType,
keyType: GetTimetableParamsOptionsElementKeyType.id,
),
startDate: startdate,
@@ -43,7 +36,8 @@ class GetTimetableCache extends RequestCache<GetTimetableResponse> {
subjectFields: GetTimetableParamsOptionsFields.all,
roomFields: GetTimetableParamsOptionsFields.all,
klasseFields: GetTimetableParamsOptionsFields.all,
)
)
),
),
).run();
}
}
+1 -1
View File
@@ -28,7 +28,7 @@ import 'state/app/modules/chat/bloc/chat_bloc.dart';
import 'state/app/modules/chatList/bloc/chat_list_bloc.dart';
import 'state/app/modules/settings/bloc/settings_cubit.dart';
import 'state/app/modules/timetable/bloc/timetable_bloc.dart';
import 'storage/base/settings.dart';
import 'storage/settings.dart';
import 'theming/dark_app_theme.dart';
import 'theming/light_app_theme.dart';
import 'view/login/login.dart';
@@ -3,7 +3,7 @@ import 'dart:developer';
import 'package:easy_debounce/easy_debounce.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import '../../../../../storage/base/settings.dart';
import '../../../../../storage/settings.dart';
import '../../../../../view/pages/settings/data/default_settings.dart';
import '../../app_modules.dart';
@@ -1,6 +1,6 @@
import 'package:json_annotation/json_annotation.dart';
part 'devToolsSettings.g.dart';
part 'dev_tools_settings.g.dart';
@JsonSerializable()
class DevToolsSettings {
@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'devToolsSettings.dart';
part of 'dev_tools_settings.dart';
// **************************************************************************
// JsonSerializableGenerator
@@ -2,7 +2,7 @@ import 'package:json_annotation/json_annotation.dart';
import '../../view/pages/files/files.dart';
part 'fileSettings.g.dart';
part 'file_settings.g.dart';
@JsonSerializable()
class FileSettings {
@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'fileSettings.dart';
part of 'file_settings.dart';
// **************************************************************************
// JsonSerializableGenerator
@@ -1,6 +1,6 @@
import 'package:json_annotation/json_annotation.dart';
part 'fileViewSettings.g.dart';
part 'file_view_settings.g.dart';
@JsonSerializable()
class FileViewSettings {
@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'fileViewSettings.dart';
part of 'file_view_settings.dart';
// **************************************************************************
// JsonSerializableGenerator
@@ -1,6 +1,6 @@
import 'package:json_annotation/json_annotation.dart';
part 'holidaysSettings.g.dart';
part 'holidays_settings.g.dart';
@JsonSerializable()
class HolidaysSettings {
@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'holidaysSettings.dart';
part of 'holidays_settings.dart';
// **************************************************************************
// JsonSerializableGenerator
@@ -2,7 +2,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
import '../../state/app/modules/app_modules.dart';
part 'modulesSettings.g.dart';
part 'modules_settings.g.dart';
@JsonSerializable()
class ModulesSettings {
@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'modulesSettings.dart';
part of 'modules_settings.dart';
// **************************************************************************
// JsonSerializableGenerator
@@ -1,6 +1,6 @@
import 'package:json_annotation/json_annotation.dart';
part 'notificationSettings.g.dart';
part 'notification_settings.g.dart';
@JsonSerializable()
class NotificationSettings {
@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'notificationSettings.dart';
part of 'notification_settings.dart';
// **************************************************************************
// JsonSerializableGenerator
@@ -1,14 +1,14 @@
import 'package:flutter/material.dart';
import 'package:json_annotation/json_annotation.dart';
import '../devTools/devToolsSettings.dart';
import '../file/fileSettings.dart';
import '../fileView/fileViewSettings.dart';
import '../general/modulesSettings.dart';
import '../holidays/holidaysSettings.dart';
import '../notification/notificationSettings.dart';
import '../talk/talkSettings.dart';
import '../timetable/timetableSettings.dart';
import 'dev_tools_settings.dart';
import 'file_settings.dart';
import 'file_view_settings.dart';
import 'modules_settings.dart';
import 'holidays_settings.dart';
import 'notification_settings.dart';
import 'talk_settings.dart';
import 'timetable_settings.dart';
part 'settings.g.dart';
@@ -1,6 +1,6 @@
import 'package:json_annotation/json_annotation.dart';
part 'talkSettings.g.dart';
part 'talk_settings.g.dart';
@JsonSerializable()
class TalkSettings {
@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'talkSettings.dart';
part of 'talk_settings.dart';
// **************************************************************************
// JsonSerializableGenerator
@@ -1,8 +1,8 @@
import 'package:json_annotation/json_annotation.dart';
import 'timetable_name_mode.dart';
import '../../../view/pages/timetable/data/timetable_name_mode.dart';
part 'timetableSettings.g.dart';
part 'timetable_settings.g.dart';
@JsonSerializable()
class TimetableSettings {
@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'timetableSettings.dart';
part of 'timetable_settings.dart';
// **************************************************************************
// JsonSerializableGenerator
+1 -1
View File
@@ -9,7 +9,7 @@ import '../../extensions/render_not_null.dart';
import '../../routing/app_routes.dart';
import '../../state/app/modules/app_modules.dart';
import '../../state/app/modules/settings/bloc/settings_cubit.dart';
import '../../storage/base/settings.dart' as model;
import '../../storage/settings.dart' as model;
import '../../widget/centered_leading.dart';
import '../../widget/info_dialog.dart';
import 'settings/data/default_settings.dart';
@@ -3,16 +3,16 @@ import 'dart:io';
import 'package:flutter/material.dart';
import '../../../../state/app/modules/app_modules.dart';
import '../../../../storage/base/settings.dart';
import '../../../../storage/devTools/devToolsSettings.dart';
import '../../../../storage/file/fileSettings.dart';
import '../../../../storage/fileView/fileViewSettings.dart';
import '../../../../storage/general/modulesSettings.dart';
import '../../../../storage/holidays/holidaysSettings.dart';
import '../../../../storage/notification/notificationSettings.dart';
import '../../../../storage/talk/talkSettings.dart';
import '../../../../storage/timetable/timetable_name_mode.dart';
import '../../../../storage/timetable/timetableSettings.dart';
import '../../../../storage/settings.dart';
import '../../../../storage/dev_tools_settings.dart';
import '../../../../storage/file_settings.dart';
import '../../../../storage/file_view_settings.dart';
import '../../../../storage/modules_settings.dart';
import '../../../../storage/holidays_settings.dart';
import '../../../../storage/notification_settings.dart';
import '../../../../storage/talk_settings.dart';
import '../../../../view/pages/timetable/data/timetable_name_mode.dart';
import '../../../../storage/timetable_settings.dart';
import '../../files/files.dart';
class DefaultSettings {
@@ -3,7 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../../state/app/modules/settings/bloc/settings_cubit.dart';
import '../../../../state/app/modules/timetable/bloc/timetable_bloc.dart';
import '../../../../storage/timetable/timetable_name_mode.dart';
import '../../../../view/pages/timetable/data/timetable_name_mode.dart';
class TimetableSection extends StatelessWidget {
const TimetableSection({super.key});
+1 -1
View File
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../state/app/modules/settings/bloc/settings_cubit.dart';
import '../../../storage/base/settings.dart' as model;
import '../../../storage/settings.dart' as model;
import 'sections/about_section.dart';
import 'sections/account_section.dart';
import 'sections/appearance_section.dart';
@@ -5,7 +5,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../../api/marianumcloud/talk/chat/getChatResponse.dart';
import '../../../../api/marianumcloud/talk/deleteMessage/deleteMessage.dart';
import '../../../../api/marianumcloud/talk/actions/talk_actions.dart';
import '../../../../api/marianumcloud/talk/reactMessage/reactMessage.dart';
import '../../../../api/marianumcloud/talk/reactMessage/reactMessageParams.dart';
import '../../../../api/marianumcloud/talk/room/getRoomResponse.dart';
+1 -2
View File
@@ -3,10 +3,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:jiffy/jiffy.dart';
import '../../../../api/marianumcloud/talk/actions/talk_actions.dart';
import '../../../../api/marianumcloud/talk/chat/richObjectStringProcessor.dart';
import '../../../../api/marianumcloud/talk/leaveRoom/leaveRoom.dart';
import '../../../../api/marianumcloud/talk/room/getRoomResponse.dart';
import '../../../../api/marianumcloud/talk/setFavorite/setFavorite.dart';
import '../../../../api/marianumcloud/talk/setReadMarker/setReadMarker.dart';
import '../../../../api/marianumcloud/talk/setReadMarker/setReadMarkerParams.dart';
import '../../../../model/account_data.dart';
@@ -5,8 +5,8 @@ import '../../../../api/mhsl/customTimetableEvent/customTimetableEvent.dart';
import '../../../../api/webuntis/queries/getRooms/getRoomsResponse.dart';
import '../../../../api/webuntis/queries/getSubjects/getSubjectsResponse.dart';
import '../../../../api/webuntis/queries/getTimetable/getTimetableResponse.dart';
import '../../../../storage/timetable/timetableSettings.dart';
import '../../../../storage/timetable/timetable_name_mode.dart';
import '../../../../storage/timetable_settings.dart';
import 'timetable_name_mode.dart';
import '../custom_events/custom_event_colors.dart';
import 'arbitrary_appointment.dart';
import 'lesson_color.dart';
@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import '../../widget/dropdown_display.dart';
import '../../../../widget/dropdown_display.dart';
enum TimetableNameMode { name, longName, alternateName }