diff --git a/lib/api/marianumcloud/webdav/queries/listFiles/cacheableFile.dart b/lib/api/marianumcloud/webdav/queries/listFiles/cacheableFile.dart index 99f2c6d..ab59a9f 100644 --- a/lib/api/marianumcloud/webdav/queries/listFiles/cacheableFile.dart +++ b/lib/api/marianumcloud/webdav/queries/listFiles/cacheableFile.dart @@ -1,46 +1,32 @@ -// import 'package:json_annotation/json_annotation.dart'; -// import 'package:webdav_client/webdav_client.dart'; -// -// part 'cacheableFile.g.dart'; -// -// @JsonSerializable(explicitToJson: true) -// class CacheableFile { -// String? path; -// bool? isDir; -// String? name; -// String? mimeType; -// int? size; -// String? eTag; -// DateTime? cTime; -// DateTime? mTime; -// -// CacheableFile(this.path, this.isDir, this.name, this.mimeType, this.size, -// this.eTag, this.cTime, this.mTime); -// -// CacheableFile.fromDavFile(File file) { -// path = file.path; -// isDir = file.isDir; -// name = file.name; -// mimeType = file.mimeType; -// size = file.size; -// eTag = file.eTag; -// cTime = file.cTime; -// mTime = file.mTime; -// } -// -// File toDavFile() { -// return File( -// path: path, -// isDir: isDir, -// name: name, -// mimeType: mimeType, -// size: size, -// eTag: eTag, -// cTime: cTime, -// mTime: mTime -// ); -// } -// -// factory CacheableFile.fromJson(Map json) => _$CacheableFileFromJson(json); -// Map toJson() => _$CacheableFileToJson(this); -// } \ No newline at end of file +import 'package:json_annotation/json_annotation.dart'; +import 'package:nextcloud/nextcloud.dart'; + +part 'cacheableFile.g.dart'; + +@JsonSerializable(explicitToJson: true) +class CacheableFile { + late String path; + late bool isDirectory; + late String name; + String? mimeType; + int? size; + String? eTag; + DateTime? createdAt; + DateTime? modifiedAt; + + CacheableFile(this.path, this.isDirectory, this.name, {this.mimeType, this.size, this.eTag, this.createdAt, this.modifiedAt}); + + CacheableFile.fromDavFile(WebDavFile file) { + path = file.path; + isDirectory = file.isDirectory; + name = file.name; + mimeType = file.mimeType; + size = file.size; + eTag = file.etag; + createdAt = file.createdDate; + modifiedAt = file.lastModified; + } + + factory CacheableFile.fromJson(Map json) => _$CacheableFileFromJson(json); + Map toJson() => _$CacheableFileToJson(this); +} \ No newline at end of file diff --git a/lib/api/marianumcloud/webdav/queries/listFiles/cacheableFile.g.dart b/lib/api/marianumcloud/webdav/queries/listFiles/cacheableFile.g.dart new file mode 100644 index 0000000..1e09407 --- /dev/null +++ b/lib/api/marianumcloud/webdav/queries/listFiles/cacheableFile.g.dart @@ -0,0 +1,35 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'cacheableFile.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +CacheableFile _$CacheableFileFromJson(Map json) => + CacheableFile( + json['path'] as String, + json['isDirectory'] as bool, + json['name'] as String, + mimeType: json['mimeType'] as String?, + size: json['size'] as int?, + eTag: json['eTag'] as String?, + createdAt: json['createdAt'] == null + ? null + : DateTime.parse(json['createdAt'] as String), + modifiedAt: json['modifiedAt'] == null + ? null + : DateTime.parse(json['modifiedAt'] as String), + ); + +Map _$CacheableFileToJson(CacheableFile instance) => + { + 'path': instance.path, + 'isDirectory': instance.isDirectory, + 'name': instance.name, + 'mimeType': instance.mimeType, + 'size': instance.size, + 'eTag': instance.eTag, + 'createdAt': instance.createdAt?.toIso8601String(), + 'modifiedAt': instance.modifiedAt?.toIso8601String(), + }; diff --git a/lib/api/marianumcloud/webdav/queries/listFiles/listFiles.dart b/lib/api/marianumcloud/webdav/queries/listFiles/listFiles.dart index 497e097..fd3a472 100644 --- a/lib/api/marianumcloud/webdav/queries/listFiles/listFiles.dart +++ b/lib/api/marianumcloud/webdav/queries/listFiles/listFiles.dart @@ -1,21 +1,18 @@ -// -// import 'package:marianum_mobile/api/apiParams.dart'; -// import 'package:marianum_mobile/api/apiResponse.dart'; -// import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/cacheableFile.dart'; -// import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/listFilesParams.dart'; -// import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/listFilesResponse.dart'; -// import 'package:marianum_mobile/api/marianumcloud/webdav/webdavApi.dart'; -// import 'package:webdav_client/webdav_client.dart'; -// -// class ListFiles extends WebdavApi { -// ListFilesParams params; -// -// ListFiles(this.params) : super(params); -// -// @override -// Future run() async { -// Set files = (await (await WebdavApi.webdav).readDir(params.path)).map((e) => CacheableFile.fromDavFile(e)).toSet(); -// -// return ListFilesResponse(files); -// } -// } \ No newline at end of file + +import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/cacheableFile.dart'; +import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/listFilesParams.dart'; +import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/listFilesResponse.dart'; +import 'package:marianum_mobile/api/marianumcloud/webdav/webdavApi.dart'; + +class ListFiles extends WebdavApi { + ListFilesParams params; + + ListFiles(this.params) : super(params); + + @override + Future run() async { + Set files = (await (await WebdavApi.webdav).ls(params.path)).map((e) => CacheableFile.fromDavFile(e)).toSet(); + + return ListFilesResponse(files); + } +} \ No newline at end of file diff --git a/lib/api/marianumcloud/webdav/queries/listFiles/listFilesCache.dart b/lib/api/marianumcloud/webdav/queries/listFiles/listFilesCache.dart index d69c586..b2f93c6 100644 --- a/lib/api/marianumcloud/webdav/queries/listFiles/listFilesCache.dart +++ b/lib/api/marianumcloud/webdav/queries/listFiles/listFilesCache.dart @@ -1,33 +1,32 @@ -// import 'dart:convert'; -// import 'dart:developer'; -// -// import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/listFiles.dart'; -// import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/listFilesParams.dart'; -// import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/listFilesResponse.dart'; -// import 'package:marianum_mobile/api/requestCache.dart'; -// import 'package:webdav_client/webdav_client.dart'; -// -// class ListFilesCache extends RequestCache { -// String path; -// -// ListFilesCache({required onUpdate, required this.path}) : super(RequestCache.cacheNothing, onUpdate) { -// String cacheName = path.replaceAll(RegExp("[^A-Za-z0-9]"), "_"); //TODO this is very evil, "/ü/" > "___" also "/ä/" > "___" -// log(cacheName); -// -// start("MarianumMobile", "wd-folder-$cacheName"); -// } -// -// @override -// Future onLoad() async { -// log("Loading remote data"); -// ListFilesResponse data = await ListFiles(ListFilesParams(path)).run(); -// return data; -// } -// -// @override -// ListFilesResponse onLocalData(String json) { -// log("Loading local data"); -// return ListFilesResponse.fromJson(jsonDecode(json)); -// } -// -// } \ No newline at end of file +import 'dart:convert'; +import 'dart:developer'; + +import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/listFiles.dart'; +import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/listFilesParams.dart'; +import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/listFilesResponse.dart'; +import 'package:marianum_mobile/api/requestCache.dart'; + +class ListFilesCache extends RequestCache { + String path; + + ListFilesCache({required onUpdate, required this.path}) : super(RequestCache.cacheNothing, onUpdate) { + String cacheName = path.replaceAll(RegExp("[^A-Za-z0-9]"), "_"); //TODO this is very evil, "/ü/" > "___" also "/ä/" > "___" + log(cacheName); + + start("MarianumMobile", "wd-folder-$cacheName"); + } + + @override + Future onLoad() async { + log("Loading remote data"); + ListFilesResponse data = await ListFiles(ListFilesParams(path)).run(); + return data; + } + + @override + ListFilesResponse onLocalData(String json) { + log("Loading local data"); + return ListFilesResponse.fromJson(jsonDecode(json)); + } + +} \ No newline at end of file diff --git a/lib/api/marianumcloud/webdav/queries/listFiles/listFilesResponse.dart b/lib/api/marianumcloud/webdav/queries/listFiles/listFilesResponse.dart index 656c688..80bab99 100644 --- a/lib/api/marianumcloud/webdav/queries/listFiles/listFilesResponse.dart +++ b/lib/api/marianumcloud/webdav/queries/listFiles/listFilesResponse.dart @@ -1,16 +1,16 @@ -// import 'package:json_annotation/json_annotation.dart'; -// import 'package:marianum_mobile/api/apiResponse.dart'; -// -// import 'cacheableFile.dart'; -// -// part 'listFilesResponse.g.dart'; -// -// @JsonSerializable(explicitToJson: true) -// class ListFilesResponse extends ApiResponse { -// Set files; -// -// ListFilesResponse(this.files); -// -// factory ListFilesResponse.fromJson(Map json) => _$ListFilesResponseFromJson(json); -// Map toJson() => _$ListFilesResponseToJson(this); -// } \ No newline at end of file +import 'package:json_annotation/json_annotation.dart'; +import 'package:marianum_mobile/api/apiResponse.dart'; + +import 'cacheableFile.dart'; + +part 'listFilesResponse.g.dart'; + +@JsonSerializable(explicitToJson: true) +class ListFilesResponse extends ApiResponse { + Set files; + + ListFilesResponse(this.files); + + factory ListFilesResponse.fromJson(Map json) => _$ListFilesResponseFromJson(json); + Map toJson() => _$ListFilesResponseToJson(this); +} \ No newline at end of file diff --git a/lib/api/marianumcloud/webdav/queries/listFiles/listFilesResponse.g.dart b/lib/api/marianumcloud/webdav/queries/listFiles/listFilesResponse.g.dart new file mode 100644 index 0000000..f6281c4 --- /dev/null +++ b/lib/api/marianumcloud/webdav/queries/listFiles/listFilesResponse.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'listFilesResponse.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ListFilesResponse _$ListFilesResponseFromJson(Map json) => + ListFilesResponse( + (json['files'] as List) + .map((e) => CacheableFile.fromJson(e as Map)) + .toSet(), + ); + +Map _$ListFilesResponseToJson(ListFilesResponse instance) => + { + 'files': instance.files.map((e) => e.toJson()).toList(), + }; diff --git a/lib/api/marianumcloud/webdav/webdavApi.dart b/lib/api/marianumcloud/webdav/webdavApi.dart index 1f483a9..06f1131 100644 --- a/lib/api/marianumcloud/webdav/webdavApi.dart +++ b/lib/api/marianumcloud/webdav/webdavApi.dart @@ -1,43 +1,23 @@ -// import 'dart:developer'; -// -// import 'package:marianum_mobile/api/apiParams.dart'; -// import 'package:marianum_mobile/api/apiRequest.dart'; -// import 'package:marianum_mobile/api/webuntis/queries/authenticate/authenticate.dart'; -// import 'package:shared_preferences/shared_preferences.dart'; -// import 'package:webdav_client/webdav_client.dart'; -// -// import '../../apiResponse.dart'; -// -// abstract class WebdavApi extends ApiRequest { -// T genericParams; -// -// WebdavApi(this.genericParams) { -// establishWebdavConnection(); -// } -// -// Future run(); -// -// static Future webdav = establishWebdavConnection(); -// -// static Future establishWebdavConnection() async { -// SharedPreferences preferences = await SharedPreferences.getInstance(); -// -// // Client client = newClient( -// // "https://cloud.marianum-fulda.de/remote.php/dav/files/***REMOVED***/", -// // user: "***REMOVED***", -// // password: "***REMOVED***", -// // debug: true -// // ); -// // -// // client.setHeaders( -// // { -// // "Authorization": "Bearer", -// // "User-Agent": "Marianum Fulda/Alpha0.1 (Development build) ; https://mhsl.eu/id.html", -// // } -// // ); -// -// throw UnimplementedError(); -// //return client; -// -// } -// } \ No newline at end of file +import 'package:marianum_mobile/api/apiRequest.dart'; +import 'package:nextcloud/nextcloud.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +import '../../apiResponse.dart'; + +abstract class WebdavApi extends ApiRequest { + T genericParams; + + WebdavApi(this.genericParams) { + establishWebdavConnection(); + } + + Future run(); + + static Future webdav = establishWebdavConnection(); + + static Future establishWebdavConnection() async { + SharedPreferences preferences = await SharedPreferences.getInstance(); + + return NextcloudClient("https://cloud.marianum-fulda.de/", username: preferences.getString("username"), password: preferences.getString("password"), loginName: preferences.getString("username")).webdav; + } +} \ No newline at end of file diff --git a/lib/data/files/filesProps.dart b/lib/data/files/filesProps.dart index 5007bce..ec0e577 100644 --- a/lib/data/files/filesProps.dart +++ b/lib/data/files/filesProps.dart @@ -1,31 +1,38 @@ -// import 'dart:developer'; -// -// import 'package:marianum_mobile/api/apiResponse.dart'; -// import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/listFilesCache.dart'; -// import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/listFilesResponse.dart'; -// import 'package:marianum_mobile/data/dataHolder.dart'; -// -// class FilesProps extends DataHolder { -// -// ListFilesResponse? _listFilesResponse; -// ListFilesResponse get listFilesResponse => _listFilesResponse!; -// -// @override -// List properties() { -// return [_listFilesResponse]; -// } -// -// @override -// void run() { -// log("Query Cache"); -// ListFilesCache( -// path: "/", -// onUpdate: (ListFilesResponse data) => { -// log("Got cache response"), -// _listFilesResponse = data, -// notifyListeners(), -// } -// ); -// } -// -// } \ No newline at end of file +import 'dart:developer'; + +import 'package:marianum_mobile/api/apiResponse.dart'; +import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/listFilesCache.dart'; +import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/listFilesResponse.dart'; +import 'package:marianum_mobile/data/dataHolder.dart'; + +class FilesProps extends DataHolder { + String _path = "/"; + + ListFilesResponse? _listFilesResponse; + ListFilesResponse get listFilesResponse => _listFilesResponse!; + + @override + List properties() { + return [_listFilesResponse]; + } + + @override + void run() { + notifyListeners(); + ListFilesCache( + path: _path, + onUpdate: (ListFilesResponse data) => { + log("Got cache response"), + _listFilesResponse = data, + notifyListeners(), + } + ); + } + + void setPath(String path) { + _listFilesResponse = null; + _path = path; + run(); + } + +} \ No newline at end of file diff --git a/lib/data/timetable/timetableProps.dart b/lib/data/timetable/timetableProps.dart index 1bc114b..cf08e20 100644 --- a/lib/data/timetable/timetableProps.dart +++ b/lib/data/timetable/timetableProps.dart @@ -1,6 +1,4 @@ -import 'dart:developer'; - import 'package:intl/intl.dart'; import 'package:marianum_mobile/api/apiResponse.dart'; import 'package:marianum_mobile/api/webuntis/queries/getHolidays/getHolidaysCache.dart'; @@ -31,7 +29,7 @@ class TimetableProps extends DataHolder { late DateTime endDate = getDate(_queryWeek.add(Duration(days: DateTime.daysPerWeek - _queryWeek.weekday))); GetTimetableResponse? _getTimetableResponse; - GetTimetableResponse get getTimetableResponse => _getTimetableResponse!; + GetTimetableResponse get getTimetableResponse => _getTimetableResponse!; //TODO failed null check when no cache GetRoomsResponse? _getRoomsResponse; GetRoomsResponse get getRoomsResponse => _getRoomsResponse!; diff --git a/lib/main.dart b/lib/main.dart index 4eb5e2e..f9d86ef 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -13,6 +13,7 @@ import 'app.dart'; import 'data/chatList/chatListProps.dart'; import 'data/chatList/chatProps.dart'; import 'data/accountModel.dart'; +import 'data/files/filesProps.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -27,6 +28,7 @@ Future main() async { ChangeNotifierProvider(create: (context) => TimetableProps()), ChangeNotifierProvider(create: (context) => ChatListProps()), ChangeNotifierProvider(create: (context) => ChatProps()), + ChangeNotifierProvider(create: (context) => FilesProps()), ], child: const Main(), ) diff --git a/lib/screen/pages/files/files.dart b/lib/screen/pages/files/files.dart index cc89b66..87a3e83 100644 --- a/lib/screen/pages/files/files.dart +++ b/lib/screen/pages/files/files.dart @@ -1,5 +1,16 @@ +import 'dart:developer'; + +import 'package:filesize/filesize.dart'; import 'package:flutter/material.dart'; +import 'package:jiffy/jiffy.dart'; +import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/cacheableFile.dart'; +import 'package:marianum_mobile/api/marianumcloud/webdav/queries/listFiles/listFilesParams.dart'; +import 'package:provider/provider.dart'; + +import '../../../api/marianumcloud/webdav/queries/listFiles/listFiles.dart'; +import '../../../api/marianumcloud/webdav/queries/listFiles/listFilesResponse.dart'; +import '../../../data/files/filesProps.dart'; class Files extends StatefulWidget { const Files({Key? key}) : super(key: key); @@ -13,7 +24,7 @@ class _FilesState extends State { @override void initState() { WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - //Provider.of(context, listen: false).run(); + Provider.of(context, listen: false).run(); }); super.initState(); @@ -22,50 +33,31 @@ class _FilesState extends State { @override Widget build(BuildContext context) { + Future files = ListFiles(ListFilesParams("/")).run(); + files.then((value) => log(value.toJson().toString())); - // log("NEW CLIENT"); - // Client client = newClient( - // "https://***REMOVED***:***REMOVED***@cloud.marianum-fulda.de/remote.php/dav/files/***REMOVED***/", - // user: "***REMOVED***", - // password: "***REMOVED***", - // debug: true - // ); - // - // // client.setHeaders( - // // { - // // "User-Agent": "Marianum Fulda/Alpha0.1 (Development build) ; https://mhsl.eu/id.html", - // // } - // // ); - // - // log("DATA"); - // log(client.readDir("/").toString()); + return Consumer( + builder: (context, value, child) { + if(value.primaryLoading()) return const Center(child: CircularProgressIndicator()); - // Future> files = Client("https://cloud.marianum-fulda.de/remote.php/dav/files/***REMOVED***", "***REMOVED***", "***REMOVED***").ls(); - // log(files.toString()); - // log("REQUEST FINISH"); - // - // files.then((asd) => { - // asd.forEach((element) { - // log(element.name); - // }), - // }); - - // var client = NextcloudClient("https://cloud.marianum-fulda.de", username: "***REMOVED***", password: "***REMOVED***"); - // - // //client.baseHeaders.putIfAbsent("Authorization", () => "Basic ***REMOVED***"); - // //client.authentication?.headers.putIfAbsent("Authorization", () => "Basic ***REMOVED***"); - // //client.webdav.rootClient.baseHeaders.putIfAbsent("Authorization", () => "Basic ***REMOVED***"); - // - // client.webdav.ls("/").then((value) => () { - // log("TEST"); - // value.forEach((element) { - // log(element.name); - // }); - // }); - - - return const Center( - child: Text("Currently not implemented!"), + return ListView.builder( + itemCount: value.listFilesResponse.files.length, + itemBuilder: (context, index) { + CacheableFile file = value.listFilesResponse.files.skip(index).first; + return ListTile( + leading: Icon(file.isDirectory ? Icons.folder : Icons.file_open_outlined), + title: Text(file.name), + subtitle: file.isDirectory ? Text("geändert ${Jiffy(file.modifiedAt).fromNow()}") : Text("${filesize(file.size)}, ${Jiffy(file.modifiedAt).fromNow()}}"), + trailing: Icon(file.isDirectory ? Icons.arrow_right : Icons.open_in_new), + onTap: () { + if(file.isDirectory) { + Provider.of(context, listen: false).setPath(file.path); + } + }, + ); + }, + ); + } ); // return Consumer( diff --git a/lib/screen/pages/talk/chatBubble.dart b/lib/screen/pages/talk/chatBubble.dart index 887b8d2..d6f4ff5 100644 --- a/lib/screen/pages/talk/chatBubble.dart +++ b/lib/screen/pages/talk/chatBubble.dart @@ -1,5 +1,6 @@ import 'package:bubble/bubble.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:jiffy/jiffy.dart'; import 'package:marianum_mobile/api/marianumcloud/talk/chat/getChatResponse.dart'; import 'package:marianum_mobile/screen/pages/talk/chatMessage.dart'; @@ -123,17 +124,25 @@ class ChatBubble { showDialog(context: context, builder: (context) { return SimpleDialog( children: [ - ListTile( - leading: Icon(Icons.copy), - title: Text("Nachricht kopieren"), + Visibility( + visible: !message.containsFile && bubbleData.messageType == GetRoomResponseObjectMessageType.comment, + child: ListTile( + leading: const Icon(Icons.copy), + title: const Text("Nachricht kopieren"), + onTap: () => { + Clipboard.setData(ClipboardData(text: bubbleData.message)), + Navigator.of(context).pop(), + }, + ), ), ListTile( - leading: Icon(Icons.person), + leading: const Icon(Icons.person), title: Text("Zu '${bubbleData.actorDisplayName}' wechseln"), + onTap: () => {}, ), ListTile( - leading: Icon(Icons.bug_report_outlined), - title: Text("Debugdaten anzeigen"), + leading: const Icon(Icons.bug_report_outlined), + title: const Text("Debugdaten anzeigen"), onTap: () => JsonViewer.asDialog(context, bubbleData.toJson()), ) ],