From 3226dc5a11e4da04c973cd62534f455cb4d3718b Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Sun, 1 Aug 2021 08:05:40 +0200 Subject: [PATCH] feat: Implement new space view --- assets/l10n/intl_en.arb | 25 +++++++++++++ lib/config/routes.dart | 10 ++++++ lib/pages/chat_list.dart | 20 ++++++----- lib/pages/new_space.dart | 43 ++++++++++++++++++++++ lib/pages/views/chat_list_view.dart | 12 +++++++ lib/pages/views/new_space_view.dart | 55 +++++++++++++++++++++++++++++ 6 files changed, 156 insertions(+), 9 deletions(-) create mode 100644 lib/pages/new_space.dart create mode 100644 lib/pages/views/new_space_view.dart diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index be924a2c..134556de 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -120,6 +120,11 @@ "type": "text", "placeholders": {} }, + "publicSpace": "Public space", + "@publicSpace": { + "type": "text", + "placeholders": {} + }, "acceptedTheInvitation": "{username} accepted the invitation", "@acceptedTheInvitation": { "type": "text", @@ -671,6 +676,11 @@ "type": "text", "placeholders": {} }, + "createNewSpace": "Create new space", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, "crossSigningDisabled": "Cross-signing off", "@crossSigningDisabled": { "type": "text", @@ -908,6 +918,11 @@ "type": "text", "placeholders": {} }, + "enterASpacepName": "Enter a space name", + "@enterASpaceName": { + "type": "text", + "placeholders": {} + }, "enterAUsername": "Enter a username", "@enterAUsername": { "type": "text", @@ -973,6 +988,11 @@ "type": "text", "placeholders": {} }, + "spaceIsPublic": "Space is public", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, "groupWith": "Group with {displayname}", "@groupWith": { "type": "text", @@ -1429,6 +1449,11 @@ "type": "text", "placeholders": {} }, + "spaceName": "Space name", + "@spaceName": { + "type": "text", + "placeholders": {} + }, "participatingUserDevices": "Participating user devices", "@participatingUserDevices": { "type": "text", diff --git a/lib/config/routes.dart b/lib/config/routes.dart index bf9bdaf6..44dfc19a 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -1,6 +1,7 @@ import 'package:fluffychat/pages/archive.dart'; import 'package:fluffychat/pages/homeserver_picker.dart'; import 'package:fluffychat/pages/invitation_selection.dart'; +import 'package:fluffychat/pages/new_space.dart'; import 'package:fluffychat/pages/settings_account.dart'; import 'package:fluffychat/pages/settings_chat.dart'; import 'package:fluffychat/pages/settings_emotes.dart'; @@ -81,6 +82,10 @@ class AppRoutes { path: '/newgroup', widget: NewGroup(), ), + VWidget( + path: '/newspace', + widget: NewSpace(), + ), ], ), ]; @@ -108,6 +113,11 @@ class AppRoutes { widget: NewGroup(), buildTransition: _fadeTransition, ), + VWidget( + path: '/newspace', + widget: NewSpace(), + buildTransition: _fadeTransition, + ), VNester( path: ':roomid', widgetBuilder: (child) => SideViewLayout( diff --git a/lib/pages/chat_list.dart b/lib/pages/chat_list.dart index dd5e4fc9..9f9667f5 100644 --- a/lib/pages/chat_list.dart +++ b/lib/pages/chat_list.dart @@ -24,7 +24,14 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'bootstrap_dialog.dart'; enum SelectMode { normal, share, select } -enum PopupMenuAction { settings, invite, newGroup, setStatus, archive } +enum PopupMenuAction { + settings, + invite, + newGroup, + newSpace, + setStatus, + archive, +} class ChatList extends StatefulWidget { const ChatList({Key key}) : super(key: key); @@ -248,6 +255,9 @@ class ChatListController extends State { case PopupMenuAction.newGroup: VRouter.of(context).to('/newgroup'); break; + case PopupMenuAction.newSpace: + VRouter.of(context).to('/newspace'); + break; case PopupMenuAction.archive: VRouter.of(context).to('/archive'); break; @@ -294,11 +304,3 @@ class ChatListController extends State { return ChatListView(this); } } - -enum ChatListPopupMenuItemActions { - createGroup, - discover, - setStatus, - inviteContact, - settings, -} diff --git a/lib/pages/new_space.dart b/lib/pages/new_space.dart new file mode 100644 index 00000000..02ea4442 --- /dev/null +++ b/lib/pages/new_space.dart @@ -0,0 +1,43 @@ +import 'package:matrix/matrix.dart' as sdk; +import 'package:fluffychat/pages/views/new_space_view.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import 'package:flutter/material.dart'; +import 'package:matrix/matrix.dart'; +import 'package:vrouter/vrouter.dart'; + +class NewSpace extends StatefulWidget { + @override + NewSpaceController createState() => NewSpaceController(); +} + +class NewSpaceController extends State { + TextEditingController controller = TextEditingController(); + bool publicGroup = false; + + void setPublicGroup(bool b) => setState(() => publicGroup = b); + + void submitAction([_]) async { + final matrix = Matrix.of(context); + final roomID = await showFutureLoadingDialog( + context: context, + future: () => matrix.client.createRoom( + preset: publicGroup + ? sdk.CreateRoomPreset.public_chat + : sdk.CreateRoomPreset.private_chat, + creationContent: {'type': RoomCreationTypes.mSpace}, + visibility: publicGroup ? sdk.Visibility.public : null, + roomAliasName: publicGroup && controller.text.isNotEmpty + ? controller.text.trim().toLowerCase().replaceAll(' ', '_') + : null, + name: controller.text.isNotEmpty ? controller.text : null, + ), + ); + if (roomID.error == null) { + VRouter.of(context).to('/rooms/${roomID.result}/details'); + } + } + + @override + Widget build(BuildContext context) => NewSpaceView(this); +} diff --git a/lib/pages/views/chat_list_view.dart b/lib/pages/views/chat_list_view.dart index 427505d6..059f7a9d 100644 --- a/lib/pages/views/chat_list_view.dart +++ b/lib/pages/views/chat_list_view.dart @@ -119,6 +119,17 @@ class ChatListView extends StatelessWidget { ], ), ), + PopupMenuItem( + value: PopupMenuAction.newSpace, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon(Icons.group_work_outlined), + SizedBox(width: 12), + Text(L10n.of(context).createNewSpace), + ], + ), + ), PopupMenuItem( value: PopupMenuAction.invite, child: Row( @@ -366,6 +377,7 @@ class ChatListView extends StatelessWidget { enum ChatListPopupMenuItemActions { createGroup, + createSpace, discover, setStatus, inviteContact, diff --git a/lib/pages/views/new_space_view.dart b/lib/pages/views/new_space_view.dart new file mode 100644 index 00000000..45a3bf3b --- /dev/null +++ b/lib/pages/views/new_space_view.dart @@ -0,0 +1,55 @@ +import 'package:fluffychat/widgets/layouts/max_width_body.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import '../new_space.dart'; + +class NewSpaceView extends StatelessWidget { + final NewSpaceController controller; + + const NewSpaceView(this.controller, {Key key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + leading: BackButton(), + title: Text(L10n.of(context).createNewSpace), + elevation: 0, + ), + body: MaxWidthBody( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.all(12.0), + child: TextField( + controller: controller.controller, + autofocus: true, + autocorrect: false, + textInputAction: TextInputAction.go, + onSubmitted: controller.submitAction, + decoration: InputDecoration( + labelText: L10n.of(context).spaceName, + prefixIcon: Icon(Icons.people_outlined), + hintText: L10n.of(context).enterASpacepName), + ), + ), + SwitchListTile( + title: Text(L10n.of(context).spaceIsPublic), + value: controller.publicGroup, + onChanged: controller.setPublicGroup, + ), + Expanded( + child: Image.asset('assets/private_chat_wallpaper.png'), + ), + ], + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: controller.submitAction, + child: Icon(Icons.arrow_forward_outlined), + ), + ); + } +}