diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index b17ad9f16..a96dc4484 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -4059,5 +4059,8 @@ "restricted": "Restricted", "@restricted": {}, "knockRestricted": "Knock restricted", - "@knockRestricted": {} + "@knockRestricted": {}, + "nonexistentSelection": "Selection no longer exists.", + "cantAddSpaceChild": "You do not have permission to add a child to this space.", + "roomAddedToSpace": "Room(s) have been added to the selected space." } \ No newline at end of file diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 6d018bbf6..b199a1b67 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -806,11 +806,18 @@ class ChatController extends State builder: (c) => const RecordingDialog(), ); if (result == null) return; - final audioFile = File(result.path); + // #Pangea + // enable web recording + // final audioFile = File(result.path); + // final file = MatrixAudioFile( + // bytes: audioFile.readAsBytesSync(), + // name: audioFile.path, + // ); final file = MatrixAudioFile( - bytes: audioFile.readAsBytesSync(), - name: audioFile.path, + bytes: result.bytes, + name: result.path, ); + // Pangea# await room.sendFileEvent( file, inReplyTo: replyEvent, diff --git a/lib/pages/chat/recording_dialog.dart b/lib/pages/chat/recording_dialog.dart index caf5aef60..1540b3405 100644 --- a/lib/pages/chat/recording_dialog.dart +++ b/lib/pages/chat/recording_dialog.dart @@ -1,11 +1,14 @@ import 'dart:async'; +import 'dart:io'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pangea/utils/update_version_dialog.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:http/http.dart' as http; import 'package:path_provider/path_provider.dart'; import 'package:record/record.dart'; import 'package:wakelock_plus/wakelock_plus.dart'; @@ -39,9 +42,15 @@ class RecordingDialogState extends State { Future startRecording() async { try { - final tempDir = await getTemporaryDirectory(); - final path = _recordedPath = - '${tempDir.path}/recording${DateTime.now().microsecondsSinceEpoch}.${RecordingDialog.recordingFileType}'; + // #Pangea + // enable recording on web + // final tempDir = await getTemporaryDirectory(); + // final path = _recordedPath = + // '${tempDir.path}/recording${DateTime.now().microsecondsSinceEpoch}.${RecordingDialog.recordingFileType}'; + final tempDirPath = kIsWeb ? "." : (await getTemporaryDirectory()).path; + _recordedPath = + '$tempDirPath/recording${DateTime.now().microsecondsSinceEpoch}.${RecordingDialog.recordingFileType}'; + // Pangea# final result = await _audioRecorder.hasPermission(); if (result != true) { @@ -110,9 +119,25 @@ class RecordingDialogState extends State { void _stopAndSend() async { _recorderSubscription?.cancel(); - await _audioRecorder.stop(); + // #Pangea + // await _audioRecorder.stop(); + final outputPath = await _audioRecorder.stop(); + // Pangea# final path = _recordedPath; if (path == null) throw ('Recording failed!'); + + // #Pangea + Uint8List bytes; + if (kIsWeb) { + if (outputPath == null) throw ('Recording failed!'); + final response = await http.get(Uri.parse(outputPath)); + bytes = response.bodyBytes; + } else { + final audioFile = File(path); + bytes = audioFile.readAsBytesSync(); + } + // Pangea# + const waveCount = AudioPlayerWidget.wavesCount; final step = amplitudeTimeline.length < waveCount ? 1 @@ -126,6 +151,9 @@ class RecordingDialogState extends State { path: path, duration: _duration.inMilliseconds, waveform: waveform, + // #Pangea + bytes: bytes, + // Pangea# ), ); } @@ -236,11 +264,17 @@ class RecordingResult { final String path; final int duration; final List waveform; + // #Pangea + final Uint8List bytes; + // Pangea# const RecordingResult({ required this.path, required this.duration, required this.waveform, + // #Pangea + required this.bytes, + // Pangea# }); factory RecordingResult.fromJson(Map json) => @@ -248,11 +282,17 @@ class RecordingResult { path: json['path'], duration: json['duration'], waveform: List.from(json['waveform']), + // #Pangea + bytes: Uint8List.fromList(json['bytes']), + // Pangea# ); Map toJson() => { 'path': path, 'duration': duration, 'waveform': waveform, + // #Pangea + 'bytes': bytes, + // Pangea# }; } diff --git a/lib/pages/chat_list/chat_list.dart b/lib/pages/chat_list/chat_list.dart index c7a3ee706..7448982d5 100644 --- a/lib/pages/chat_list/chat_list.dart +++ b/lib/pages/chat_list/chat_list.dart @@ -800,6 +800,10 @@ class ChatListController extends State // Pangea# Future addToSpace() async { + // #Pangea + final firstSelectedRoom = + Matrix.of(context).client.getRoomById(selectedRoomIds.toList().first); + // Pangea# final selectedSpace = await showConfirmationDialog( context: context, title: L10n.of(context)!.addToSpace, @@ -818,8 +822,9 @@ class ChatListController extends State && selectedRoomIds .map((id) => Matrix.of(context).client.getRoomById(id)) - .where((e) => !(e?.isPangeaClass ?? true)) - .every((e) => r.canIAddSpaceChild(e)), + // Only show non-recursion-causing spaces + // Performs a few other checks as well + .every((e) => r.canAddAsParentOf(e)), //Pangea# ) .map( @@ -829,6 +834,13 @@ class ChatListController extends State // label: space // .getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)), label: space.nameIncludingParents(context), + // If user is not admin of space, button is grayed out + textStyle: TextStyle( + color: (firstSelectedRoom == null || + (firstSelectedRoom.isSpace && !space.isRoomAdmin)) + ? Theme.of(context).colorScheme.outline + : Theme.of(context).colorScheme.surfaceTint, + ), // Pangea# ), ) @@ -840,12 +852,20 @@ class ChatListController extends State future: () async { final space = Matrix.of(context).client.getRoomById(selectedSpace)!; // #Pangea + if (firstSelectedRoom == null) { + throw L10n.of(context)!.nonexistentSelection; + } + // If user is not admin of the would-be parent space, does not allow + if (firstSelectedRoom.isSpace && !space.isRoomAdmin) { + throw L10n.of(context)!.cantAddSpaceChild; + } await pangeaAddToSpace( space, selectedRoomIds.toList(), context, pangeaController, ); + // if (space.canSendDefaultStates) { // for (final roomId in selectedRoomIds) { // await space.setSpaceChild(roomId); @@ -858,7 +878,10 @@ class ChatListController extends State if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: Text(L10n.of(context)!.chatHasBeenAddedToThisSpace), + // #Pangea + // content: Text(L10n.of(context)!.chatHasBeenAddedToThisSpace), + content: Text(L10n.of(context)!.roomAddedToSpace), + // Pangea# ), ); } diff --git a/lib/pangea/extensions/pangea_room_extension/children_and_parents_extension.dart b/lib/pangea/extensions/pangea_room_extension/children_and_parents_extension.dart index 78ab91cc8..24dad6c41 100644 --- a/lib/pangea/extensions/pangea_room_extension/children_and_parents_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/children_and_parents_extension.dart @@ -127,4 +127,14 @@ extension ChildrenAndParentsRoomExtension on Room { } return childIds; } + + // Checks if has permissions to add child chat + // Or whether potential child space is ancestor of this + bool _canAddAsParentOf(Room? child) { + if (child == null || !child.isSpace) { + return _canIAddSpaceChild(child); + } + if (id == child.id) return false; + return !child._allSpaceChildRoomIds.contains(id); + } } diff --git a/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart b/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart index edcd80b04..25694901c 100644 --- a/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart @@ -114,6 +114,8 @@ extension PangeaRoom on Room { List get allSpaceChildRoomIds => _allSpaceChildRoomIds; + bool canAddAsParentOf(Room? child) => _canAddAsParentOf(child); + // class_and_exchange_settings DateTime? get rulesUpdatedAt => _rulesUpdatedAt; diff --git a/lib/pangea/widgets/class/add_space_toggles.dart b/lib/pangea/widgets/class/add_space_toggles.dart index cfea4dd7b..c2ed32efe 100644 --- a/lib/pangea/widgets/class/add_space_toggles.dart +++ b/lib/pangea/widgets/class/add_space_toggles.dart @@ -144,9 +144,13 @@ class AddToSpaceState extends State { Widget getAddToSpaceToggleItem(int index) { final Room possibleParent = possibleParents[index]; - final bool canAdd = !(!possibleParent.isRoomAdmin && - widget.mode == AddToClassMode.exchange) && - possibleParent.canIAddSpaceChild(room); + final bool canAdd = (room?.isSpace ?? false) + // Room is space + ? possibleParent.isRoomAdmin && + room!.isRoomAdmin && + possibleParent.canAddAsParentOf(room) + // Room is null or chat + : possibleParent.canAddAsParentOf(room); return Opacity( opacity: canAdd ? 1 : 0.5, diff --git a/lib/utils/platform_infos.dart b/lib/utils/platform_infos.dart index 9094b774b..350fc914f 100644 --- a/lib/utils/platform_infos.dart +++ b/lib/utils/platform_infos.dart @@ -2,7 +2,6 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; - import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:go_router/go_router.dart'; import 'package:package_info_plus/package_info_plus.dart'; @@ -29,7 +28,10 @@ abstract class PlatformInfos { static bool get usesTouchscreen => !isMobile; - static bool get platformCanRecord => (isMobile || isMacOS); + // #Pangea + // static bool get platformCanRecord => (isMobile || isMacOS); + static bool get platformCanRecord => (isMobile || isMacOS || kIsWeb); + // Pangea# static String get clientName => '${AppConfig.applicationName} ${isWeb ? 'web' : Platform.operatingSystem}${kReleaseMode ? '' : 'Debug'}'; diff --git a/needed-translations.txt b/needed-translations.txt index 359b812db..8a6cceee4 100644 --- a/needed-translations.txt +++ b/needed-translations.txt @@ -857,7 +857,10 @@ "capacitySetTooLow", "roomCapacityExplanation", "enterNumber", - "buildTranslation" + "buildTranslation", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "be": [ @@ -2351,7 +2354,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "bn": [ @@ -3841,7 +3847,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "bo": [ @@ -5335,7 +5344,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "ca": [ @@ -6231,7 +6243,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "cs": [ @@ -7209,7 +7224,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "de": [ @@ -8070,7 +8088,10 @@ "capacitySetTooLow", "roomCapacityExplanation", "enterNumber", - "buildTranslation" + "buildTranslation", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "el": [ @@ -9515,7 +9536,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "eo": [ @@ -10658,7 +10682,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "es": [ @@ -10696,7 +10723,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "et": [ @@ -11557,7 +11587,10 @@ "capacitySetTooLow", "roomCapacityExplanation", "enterNumber", - "buildTranslation" + "buildTranslation", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "eu": [ @@ -12420,7 +12453,10 @@ "enterNumber", "buildTranslation", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "fa": [ @@ -13420,7 +13456,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "fi": [ @@ -14384,7 +14423,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "fil": [ @@ -15704,7 +15746,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "fr": [ @@ -16703,7 +16748,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "ga": [ @@ -17831,7 +17879,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "gl": [ @@ -18692,7 +18743,10 @@ "capacitySetTooLow", "roomCapacityExplanation", "enterNumber", - "buildTranslation" + "buildTranslation", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "he": [ @@ -19939,7 +19993,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "hi": [ @@ -21426,7 +21483,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "hr": [ @@ -22366,7 +22426,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "hu": [ @@ -23243,7 +23306,10 @@ "enterNumber", "buildTranslation", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "ia": [ @@ -24723,7 +24789,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "id": [ @@ -25590,7 +25659,10 @@ "enterNumber", "buildTranslation", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "ie": [ @@ -26841,7 +26913,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "it": [ @@ -27759,7 +27834,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "ja": [ @@ -28788,7 +28866,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "ka": [ @@ -30136,7 +30217,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "ko": [ @@ -30999,7 +31083,10 @@ "enterNumber", "buildTranslation", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "lt": [ @@ -32028,7 +32115,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "lv": [ @@ -32897,7 +32987,10 @@ "enterNumber", "buildTranslation", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "nb": [ @@ -34090,7 +34183,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "nl": [ @@ -35047,7 +35143,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "pl": [ @@ -36013,7 +36112,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "pt": [ @@ -37485,7 +37587,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "pt_BR": [ @@ -38352,7 +38457,10 @@ "enterNumber", "buildTranslation", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "pt_PT": [ @@ -39546,7 +39654,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "ro": [ @@ -40547,7 +40658,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "ru": [ @@ -41414,7 +41528,10 @@ "enterNumber", "buildTranslation", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "sk": [ @@ -42674,7 +42791,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "sl": [ @@ -44064,7 +44184,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "sr": [ @@ -45228,7 +45351,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "sv": [ @@ -46126,7 +46252,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "ta": [ @@ -47617,7 +47746,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "th": [ @@ -49062,7 +49194,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "tr": [ @@ -49923,7 +50058,10 @@ "capacitySetTooLow", "roomCapacityExplanation", "enterNumber", - "buildTranslation" + "buildTranslation", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "uk": [ @@ -50821,7 +50959,10 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "vi": [ @@ -52167,7 +52308,10 @@ "buildTranslation", "noDatabaseEncryption", "thereAreCountUsersBlocked", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "zh": [ @@ -53028,7 +53172,10 @@ "capacitySetTooLow", "roomCapacityExplanation", "enterNumber", - "buildTranslation" + "buildTranslation", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ], "zh_Hant": [ @@ -54170,6 +54317,9 @@ "noDatabaseEncryption", "thereAreCountUsersBlocked", "restricted", - "knockRestricted" + "knockRestricted", + "nonexistentSelection", + "cantAddSpaceChild", + "roomAddedToSpace" ] }