diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 3a012e08d..b99191d7d 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -4024,7 +4024,7 @@ "conversationBotCustomZone_customSystemPromptPlaceholder": "Set custom system prompt", "conversationBotCustomZone_customSystemPromptEmptyError": "Missing custom system prompt", "conversationBotCustomZone_customTriggerReactionEnabledLabel": "Responds on ⏩ reaction", - "botConfig": "Chat settings", + "botConfig": "Bot and activity settings", "addConversationBotDialogTitleInvite": "Confirm inviting conversation bot", "addConversationBotButtonInvite": "Invite", "addConversationBotDialogInviteConfirmation": "Invite", @@ -4500,5 +4500,11 @@ "other": "Other", "botModeValidation": "Please select a chat mode", "clickBestOption": "Choose the best options to translate your message!", - "unlockedLanguageTools": "You’ve unlocked the language tools for this message. Try them out by clicking below!" + "unlockedLanguageTools": "You’ve unlocked the language tools for this message. Try them out by clicking below!", + "botSettingsSubtitle": "Invite bot to moderate chat activity", + "invitePeople": "Invite users", + "invitePeopleChatSubtitle": "Invite users or admins to this chat", + "invitePeopleSpaceSubtitle": "Invite users or admins to this space", + "noCapacityLimit": "No capacity limit", + "downloadGroupText": "Download group text" } \ No newline at end of file diff --git a/assets/l10n/intl_es.arb b/assets/l10n/intl_es.arb index fd478e870..ece21fa87 100644 --- a/assets/l10n/intl_es.arb +++ b/assets/l10n/intl_es.arb @@ -5004,9 +5004,286 @@ "enterDiscussionTopic": "Introduzca un tema de debate", "selectBotChatMode": "Selecciona el modo de chat", "messageNotInTargetLang": "El mensaje no está en la lengua de llegada", - "botConfig": "Configuración del chat", "chatCapacityNotSet": "Este chat no tiene límite de capacidad.", "spaceCapacityNotSet": "Este espacio no tiene límite de capacidad.", "chatExceedsCapacity": "Este chat supera su capacidad.", - "spaceExceedsCapacity": "Este espacio supera su capacidad." -} \ No newline at end of file + "spaceExceedsCapacity": "Este espacio supera su capacidad.", + "botConfig": "Configuración de bots y actividades", + "missingVoiceTitle": "La voz que falta", + "grammarCopyPOSsconj": "Conjunción subordinante", + "grammarCopyPOSnum": "Número", + "grammarCopyPOSverb": "Verbo", + "grammarCopyPOSaffix": "Coloque", + "grammarCopyPOSpart": "Partículas", + "grammarCopyPOSadj": "Adjetivo", + "grammarCopyPOScconj": "Conjunción de coordinación", + "grammarCopyPOSpunct": "Puntuación", + "grammarCopyPOSadv": "Adverbio", + "grammarCopyPOSaux": "Auxiliar", + "grammarCopyPOSspace": "Espacio", + "grammarCopyPOSsym": "Símbolo", + "grammarCopyPOSdet": "Determinante", + "grammarCopyPOSpron": "Pronombre", + "grammarCopyPOSadp": "Adposición", + "grammarCopyPOSpropn": "Nombre propio", + "grammarCopyPOSnoun": "Sustantivo", + "grammarCopyPOSintj": "Interjección", + "grammarCopyPOSx": "Otros", + "grammarCopyGENDERfem": "Femenino", + "grammarCopyPERSON2": "Segunda persona", + "grammarCopyMOODimp": "Imperativo", + "grammarCopyPUNCTTYPEqest": "Pregunta", + "grammarCopyASPECTperf": "Perfecto", + "grammarCopyCASEaccnom": "Acusativo, Nominativo", + "grammarCopyCASEobl": "Oblicuo", + "grammarCopyVOICEact": "Activo", + "grammarCopyPUNCTTYPEbrck": "Soporte", + "grammarCopyNOUNTYPEart": "Artículo", + "grammarCopyNUMBERsing": "Singular", + "grammarCopyGENDERmasc": "Hombre", + "grammarCopyVERBTYPEmod": "Modal", + "grammarCopyADVTYPEadverbial": "Adverbial", + "grammarCopyTENSEperi": "Perifrástico", + "grammarCopyNUMFORMdigit": "Dígitos", + "grammarCopyNOUNTYPEnot_proper": "No procede", + "grammarCopyNUMTYPEcard": "Cardenal", + "grammarCopyNOUNTYPEprop": "Adecuado", + "grammarCopyPUNCTTYPEdash": "Dash", + "grammarCopyPUNCTTYPEyes": "Sí", + "grammarCopyPUNCTTYPEsemi": "Punto y coma", + "grammarCopyPUNCTTYPEcomm": "Coma", + "grammarCopyMOODcnd": "Condicional", + "grammarCopyCASEacc": "Acusativo", + "grammarCopyPARTTYPEpart": "Partitivo", + "grammarCopyTENSEpast": "Anterior", + "grammarCopyDEGREEsup": "Superlativo", + "grammarCopyPUNCTTYPEcolo": "Colon", + "grammarCopyPERSON3": "Tercera persona", + "grammarCopyNUMBERplur": "Plural", + "grammarCopyPRONTYPEnpr": "Nombre propio", + "grammarCopyPRONTYPEinterrogative": "Preguntas", + "grammarCopyPOLITEinfm": "Informal", + "grammarCopyADVTYPEtim": "Tiempo", + "grammarCopyPOLARITYneg": "Negativo", + "grammarCopyNUMTYPEtot": "Total", + "grammarCopyADVTYPEadnomial": "Adnominal", + "grammarCopyASPECTprog": "Progresiva", + "grammarCopyMOODsub": "Subjuntivo", + "grammarCopyVERBFORMcomplementive": "Complementive", + "grammarCopyCASEnom": "Nominativo", + "grammarCopyTENSEfut": "Futuro", + "grammarCopyCASEdat": "Dativo", + "grammarCopyTENSEpres": "Presente", + "grammarCopyGENDERneut": "Esterilizar", + "grammarCopyPRONTYPErel": "Relativa", + "grammarCopyVERBFORMfinalEnding": "Final", + "grammarCopyPRONTYPEdem": "Demostrativo", + "grammarCopyPREPCASEpre": "Preposicional", + "grammarCopyVERBFORMfin": "Finito", + "grammarCopyDEGREEpos": "Positivo", + "grammarCopyPUNCTTYPEquot": "Presupuesto", + "grammarCopyVERBFORMger": "Redondo", + "grammarCopyVOICEpass": "Pasivo", + "grammarCopyCASEgen": "Genitivo", + "grammarCopyTENSEprs": "Presente", + "grammarCopyDEFINITEdef": "Definitivo", + "grammarCopyNUMTYPEord": "Ordinal", + "grammarCopyCASEins": "Instrumental", + "grammarCopyVERBFORMinf": "Infinitivo", + "grammarCopyNUMFORMlong": "Largo", + "grammarCopyCASEloc": "Locativo", + "grammarCopyMOODind": "Indicativo", + "grammarCopyDEGREEcmp": "Comparativa", + "grammarCopyCASErelativeCase": "Relativa", + "grammarCopyPUNCTTYPEexcl": "Exclamativo", + "grammarCopyPERSON1": "En primera persona", + "grammarCopyPUNCTSIDEini": "Inicial", + "grammarCopyGENDERperson": "Persona", + "grammarCopyFOREIGNyes": "Extranjero", + "grammarCopyVOICEvoice": "Voz", + "grammarCopyVERBTYPEverbType": "Verbo", + "grammarCopyPOSSpass": "Posesivo", + "grammarCopyPREPCASEprepCase": "Preposicional", + "grammarCopyNUMTYPEnumType": "Numeral", + "grammarCopyNOUNTYPEnounType": "Sustantivo", + "grammarCopyREFLEXreflex": "Reflexivo", + "grammarCopyPRONTYPEpronType": "Pronombre", + "grammarCopyPUNCTSIDEpunctSide": "Puntuación Lado", + "grammarCopyVERBFORMverbForm": "Verbo", + "grammarCopyGENDERgender": "Género", + "grammarCopyMOODmood": "Estado de ánimo", + "grammarCopyASPECTaspect": "Aspecto", + "grammarCopyPUNCTTYPEpunctType": "Puntuación", + "grammarCopyTENSEtense": "Tense", + "grammarCopyDEGREEdegree": "Titulación", + "grammarCopyPOLITEpolite": "Cortesía", + "grammarCopyADVTYPEadvType": "Adverbio", + "grammarCopyNUMFORMnumber": "Número", + "grammarCopyCONJTYPEconjType": "Conjunción", + "grammarCopyPOLARITYpolarity": "Polaridad", + "grammarCopyCASEcase": "Caso", + "grammarCopyDEFINITEdefinite": "Definitividad", + "grammarCopyNUMFORMnumForm": "Numeral", + "grammarCopyPRONTYPEadn": "Adnominal", + "grammarCopyVOCvoc": "Vocativo", + "grammarCopyCMPLcmpl": "Complementizer", + "grammarCopyADVadv": "Adverbial", + "grammarCopyMOODjus": "Jussive", + "grammarCopyGENDERcom": "Común", + "grammarCopyREFLEXrflx": "Reflexivo", + "grammarCopyPARTTYPEpar": "Partitivo", + "grammarCopySPCspc": "Específico", + "grammarCopyTENSEpqp": "Pluperfect", + "grammarCopyREFLEXref": "Reflexivo", + "grammarCopyPUNCTTYPEnshrt": "Corto", + "grammarCopyNUMBERdual": "Doble", + "grammarCopyNUMFORMlng": "Largo", + "grammarCopyVOICEmid": "Medio", + "grammarCopyINTRELintRel": "Interrogativo, relativo", + "grammarCopyINTint": "Preguntas", + "grammarCopyVOICEcaus": "Causa", + "grammarCopyEVIDENTevident": "Evidencialidad", + "grammarCopyNUMFORMnumberPsor": "Número del poseedor", + "grammarCopyASPECThab": "Habitual", + "grammarCopyCASEabl": "Ablativo", + "grammarCopyCASEall": "Allative", + "grammarCopyCASEess": "Essive", + "grammarCopyCASEtra": "Translativo", + "grammarCopyCASEequ": "Ecuativo", + "grammarCopyCASEdis": "Distributivo", + "grammarCopyCASEabs": "Absolutivo", + "grammarCopyCASEerg": "Ergativa", + "grammarCopyCASEcau": "Causal", + "grammarCopyCASEben": "Benefactive", + "grammarCopyCASEtem": "Temporal", + "grammarCopyCONJTYPEcoord": "Coordinación", + "grammarCopyDEFINITEcons": "Construir el Estado", + "grammarCopyDEGREEabs": "Grado absoluto", + "grammarCopyEVIDENTfh": "Evidencialidad de los hechos", + "grammarCopyEVIDENTnfh": "Evidencialidad no factual", + "grammarCopyMOODopt": "Optativo", + "grammarCopyMOODadm": "Admirable", + "grammarCopyMOODdes": "Desiderativo", + "grammarCopyMOODnec": "Necesidades", + "grammarCopyMOODpot": "Posible", + "grammarCopyMOODprp": "Propositivo", + "grammarCopyMOODqot": "Cita", + "grammarCopyNUMFORMword": "Forma verbal", + "grammarCopyNUMFORMroman": "Número romano", + "grammarCopyNUMFORMletter": "Formulario de carta", + "grammarCopyNUMTYPEmult": "Multiplicativo", + "grammarCopyNUMTYPEfrac": "Fraccional", + "grammarCopyNUMTYPEsets": "Establecer", + "grammarCopyNUMTYPErange": "Gama", + "grammarCopyNUMTYPEdist": "Distributivo", + "grammarCopyNUMBERtri": "Ensayo", + "grammarCopyNUMBERpauc": "Paucal", + "grammarCopyNUMBERgrpa": "Gran Paucal", + "grammarCopyNUMBERgrpl": "Mayor Plural", + "grammarCopyNUMBERinv": "Inversa", + "grammarCopyPERSON0": "Cero", + "grammarCopyPERSON4": "Cuarto", + "grammarCopyPOLITEform": "Formal", + "grammarCopyPOLITEelev": "Elevado", + "grammarCopyPOLITEhumb": "Humilde", + "grammarCopyPRONTYPEemp": "Enfático", + "grammarCopyPRONTYPEexc": "Exclamativo", + "grammarCopyPRONTYPErcp": "Reciprocal", + "grammarCopyPRONTYPEintRelPronType": "Interrogativo-Relativo", + "grammarCopyTENSEaor": "aoristo", + "grammarCopyTENSEeps": "Epistémica", + "grammarCopyTENSEprosp": "Prospectiva", + "grammarCopyVERBFORMpart": "Participio", + "grammarCopyVERBFORMconv": "Converb", + "grammarCopyVERBFORMvnoun": "Sustantivo verbal", + "grammarCopyVOICEantip": "Antipasivo", + "grammarCopyVOICEcauVoice": "Causa", + "grammarCopyVOICedir": "Directo", + "grammarCopyVOICEinvVoice": "Inversa", + "grammarCopyVOICErcpVoice": "Reciprocal", + "grammarCopyPOS": "Parte de la oración", + "grammarCopyGENDER": "Género", + "grammarCopyPERSON": "Persona", + "grammarCopyMOOD": "Estado de ánimo", + "grammarCopyPUNCTTYPE": "Tipo de puntuación", + "grammarCopyASPECT": "Aspecto", + "grammarCopyCASE": "Caso", + "grammarCopyVOICE": "Voz", + "grammarCopyNOUNTYPE": "Tipo de sustantivo", + "grammarCopyVERBTYPE": "Tipo de verbo", + "grammarCopyADVTYPE": "Tipo de adverbio", + "grammarCopyNUMFORM": "Forma numérica", + "grammarCopyNUMTYPE": "Tipo de número", + "grammarCopyNUMBER": "Número", + "grammarCopyDEFINITE": "Definitividad", + "grammarCopyDEGREE": "Titulación", + "grammarCopyEVIDENT": "Evidencialidad", + "grammarCopyFOREIGN": "Extranjero", + "grammarCopyPOLARITY": "Polaridad", + "grammarCopyPOLITE": "Cortesía", + "grammarCopyPREPCASE": "Caso preposicional", + "grammarCopyPRONTYPE": "Tipo de pronombre", + "grammarCopyPUNCTSIDE": "Puntuación Lado", + "grammarCopyREFLEX": "Reflexivo", + "grammarCopyTENSE": "Tense", + "grammarCopyVERBFORM": "Forma verbal", + "grammarCopyCONJTYPE": "Tipo de conjunción", + "grammarCopySPC": "Especificidad", + "grammarCopyPARTTYPE": "Tipo Partitivo", + "grammarCopyINTREL": "Interrogativo-Relativo", + "grammarCopyNUMFORMpsor": "Número del poseedor", + "grammarCopyUNKNOWN": "Desconocido", + "grammarCopyNUMBERPSOR": "Número del poseedor", + "grammarCopyPOSS": "Posesivo", + "grammarCopyASPECTimp": "Aspecto imperfectivo", + "grammarCopyCASEvoc": "Vocativo", + "grammarCopyCASEcom": "Comitative", + "grammarCopyCASEpar": "Partitivo", + "grammarCopyCASEadv": "Adverbial", + "grammarCopyCASEref": "Referencial", + "grammarCopyCASErel": "Relativa", + "grammarCopyCASEsub": "Subesivo", + "grammarCopyCASEsup": "Superessive", + "grammarCopyCASEaccdat": "Acusativo-dativo", + "grammarCopyCASEpre": "Preposicional", + "grammarCopyCONJTYPEsub": "Subordinación", + "grammarCopyCONJTYPEcmp": "Comparativa", + "grammarCopyDEFINITEind": "Indefinido", + "grammarCopyMOODint": "Modo interrogativo", + "grammarCopyNOUNTYPEcomm": "Sustantivo común", + "grammarCopyNUMBERPSORsing": "Singular del poseedor", + "grammarCopyNUMBERPSORplur": "Plural del poseedor", + "grammarCopyNUMBERPSORdual": "Doble del poseedor", + "grammarCopyPOLARITYpos": "Polaridad positiva", + "grammarCopyPOSSyes": "Posesivo", + "grammarCopyPREPCASEnpr": "No preposicional", + "grammarCopyPRONTYPEprs": "Personal", + "grammarCopyPRONTYPEint": "Preguntas", + "grammarCopyPRONTYPEtot": "Total", + "grammarCopyPRONTYPEneg": "Negativo", + "grammarCopyPRONTYPEart": "Artículo", + "grammarCopyPRONTYPEind": "Indefinido", + "grammarCopyPRONTYPEintrel": "Interrogativo-Relativo", + "grammarCopyPUNCTSIDEfin": "Puntuación final", + "grammarCopyPUNCTTYPEperi": "Periodo", + "grammarCopyREFLEXyes": "Reflexivo", + "grammarCopyTENSEimp": "Imperfect", + "grammarCopyVERBFORMsup": "SuApine", + "grammarCopyVERBFORMadn": "Adnominal", + "grammarCopyVERBFORMlng": "Largo", + "grammarCopyVERBTYPEcaus": "Verbo causativo", + "grammarCopyVOICEcau": "Causa", + "grammarCopyVOICEdir": "Directo", + "grammarCopyVOICEinv": "Inversa", + "grammarCopyVOICErcp": "Reciprocal", + "other": "Otros", + "botModeValidation": "Seleccione un modo de chat", + "clickBestOption": "Elija las mejores opciones para traducir su mensaje", + "unlockedLanguageTools": "Has desbloqueado las herramientas lingüísticas para este mensaje. Pruébalas haciendo clic a continuación.", + "botSettingsSubtitle": "Invitar a un bot a moderar la actividad del chat", + "invitePeople": "Invitar a usuarios", + "invitePeopleChatSubtitle": "Invitar a usuarios o administradores a este chat", + "invitePeopleSpaceSubtitle": "Invitar a usuarios o administradores a este espacio", + "noCapacityLimit": "Sin límite de capacidad", + "downloadGroupText": "Descargar texto del grupo" +} diff --git a/lib/pages/chat/chat_event_list.dart b/lib/pages/chat/chat_event_list.dart index b091be925..5152f49a4 100644 --- a/lib/pages/chat/chat_event_list.dart +++ b/lib/pages/chat/chat_event_list.dart @@ -6,8 +6,6 @@ import 'package:fluffychat/pages/chat/seen_by_row.dart'; import 'package:fluffychat/pages/chat/typing_indicators.dart'; import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart'; import 'package:fluffychat/pangea/enum/instructions_enum.dart'; -import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; -import 'package:fluffychat/pangea/widgets/chat/locked_chat_message.dart'; import 'package:fluffychat/utils/account_config.dart'; import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/filtered_timeline_extension.dart'; @@ -99,14 +97,6 @@ class ChatEventList extends StatelessWidget { ); } - // #Pangea - if (i == 1) { - return (controller.room.isLocked) && !controller.room.isRoomAdmin - ? const LockedChatMessage() - : const SizedBox.shrink(); - } - // Pangea# - // Request history button or progress indicator: if (i == events.length + 1) { if (controller.timeline!.isRequestingHistory) { @@ -158,10 +148,7 @@ class ChatEventList extends StatelessWidget { return const SizedBox(height: AppConfig.toolbarMaxHeight); // Pangea# } - // #Pangea - // i--; - i = i - 2; - // Pangea# + i--; final event = events[i]; final animateIn = animateInEventIndex != null && diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart index 7b2a3cf2b..29c319547 100644 --- a/lib/pages/chat/chat_view.dart +++ b/lib/pages/chat/chat_view.dart @@ -16,7 +16,6 @@ import 'package:fluffychat/pangea/widgets/chat/chat_floating_action_button.dart' import 'package:fluffychat/pangea/widgets/chat/chat_view_background.dart'; import 'package:fluffychat/pangea/widgets/chat/input_bar_wrapper.dart'; import 'package:fluffychat/utils/account_config.dart'; -import 'package:fluffychat/widgets/chat_settings_popup_menu.dart'; import 'package:fluffychat/widgets/connection_status_header.dart'; import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/mxc_image.dart'; @@ -117,9 +116,16 @@ class ChatView extends StatelessWidget { // #Pangea } else { return [ - ChatSettingsPopupMenu( - controller.room, - (!controller.room.isDirectChat && !controller.room.isArchived), + IconButton( + icon: const Icon(Icons.info_outline), + tooltip: L10n.of(context)!.chatDetails, + onPressed: () { + if (GoRouterState.of(context).uri.path.endsWith('/details')) { + context.go('/rooms/${controller.room.id}'); + } else { + context.go('/rooms/${controller.room.id}/details'); + } + }, ), ]; } diff --git a/lib/pages/chat_details/chat_details.dart b/lib/pages/chat_details/chat_details.dart index 2edbc2867..76591e870 100644 --- a/lib/pages/chat_details/chat_details.dart +++ b/lib/pages/chat_details/chat_details.dart @@ -1,8 +1,8 @@ import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:collection/collection.dart'; import 'package:file_picker/file_picker.dart'; -import 'package:fluffychat/pages/chat_details/chat_details_view.dart'; import 'package:fluffychat/pages/settings/settings.dart'; +import 'package:fluffychat/pangea/pages/chat_details/pangea_chat_details.dart'; import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_description_button.dart'; import 'package:fluffychat/pangea/utils/set_class_name.dart'; import 'package:fluffychat/utils/platform_infos.dart'; @@ -199,7 +199,10 @@ class ChatDetailsController extends State { static const fixedWidth = 360.0; @override - Widget build(BuildContext context) => ChatDetailsView(this); + // #Pangea + Widget build(BuildContext context) => PangeaChatDetailsView(this); + // Widget build(BuildContext context) => ChatDetailsView(this); + // Pangea# // #Pangea bool showEditNameIcon = false; @@ -220,6 +223,29 @@ class ChatDetailsController extends State { if (mounted) setState(() {}); } + Future toggleMute() async { + final client = Matrix.of(context).client; + final Room? room = client.getRoomById(roomId!); + if (room == null) return; + await showFutureLoadingDialog( + context: context, + future: () async { + await (room.pushRuleState == PushRuleState.notify + ? room.setPushRuleState(PushRuleState.mentionsOnly) + : room.setPushRuleState(PushRuleState.notify)); + }, + ); + + // wait for push rule update in sync + await client.onSync.stream.firstWhere( + (sync) => + sync.accountData != null && + sync.accountData!.isNotEmpty && + sync.accountData!.any((e) => e.type == 'm.push_rules'), + ); + if (mounted) setState(() {}); + } + @override void initState() { super.initState(); diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index 6040279b7..9f05f959d 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -1,5 +1,4 @@ import 'package:adaptive_dialog/adaptive_dialog.dart'; -import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pages/chat_details/chat_details.dart'; import 'package:fluffychat/pages/chat_details/participant_list_item.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; @@ -8,13 +7,11 @@ import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_des import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_details_toggle_add_students_tile.dart'; import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_invitation_buttons.dart'; import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart'; -import 'package:fluffychat/pangea/utils/lock_room.dart'; import 'package:fluffychat/pangea/widgets/chat/visibility_toggle.dart'; import 'package:fluffychat/pangea/widgets/conversation_bot/conversation_bot_settings.dart'; import 'package:fluffychat/utils/fluffy_share.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/widgets/avatar.dart'; -import 'package:fluffychat/widgets/chat_settings_popup_menu.dart'; import 'package:fluffychat/widgets/layouts/max_width_body.dart'; import 'package:fluffychat/widgets/matrix.dart'; import 'package:flutter/material.dart'; @@ -66,7 +63,7 @@ class ChatDetailsView extends StatelessWidget { leading: controller.widget.embeddedCloseButton ?? const Center(child: BackButton()), elevation: theme.appBarTheme.elevation, - actions: [ + actions: const [ // #Pangea // if (room.canonicalAlias.isNotEmpty) // IconButton( @@ -77,9 +74,9 @@ class ChatDetailsView extends StatelessWidget { // context, // ), // ), + // if (controller.widget.embeddedCloseButton == null) + // ChatSettingsPopupMenu(room, false), // Pangea# - if (controller.widget.embeddedCloseButton == null) - ChatSettingsPopupMenu(room, false), ], // #Pangea title: ClassNameHeader( @@ -460,44 +457,6 @@ class ChatDetailsView extends StatelessWidget { } }, ), - if (room.isRoomAdmin && !room.isDirectChat) - SwitchListTile.adaptive( - activeColor: AppConfig.activeToggleColor, - title: Text( - room.isSpace - ? L10n.of(context)!.lockSpace - : L10n.of(context)!.lockChat, - style: TextStyle( - color: - Theme.of(context).colorScheme.secondary, - fontWeight: FontWeight.bold, - ), - ), - secondary: CircleAvatar( - backgroundColor: - Theme.of(context).scaffoldBackgroundColor, - foregroundColor: iconColor, - child: Icon( - room.isLocked - ? Icons.lock_outlined - : Icons.no_encryption_outlined, - ), - ), - value: room.isLocked, - onChanged: (value) => showFutureLoadingDialog( - context: context, - future: () => value - ? lockRoom( - room, - Matrix.of(context).client, - ) - : unlockRoom( - room, - Matrix.of(context).client, - ), - ), - ), - const Divider(height: 1), // Pangea# ListTile( title: Text( diff --git a/lib/pages/chat_list/chat_list_item.dart b/lib/pages/chat_list/chat_list_item.dart index 9cbe6af82..0b5e61b55 100644 --- a/lib/pages/chat_list/chat_list_item.dart +++ b/lib/pages/chat_list/chat_list_item.dart @@ -1,6 +1,5 @@ import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:fluffychat/config/app_config.dart'; -import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; import 'package:fluffychat/pangea/utils/get_chat_list_item_subtitle.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/utils/room_status_extension.dart'; @@ -350,16 +349,6 @@ class ChatListItem extends StatelessWidget { ), ), const SizedBox(width: 8), - // #Pangea - if (room.isLocked) - const Padding( - padding: EdgeInsets.only(right: 4.0), - child: Icon( - Icons.lock_outlined, - size: 16, - ), - ), - // Pangea# AnimatedContainer( duration: FluffyThemes.animationDuration, curve: FluffyThemes.animationCurve, diff --git a/lib/pages/invitation_selection/invitation_selection.dart b/lib/pages/invitation_selection/invitation_selection.dart index 761f43271..4605a29fa 100644 --- a/lib/pages/invitation_selection/invitation_selection.dart +++ b/lib/pages/invitation_selection/invitation_selection.dart @@ -3,8 +3,6 @@ import 'dart:async'; import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:collection/collection.dart'; import 'package:fluffychat/pages/invitation_selection/invitation_selection_view.dart'; -import 'package:fluffychat/pangea/constants/class_default_values.dart'; -import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; import 'package:fluffychat/pangea/utils/bot_name.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/widgets/matrix.dart'; @@ -15,10 +13,6 @@ import 'package:matrix/matrix.dart'; import '../../utils/localized_exception_extension.dart'; -//#Pangea -enum InvitationSelectionMode { admin, member } -//Pangea# - class InvitationSelection extends StatefulWidget { final String roomId; const InvitationSelection({ @@ -76,80 +70,72 @@ class InvitationSelectionController extends State { } //#Pangea - // add all students (already local) from spaceParents who aren't already in room to eligibleStudents - // use room.members to get all users in room - bool _initialized = false; - Future> eligibleStudents( - BuildContext context, - String text, - ) async { - if (!_initialized) { - _initialized = true; - await requestParentSpaceParticipants(); - } + // // add all students (already local) from spaceParents who aren't already in room to eligibleStudents + // // use room.members to get all users in room + // bool _initialized = false; + // Future> eligibleStudents( + // BuildContext context, + // String text, + // ) async { + // if (!_initialized) { + // _initialized = true; + // await requestParentSpaceParticipants(); + // } - final eligibleStudents = []; - final spaceParents = room?.pangeaSpaceParents; - if (spaceParents == null) return eligibleStudents; + // final eligibleStudents = []; + // final spaceParents = room?.pangeaSpaceParents; + // if (spaceParents == null) return eligibleStudents; - final userId = Matrix.of(context).client.userID; - for (final Room space in spaceParents) { - eligibleStudents.addAll( - space.getParticipants().where( - (spaceUser) => - spaceUser.id != BotName.byEnvironment && - spaceUser.id != "@support:staging.pangea.chat" && - spaceUser.id != userId && - (text.isEmpty || - (spaceUser.displayName - ?.toLowerCase() - .contains(text.toLowerCase()) ?? - false) || - spaceUser.id.toLowerCase().contains(text.toLowerCase())), - ), - ); - } - return eligibleStudents; - } + // final userId = Matrix.of(context).client.userID; + // for (final Room space in spaceParents) { + // eligibleStudents.addAll( + // space.getParticipants().where( + // (spaceUser) => + // spaceUser.id != BotName.byEnvironment && + // spaceUser.id != "@support:staging.pangea.chat" && + // spaceUser.id != userId && + // (text.isEmpty || + // (spaceUser.displayName + // ?.toLowerCase() + // .contains(text.toLowerCase()) ?? + // false) || + // spaceUser.id.toLowerCase().contains(text.toLowerCase())), + // ), + // ); + // } + // return eligibleStudents; + // } - Future - eligibleStudentsAsSearchUserDirectoryResponse( - BuildContext context, - String text, - ) async { - return SearchUserDirectoryResponse( - results: (await eligibleStudents(context, text)) - .map( - (e) => Profile( - userId: e.id, - avatarUrl: e.avatarUrl, - displayName: e.displayName, - ), - ) - .toList(), - limited: false, - ); - } + // Future + // eligibleStudentsAsSearchUserDirectoryResponse( + // BuildContext context, + // String text, + // ) async { + // return SearchUserDirectoryResponse( + // results: (await eligibleStudents(context, text)) + // .map( + // (e) => Profile( + // userId: e.id, + // avatarUrl: e.avatarUrl, + // displayName: e.displayName, + // ), + // ) + // .toList(), + // limited: false, + // ); + // } - List studentsInRoom(BuildContext context) => - room - ?.getParticipants() - .where( - (u) => [Membership.join, Membership.invite].contains(u.membership), - ) - .toList() ?? - []; + // List studentsInRoom(BuildContext context) => + // room + // ?.getParticipants() + // .where( + // (u) => [Membership.join, Membership.invite].contains(u.membership), + // ) + // .toList() ?? + // []; //Pangea# - // #Pangea - // void inviteAction(BuildContext context, String id, String displayname) async { - void inviteAction( - BuildContext context, - String id, - String displayname, { - InvitationSelectionMode? mode, - }) async { - // Pangea# + void inviteAction(BuildContext context, String id, String displayname) async { final room = Matrix.of(context).client.getRoomById(roomId!)!; if (OkCancelResult.ok != await showOkCancelAlertDialog( @@ -168,16 +154,7 @@ class InvitationSelectionController extends State { } final success = await showFutureLoadingDialog( context: context, - //#Pangea - // future: () => room.invite(id), - future: () async { - if (mode == InvitationSelectionMode.admin) { - await inviteTeacherAction(room, id); - } else { - await room.invite(id); - } - }, - // Pangea# + future: () => room.invite(id), ); if (success.error == null) { ScaffoldMessenger.of(context).showSnackBar( @@ -191,13 +168,6 @@ class InvitationSelectionController extends State { } } - // #Pangea - Future inviteTeacherAction(Room room, String id) async { - await room.invite(id); - await room.setPower(id, ClassDefaultValues.powerLevelOfAdmin); - } - // Pangea# - void searchUserWithCoolDown(String text) async { coolDown?.cancel(); coolDown = Timer( @@ -218,15 +188,7 @@ class InvitationSelectionController extends State { final matrix = Matrix.of(context); SearchUserDirectoryResponse response; try { - //#Pangea - // response = await matrix.client.searchUserDirectory(text, limit: 10); - response = await (mode == InvitationSelectionMode.admin - ? matrix.client.searchUserDirectory(text, limit: 10) - : eligibleStudentsAsSearchUserDirectoryResponse( - context, - text, - )); - //Pangea# + response = await matrix.client.searchUserDirectory(text, limit: 10); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text((e).toLocalizedString(context))), @@ -264,67 +226,6 @@ class InvitationSelectionController extends State { }); } - //#Pangea - Room? _room; - Room? get room => _room ??= Matrix.of(context).client.getRoomById(roomId!); - - // request participants for all parent spaces - Future requestParentSpaceParticipants() async { - final spaceParents = room?.pangeaSpaceParents; - if (spaceParents != null) { - await Future.wait([ - ...spaceParents.map((r) async { - await r.requestParticipants(); - }), - room!.requestParticipants(), - ]); - } - } - - InvitationSelectionMode mode = InvitationSelectionMode.member; - - StreamSubscription? _spaceSubscription; - @override - void initState() { - Future.delayed( - Duration.zero, - () => setState( - () => mode = room?.isSpace ?? false - ? InvitationSelectionMode.admin - : InvitationSelectionMode.member, - ), - ); - _spaceSubscription = Matrix.of(context) - .client - .onSync - .stream - .where( - (event) => - event.rooms?.join?.keys.any( - (ithRoomId) => - room?.pangeaSpaceParents - .map((e) => e.id) - .contains(ithRoomId) ?? - false, - ) ?? - false, - ) - .listen( - (SyncUpdate syncUpdate) async { - await requestParentSpaceParticipants(); - setState(() {}); - }, - ); - super.initState(); - } - - @override - void dispose() { - _spaceSubscription?.cancel(); - super.dispose(); - } - //Pangea# - @override Widget build(BuildContext context) => InvitationSelectionView(this); } diff --git a/lib/pages/invitation_selection/invitation_selection_view.dart b/lib/pages/invitation_selection/invitation_selection_view.dart index 524005208..fb2ad8a0c 100644 --- a/lib/pages/invitation_selection/invitation_selection_view.dart +++ b/lib/pages/invitation_selection/invitation_selection_view.dart @@ -64,9 +64,7 @@ class InvitationSelectionView extends StatelessWidget { fontWeight: FontWeight.normal, ), // #Pangea - hintText: controller.mode == InvitationSelectionMode.admin - ? L10n.of(context)!.inviteUsersFromPangea - : L10n.of(context)!.inviteStudentByUserName, + hintText: L10n.of(context)!.inviteStudentByUserName, // hintText: L10n.of(context)!.inviteContactToGroup(groupName), // Pangea# prefixIcon: controller.loading @@ -93,18 +91,6 @@ class InvitationSelectionView extends StatelessWidget { builder: (context, snapshot) { final participants = room.getParticipants().map((user) => user.id).toSet(); - if (controller.mode != InvitationSelectionMode.admin && - room.spaceParents.isEmpty) { - return Padding( - padding: const EdgeInsets.all(16.0), - child: Center( - child: Text( - L10n.of(context)!.emptyInviteWarning, - textAlign: TextAlign.center, - ), - ), - ); - } return controller.foundProfiles.isNotEmpty ? ListView.builder( physics: const NeverScrollableScrollPhysics(), @@ -126,19 +112,11 @@ class InvitationSelectionView extends StatelessWidget { controller.foundProfiles[i].displayName ?? controller.foundProfiles[i].userId.localpart ?? L10n.of(context)!.user, - // #Pangea - mode: controller.mode, - // Pangea# ), ), ) : FutureBuilder>( - // #Pangea - future: controller.mode == InvitationSelectionMode.admin - ? controller.getContacts(context) - : controller.eligibleStudents(context, ""), - // future: controller.getContacts(context), - // Pangea# + future: controller.getContacts(context), builder: (BuildContext context, snapshot) { if (!snapshot.hasData) { return const Center( @@ -166,9 +144,6 @@ class InvitationSelectionView extends StatelessWidget { contacts[i].displayName ?? contacts[i].id.localpart ?? L10n.of(context)!.user, - // #Pangea - mode: controller.mode, - // Pangea# ), ), ); 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 2d631ceb7..6cb8bb962 100644 --- a/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/pangea_room_extension.dart @@ -259,7 +259,7 @@ extension PangeaRoom on Room { Future get isBotDM async => await _isBotDM; - bool get isLocked => _isLocked; + // bool get isLocked => _isLocked; bool isAnalyticsRoomOfUser(String userId) => _isAnalyticsRoomOfUser(userId); diff --git a/lib/pangea/extensions/pangea_room_extension/room_information_extension.dart b/lib/pangea/extensions/pangea_room_extension/room_information_extension.dart index 69494ac4f..86f6f6786 100644 --- a/lib/pangea/extensions/pangea_room_extension/room_information_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension/room_information_extension.dart @@ -58,24 +58,24 @@ extension RoomInformationRoomExtension on Room { Future get _isBotDM async => botOptions?.mode == BotMode.directChat; - bool get _isLocked { - if (isDirectChat) return false; - if (!isSpace) { - if (eventsDefaultPowerLevel == null) return false; - return (eventsDefaultPowerLevel ?? 0) >= - ClassDefaultValues.powerLevelOfAdmin; - } - for (final child in spaceChildren) { - if (child.roomId == null) continue; - final Room? room = client.getRoomById(child.roomId!); - if (room == null || room.isAnalyticsRoom || room.isArchived) continue; - if (!room._isLocked) { - return false; - } - } - return (eventsDefaultPowerLevel ?? 0) >= - ClassDefaultValues.powerLevelOfAdmin; - } + // bool get _isLocked { + // if (isDirectChat) return false; + // if (!isSpace) { + // if (eventsDefaultPowerLevel == null) return false; + // return (eventsDefaultPowerLevel ?? 0) >= + // ClassDefaultValues.powerLevelOfAdmin; + // } + // for (final child in spaceChildren) { + // if (child.roomId == null) continue; + // final Room? room = client.getRoomById(child.roomId!); + // if (room == null || room.isAnalyticsRoom || room.isArchived) continue; + // if (!room._isLocked) { + // return false; + // } + // } + // return (eventsDefaultPowerLevel ?? 0) >= + // ClassDefaultValues.powerLevelOfAdmin; + // } bool _isAnalyticsRoomOfUser(String userId) => isAnalyticsRoom && isMadeByUser(userId); diff --git a/lib/pangea/pages/chat_details/pangea_chat_details.dart b/lib/pangea/pages/chat_details/pangea_chat_details.dart new file mode 100644 index 000000000..f9ccdcdd5 --- /dev/null +++ b/lib/pangea/pages/chat_details/pangea_chat_details.dart @@ -0,0 +1,431 @@ +import 'package:adaptive_dialog/adaptive_dialog.dart'; +import 'package:fluffychat/pages/chat_details/chat_details.dart'; +import 'package:fluffychat/pages/chat_details/participant_list_item.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/pages/class_settings/class_name_header.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_details_toggle_add_students_tile.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart'; +import 'package:fluffychat/pangea/utils/download_chat.dart'; +import 'package:fluffychat/pangea/widgets/chat/visibility_toggle.dart'; +import 'package:fluffychat/pangea/widgets/conversation_bot/conversation_bot_settings.dart'; +import 'package:fluffychat/utils/fluffy_share.dart'; +import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; +import 'package:fluffychat/widgets/avatar.dart'; +import 'package:fluffychat/widgets/layouts/max_width_body.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + +class PangeaChatDetailsView extends StatelessWidget { + final ChatDetailsController controller; + + const PangeaChatDetailsView(this.controller, {super.key}); + + void _downloadChat(BuildContext context) async { + if (controller.roomId == null) return; + final Room? room = + Matrix.of(context).client.getRoomById(controller.roomId!); + if (room == null) return; + + final type = await showConfirmationDialog( + context: context, + title: L10n.of(context)!.downloadGroupText, + actions: [ + AlertDialogAction( + key: DownloadType.csv, + label: L10n.of(context)!.downloadCSVFile, + ), + AlertDialogAction( + key: DownloadType.txt, + label: L10n.of(context)!.downloadTxtFile, + ), + AlertDialogAction( + key: DownloadType.xlsx, + label: L10n.of(context)!.downloadXLSXFile, + ), + ], + ); + if (type == null) return; + downloadChat(room, type, context); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + + final room = Matrix.of(context).client.getRoomById(controller.roomId!); + if (room == null || room.membership == Membership.leave) { + return Scaffold( + appBar: AppBar( + title: Text(L10n.of(context)!.oopsSomethingWentWrong), + ), + body: Center( + child: Text(L10n.of(context)!.youAreNoLongerParticipatingInThisChat), + ), + ); + } + + final bool isGroupChat = !room.isDirectChat && !room.isSpace; + + return StreamBuilder( + stream: room.client.onRoomState.stream + .where((update) => update.roomId == room.id), + builder: (context, snapshot) { + var members = room.getParticipants().toList() + ..sort((b, a) => a.powerLevel.compareTo(b.powerLevel)); + members = members.take(10).toList(); + final actualMembersCount = (room.summary.mInvitedMemberCount ?? 0) + + (room.summary.mJoinedMemberCount ?? 0); + final canRequestMoreMembers = members.length < actualMembersCount; + final iconColor = theme.textTheme.bodyLarge!.color; + final displayname = room.getLocalizedDisplayname( + MatrixLocals(L10n.of(context)!), + ); + return Scaffold( + appBar: AppBar( + leading: controller.widget.embeddedCloseButton ?? + const Center(child: BackButton()), + elevation: theme.appBarTheme.elevation, + title: ClassNameHeader( + controller: controller, + room: room, + ), + backgroundColor: theme.appBarTheme.backgroundColor, + ), + body: MaxWidthBody( + child: ListView.builder( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: members.length + 1 + (canRequestMoreMembers ? 1 : 0), + itemBuilder: (BuildContext context, int i) => i == 0 + ? Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.all(32.0), + child: Stack( + children: [ + Hero( + tag: + controller.widget.embeddedCloseButton != + null + ? 'embedded_content_banner' + : 'content_banner', + child: Avatar( + mxContent: room.avatar, + name: displayname, + size: Avatar.defaultSize * 2.5, + ), + ), + if (!room.isDirectChat && + room.canChangeStateEvent( + EventTypes.RoomAvatar, + )) + Positioned( + bottom: 0, + right: 0, + child: FloatingActionButton.small( + onPressed: controller.setAvatarAction, + heroTag: null, + child: const Icon( + Icons.camera_alt_outlined, + ), + ), + ), + ], + ), + ), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextButton.icon( + onPressed: () => room.isDirectChat + ? null + : room.canChangeStateEvent( + EventTypes.RoomName, + ) + ? controller.setDisplaynameAction() + : FluffyShare.share( + displayname, + context, + copyOnly: true, + ), + icon: Icon( + room.isDirectChat + ? Icons.chat_bubble_outline + : room.canChangeStateEvent( + EventTypes.RoomName, + ) + ? Icons.edit_outlined + : Icons.copy_outlined, + size: 16, + ), + style: TextButton.styleFrom( + foregroundColor: + theme.colorScheme.onSurface, + ), + label: Text( + room.isDirectChat + ? L10n.of(context)!.directChat + : displayname, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: const TextStyle(fontSize: 18), + ), + ), + TextButton.icon( + onPressed: () => room.isDirectChat + ? null + : context.push( + '/rooms/${controller.roomId}/details/members', + ), + icon: const Icon( + Icons.group_outlined, + size: 14, + ), + style: TextButton.styleFrom( + foregroundColor: + theme.colorScheme.secondary, + ), + label: Text( + L10n.of(context)!.countParticipants( + actualMembersCount, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ), + ], + ), + Divider(color: theme.dividerColor, height: 1), + if (isGroupChat && room.canInvite) + ConversationBotSettings( + key: controller.addConversationBotKey, + room: room, + ), + if (isGroupChat && room.canInvite) + Divider(color: theme.dividerColor, height: 1), + if (room.canInvite && !room.isDirectChat) + ListTile( + title: Text( + L10n.of(context)!.inviteStudentByUserName, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + leading: CircleAvatar( + backgroundColor: + Theme.of(context).scaffoldBackgroundColor, + foregroundColor: + Theme.of(context).textTheme.bodyLarge!.color, + child: const Icon( + Icons.person_add_outlined, + ), + ), + onTap: () => context.go('/rooms/${room.id}/invite'), + ), + if (room.canInvite && !room.isDirectChat) + Divider(color: theme.dividerColor, height: 1), + if (room.isSpace && room.isRoomAdmin) + SpaceDetailsToggleAddStudentsTile( + controller: controller, + ), + if (room.isSpace && room.isRoomAdmin) + Divider(color: theme.dividerColor, height: 1), + if (isGroupChat && room.isRoomAdmin) + ListTile( + title: Text( + L10n.of(context)!.editChatPermissions, + style: TextStyle( + color: theme.colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + subtitle: Text( + L10n.of(context)!.whoCanPerformWhichAction, + ), + leading: CircleAvatar( + backgroundColor: theme.scaffoldBackgroundColor, + foregroundColor: iconColor, + child: const Icon( + Icons.manage_accounts_outlined, + ), + ), + onTap: () => context.push( + '/rooms/${room.id}/details/permissions', + ), + ), + if (isGroupChat && room.isRoomAdmin) + Divider(color: theme.dividerColor, height: 1), + if (room.isRoomAdmin) + VisibilityToggle( + room: room, + setVisibility: controller.setVisibility, + iconColor: iconColor, + ), + if (room.isRoomAdmin) + Divider(color: theme.dividerColor, height: 1), + RoomCapacityButton( + room: room, + controller: controller, + ), + Divider(color: theme.dividerColor, height: 1), + if (isGroupChat) + ListTile( + title: Text( + L10n.of(context)!.downloadGroupText, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + leading: CircleAvatar( + backgroundColor: + Theme.of(context).scaffoldBackgroundColor, + foregroundColor: iconColor, + child: const Icon( + Icons.download_outlined, + ), + ), + onTap: () => _downloadChat(context), + ), + if (isGroupChat) + Divider(color: theme.dividerColor, height: 1), + if (isGroupChat) + ListTile( + title: Text( + L10n.of(context)!.muteChat, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + leading: CircleAvatar( + backgroundColor: + Theme.of(context).scaffoldBackgroundColor, + foregroundColor: iconColor, + child: Icon( + room.pushRuleState == PushRuleState.notify + ? Icons.volume_up + : Icons.volume_off, + ), + ), + onTap: controller.toggleMute, + ), + if (isGroupChat) + Divider(color: theme.dividerColor, height: 1), + ListTile( + title: Text( + L10n.of(context)!.leave, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + leading: CircleAvatar( + backgroundColor: + Theme.of(context).scaffoldBackgroundColor, + foregroundColor: iconColor, + child: const Icon( + Icons.logout_outlined, + ), + ), + onTap: () async { + var confirmed = OkCancelResult.ok; + var shouldGo = false; + // If user is only admin, room will be archived + final onlyAdmin = await room.isOnlyAdmin(); + // archiveSpace has its own popup; only show if not space + if (!room.isSpace) { + confirmed = await showOkCancelAlertDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.areYouSure, + okLabel: L10n.of(context)!.ok, + cancelLabel: L10n.of(context)!.cancel, + message: onlyAdmin + ? L10n.of(context)!.onlyAdminDescription + : L10n.of(context)!.leaveRoomDescription, + ); + } + if (confirmed == OkCancelResult.ok) { + if (room.isSpace) { + shouldGo = onlyAdmin + ? await room.archiveSpace( + context, + Matrix.of(context).client, + onlyAdmin: true, + ) + : await room.leaveSpace( + context, + Matrix.of(context).client, + ); + } else { + final success = await showFutureLoadingDialog( + context: context, + future: () async { + onlyAdmin + ? await room.archive() + : await room.leave(); + }, + ); + shouldGo = (success.error == null); + } + if (shouldGo) { + context.go('/rooms'); + } + } + }, + ), + Divider(color: theme.dividerColor, height: 1), + ListTile( + title: Text( + L10n.of(context)!.countParticipants( + actualMembersCount.toString(), + ), + style: TextStyle( + color: theme.colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ) + : i < members.length + 1 + ? ParticipantListItem(members[i - 1]) + : ListTile( + title: Text( + L10n.of(context)!.loadCountMoreParticipants( + (actualMembersCount - members.length).toString(), + ), + ), + leading: CircleAvatar( + backgroundColor: theme.scaffoldBackgroundColor, + child: const Icon( + Icons.group_outlined, + color: Colors.grey, + ), + ), + onTap: () => context.push( + '/rooms/${controller.roomId!}/details/members', + ), + trailing: const Icon(Icons.chevron_right_outlined), + ), + ), + ), + ); + }, + ); + } +} diff --git a/lib/pangea/pages/class_settings/p_class_widgets/class_details_toggle_add_students_tile.dart b/lib/pangea/pages/class_settings/p_class_widgets/class_details_toggle_add_students_tile.dart index 051824659..320578fb0 100644 --- a/lib/pangea/pages/class_settings/p_class_widgets/class_details_toggle_add_students_tile.dart +++ b/lib/pangea/pages/class_settings/p_class_widgets/class_details_toggle_add_students_tile.dart @@ -1,5 +1,5 @@ +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_invitation_buttons.dart'; import 'package:flutter/material.dart'; - import 'package:flutter_gen/gen_l10n/l10n.dart'; import '../../../../pages/chat_details/chat_details.dart'; @@ -14,27 +14,33 @@ class SpaceDetailsToggleAddStudentsTile extends StatelessWidget { @override Widget build(BuildContext context) { - return ListTile( - title: Text( - L10n.of(context)!.addStudents, - style: TextStyle( - color: Theme.of(context).colorScheme.secondary, - fontWeight: FontWeight.bold, + return Column( + children: [ + ListTile( + title: Text( + L10n.of(context)!.addStudents, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + leading: CircleAvatar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + foregroundColor: Theme.of(context).textTheme.bodyLarge!.color, + child: const Icon( + Icons.add, + ), + ), + trailing: Icon( + controller.displayAddStudentOptions + ? Icons.keyboard_arrow_down_outlined + : Icons.keyboard_arrow_right_outlined, + ), + onTap: controller.toggleAddStudentOptions, ), - ), - leading: CircleAvatar( - backgroundColor: Theme.of(context).scaffoldBackgroundColor, - foregroundColor: Theme.of(context).textTheme.bodyLarge!.color, - child: const Icon( - Icons.add, - ), - ), - trailing: Icon( - controller.displayAddStudentOptions - ? Icons.keyboard_arrow_down_outlined - : Icons.keyboard_arrow_right_outlined, - ), - onTap: controller.toggleAddStudentOptions, + if (controller.displayAddStudentOptions) + ClassInvitationButtons(roomId: controller.roomId!), + ], ); } } diff --git a/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart b/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart index 5b22c793c..370128854 100644 --- a/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart +++ b/lib/pangea/pages/class_settings/p_class_widgets/room_capacity_button.dart @@ -86,11 +86,9 @@ class RoomCapacityButtonState extends State { foregroundColor: iconColor, child: const Icon(Icons.reduce_capacity), ), - subtitle: Text( + trailing: Text( (capacity == null) - ? spaceMode - ? L10n.of(context)!.spaceCapacityNotSet - : L10n.of(context)!.chatCapacityNotSet + ? L10n.of(context)!.noCapacityLimit : (nonAdmins != null) ? '$nonAdmins/$capacity' : '$capacity', diff --git a/lib/pangea/utils/download_chat.dart b/lib/pangea/utils/download_chat.dart index 96d941120..e9f11c3a8 100644 --- a/lib/pangea/utils/download_chat.dart +++ b/lib/pangea/utils/download_chat.dart @@ -23,13 +23,12 @@ enum DownloadType { txt, csv, xlsx } Future downloadChat( Room room, DownloadType type, - Client client, BuildContext context, ) async { List allPangeaMessages; try { - final List allEvents = await getAllEvents(room, client); + final List allEvents = await getAllEvents(room); final TimelineChunk chunk = TimelineChunk(events: allEvents); final Timeline timeline = Timeline( room: room, @@ -85,14 +84,14 @@ Future downloadChat( } } -Future> getAllEvents(Room room, Client client) async { +Future> getAllEvents(Room room) async { final GetRoomEventsResponse initalResp = - await client.getRoomEvents(room.id, Direction.b); + await room.client.getRoomEvents(room.id, Direction.b); if (initalResp.end == null) return []; String? nextStartToken = initalResp.end; List allMatrixEvents = initalResp.chunk; while (nextStartToken != null) { - final GetRoomEventsResponse resp = await client.getRoomEvents( + final GetRoomEventsResponse resp = await room.client.getRoomEvents( room.id, Direction.b, from: nextStartToken, diff --git a/lib/pangea/widgets/conversation_bot/conversation_bot_settings.dart b/lib/pangea/widgets/conversation_bot/conversation_bot_settings.dart index e6530ad3e..8bdff3616 100644 --- a/lib/pangea/widgets/conversation_bot/conversation_bot_settings.dart +++ b/lib/pangea/widgets/conversation_bot/conversation_bot_settings.dart @@ -70,6 +70,7 @@ class ConversationBotSettingsState extends State { fontWeight: FontWeight.bold, ), ), + subtitle: Text(L10n.of(context)!.botSettingsSubtitle), leading: CircleAvatar( backgroundColor: Theme.of(context).scaffoldBackgroundColor, foregroundColor: Theme.of(context).textTheme.bodyLarge!.color, @@ -78,7 +79,6 @@ class ConversationBotSettingsState extends State { expression: BotExpression.idle, ), ), - trailing: const Icon(Icons.settings), onTap: showBotOptionsDialog, ), ], diff --git a/lib/widgets/chat_settings_popup_menu.dart b/lib/widgets/chat_settings_popup_menu.dart index 6e216a38a..8d71a2859 100644 --- a/lib/widgets/chat_settings_popup_menu.dart +++ b/lib/widgets/chat_settings_popup_menu.dart @@ -123,7 +123,6 @@ class ChatSettingsPopupMenuState extends State { future: () => downloadChat( widget.room, DownloadType.txt, - Matrix.of(context).client, context, ), ); @@ -134,7 +133,6 @@ class ChatSettingsPopupMenuState extends State { future: () => downloadChat( widget.room, DownloadType.csv, - Matrix.of(context).client, context, ), ); @@ -145,7 +143,6 @@ class ChatSettingsPopupMenuState extends State { future: () => downloadChat( widget.room, DownloadType.xlsx, - Matrix.of(context).client, context, ), );