allow users to set room's searchability and public/private status seperatly, ensure public/private status determines which rooms show in space hierarchy (#1090)
This commit is contained in:
parent
7c5c28162e
commit
561359008c
10 changed files with 138 additions and 43 deletions
|
|
@ -4517,5 +4517,7 @@
|
|||
"spaceDescription": "Space description",
|
||||
"addSpaceDescription": "Add a space description",
|
||||
"notificationsOn": "Notifications on",
|
||||
"notificationsOff": "Notifications off"
|
||||
"notificationsOff": "Notifications off",
|
||||
"spaceCanBeFoundViaSearch": "Space can be found via search",
|
||||
"chatCanBeFoundViaSearch": "Chat can be found via search"
|
||||
}
|
||||
|
|
@ -12,7 +12,6 @@ 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:image_picker/image_picker.dart';
|
||||
import 'package:matrix/matrix.dart' as matrix;
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
enum AliasActions { copy, delete, setCanonical }
|
||||
|
|
@ -207,18 +206,24 @@ class ChatDetailsController extends State<ChatDetails> {
|
|||
void hoverEditNameIcon(bool hovering) =>
|
||||
setState(() => showEditNameIcon = !showEditNameIcon);
|
||||
|
||||
Future<void> setVisibility(matrix.Visibility visibility) async {
|
||||
Future<void> setJoinRules(JoinRules joinRules) async {
|
||||
if (roomId == null) return;
|
||||
final room = Matrix.of(context).client.getRoomById(roomId!);
|
||||
if (room == null) return;
|
||||
|
||||
final content = room.getState(EventTypes.RoomJoinRules)?.content ?? {};
|
||||
content['join_rule'] = joinRules.toString().replaceAll('JoinRules.', '');
|
||||
await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () async {
|
||||
await Matrix.of(context).client.setRoomVisibilityOnDirectory(
|
||||
roomId!,
|
||||
visibility: visibility,
|
||||
);
|
||||
await room.client.setRoomStateWithKey(
|
||||
roomId!,
|
||||
EventTypes.RoomJoinRules,
|
||||
'',
|
||||
content,
|
||||
);
|
||||
},
|
||||
);
|
||||
if (mounted) setState(() {});
|
||||
}
|
||||
|
||||
Future<void> toggleMute() async {
|
||||
|
|
|
|||
|
|
@ -342,8 +342,10 @@ class ChatDetailsView extends StatelessWidget {
|
|||
if (room.isRoomAdmin)
|
||||
VisibilityToggle(
|
||||
room: room,
|
||||
setVisibility: controller.setVisibility,
|
||||
setVisibility: (_) async {},
|
||||
setJoinRules: controller.setJoinRules,
|
||||
iconColor: iconColor,
|
||||
showSearchToggle: false,
|
||||
),
|
||||
// Pangea#
|
||||
Divider(color: theme.dividerColor),
|
||||
|
|
|
|||
|
|
@ -386,18 +386,27 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
await activeSpace.postLoad();
|
||||
|
||||
if (roomType == AddRoomType.subspace) {
|
||||
roomId = await client.createSpace(
|
||||
// #Pangea
|
||||
// name: names.first,
|
||||
// topic: names.last.isEmpty ? null : names.last,
|
||||
// visibility: activeSpace.joinRules == JoinRules.public
|
||||
// ? sdk.Visibility.public
|
||||
// : sdk.Visibility.private,
|
||||
// #Pangea
|
||||
// roomId = await client.createSpace(
|
||||
// name: names.first,
|
||||
// topic: names.last.isEmpty ? null : names.last,
|
||||
// visibility: activeSpace.joinRules == JoinRules.public
|
||||
// ? sdk.Visibility.public
|
||||
// : sdk.Visibility.private,
|
||||
// );
|
||||
roomId = await client.createRoom(
|
||||
preset: response.joinRules == sdk.JoinRules.public
|
||||
? sdk.CreateRoomPreset.publicChat
|
||||
: sdk.CreateRoomPreset.privateChat,
|
||||
creationContent: {'type': RoomCreationTypes.mSpace},
|
||||
visibility: response.joinRules == sdk.JoinRules.public
|
||||
? response.visibility
|
||||
: null,
|
||||
name: response.roomName,
|
||||
topic: response.roomDescription,
|
||||
visibility: response.visibility,
|
||||
// Pangea#
|
||||
powerLevelContentOverride: {'events_default': 100},
|
||||
);
|
||||
// Pangea#
|
||||
} else {
|
||||
roomId = await client.createGroupChat(
|
||||
// #Pangea
|
||||
|
|
@ -417,7 +426,9 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
// ]
|
||||
// : null,
|
||||
groupName: response.roomName,
|
||||
preset: CreateRoomPreset.publicChat,
|
||||
preset: response.joinRules == sdk.JoinRules.public
|
||||
? CreateRoomPreset.publicChat
|
||||
: CreateRoomPreset.privateChat,
|
||||
visibility: response.visibility,
|
||||
initialState: response.roomDescription.isNotEmpty
|
||||
? [
|
||||
|
|
|
|||
|
|
@ -84,7 +84,10 @@ class NewGroupView extends StatelessWidget {
|
|||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 32),
|
||||
secondary: const Icon(Icons.search_outlined),
|
||||
title: Text(L10n.of(context)!.groupCanBeFoundViaSearch),
|
||||
// #Pangea
|
||||
// title: Text(L10n.of(context)!.groupCanBeFoundViaSearch),
|
||||
title: Text(L10n.of(context)!.chatCanBeFoundViaSearch),
|
||||
// Pangea#
|
||||
value: controller.groupCanBeFound,
|
||||
onChanged: controller.loading
|
||||
? null
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ class NewSpaceController extends State<NewSpace> {
|
|||
TextEditingController nameController = TextEditingController();
|
||||
TextEditingController topicController = TextEditingController();
|
||||
bool publicGroup = false;
|
||||
// #Pangea
|
||||
bool spaceCanBeFound = true;
|
||||
// Pangea#
|
||||
bool loading = false;
|
||||
String? nameError;
|
||||
String? topicError;
|
||||
|
|
@ -48,10 +51,14 @@ class NewSpaceController extends State<NewSpace> {
|
|||
});
|
||||
}
|
||||
|
||||
// #Pangea
|
||||
void setSpaceCanBeFound(bool b) => setState(() => spaceCanBeFound = b);
|
||||
// Pangea#
|
||||
|
||||
void setPublicGroup(bool b) => setState(() => publicGroup = b);
|
||||
|
||||
// #Pangea
|
||||
List<StateEvent> initialState(String joinCode) {
|
||||
List<StateEvent> initialState(String joinCode, bool publicGroup) {
|
||||
return [
|
||||
StateEvent(
|
||||
type: EventTypes.RoomPowerLevels,
|
||||
|
|
@ -70,8 +77,9 @@ class NewSpaceController extends State<NewSpace> {
|
|||
StateEvent(
|
||||
type: sdk.EventTypes.RoomJoinRules,
|
||||
content: {
|
||||
ModelKey.joinRule:
|
||||
sdk.JoinRules.knock.toString().replaceAll('JoinRules.', ''),
|
||||
ModelKey.joinRule: publicGroup
|
||||
? sdk.JoinRules.public.toString().replaceAll('JoinRules.', '')
|
||||
: sdk.JoinRules.invite.toString().replaceAll('JoinRules.', ''),
|
||||
ModelKey.accessCode: joinCode,
|
||||
},
|
||||
),
|
||||
|
|
@ -104,8 +112,12 @@ class NewSpaceController extends State<NewSpace> {
|
|||
preset: publicGroup
|
||||
? sdk.CreateRoomPreset.publicChat
|
||||
: sdk.CreateRoomPreset.privateChat,
|
||||
// #Pangea
|
||||
visibility: publicGroup && spaceCanBeFound
|
||||
? sdk.Visibility.public
|
||||
: sdk.Visibility.private,
|
||||
// Pangea#
|
||||
creationContent: {'type': RoomCreationTypes.mSpace},
|
||||
visibility: publicGroup ? sdk.Visibility.public : null,
|
||||
roomAliasName: publicGroup
|
||||
? nameController.text.trim().toLowerCase().replaceAll(' ', '_')
|
||||
: null,
|
||||
|
|
@ -114,7 +126,7 @@ class NewSpaceController extends State<NewSpace> {
|
|||
powerLevelContentOverride: {'events_default': 100},
|
||||
initialState: [
|
||||
// #Pangea
|
||||
...initialState(joinCode),
|
||||
...initialState(joinCode, publicGroup),
|
||||
// Pangea#
|
||||
if (avatar != null)
|
||||
sdk.StateEvent(
|
||||
|
|
|
|||
|
|
@ -62,6 +62,15 @@ class NewSpaceView extends StatelessWidget {
|
|||
value: controller.publicGroup,
|
||||
onChanged: controller.setPublicGroup,
|
||||
),
|
||||
// #Pangea
|
||||
if (controller.publicGroup)
|
||||
SwitchListTile.adaptive(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 32),
|
||||
title: Text(L10n.of(context)!.spaceCanBeFoundViaSearch),
|
||||
value: controller.spaceCanBeFound,
|
||||
onChanged: controller.setSpaceCanBeFound,
|
||||
),
|
||||
// Pangea#
|
||||
ListTile(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 32),
|
||||
trailing: const Padding(
|
||||
|
|
|
|||
|
|
@ -316,8 +316,10 @@ class PangeaChatDetailsView extends StatelessWidget {
|
|||
if (room.isRoomAdmin)
|
||||
VisibilityToggle(
|
||||
room: room,
|
||||
setVisibility: controller.setVisibility,
|
||||
setVisibility: (_) async {},
|
||||
setJoinRules: controller.setJoinRules,
|
||||
iconColor: iconColor,
|
||||
showSearchToggle: false,
|
||||
),
|
||||
if (room.isRoomAdmin)
|
||||
Divider(color: theme.dividerColor, height: 1),
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import 'package:fluffychat/pangea/widgets/chat/visibility_toggle.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:matrix/matrix.dart' as matrix;
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
class AddRoomDialog extends StatefulWidget {
|
||||
final AddRoomType? roomType;
|
||||
|
|
@ -23,8 +24,13 @@ class AddRoomDialogState extends State<AddRoomDialog> {
|
|||
TextEditingController();
|
||||
|
||||
matrix.Visibility visibility = matrix.Visibility.public;
|
||||
JoinRules joinRules = JoinRules.public;
|
||||
|
||||
Future<void> setVisibility(matrix.Visibility newVisibility) async {
|
||||
Future<void> _setJoinRules(JoinRules newJoinRules) async {
|
||||
setState(() => joinRules = newJoinRules);
|
||||
}
|
||||
|
||||
Future<void> _setVisibility(matrix.Visibility newVisibility) async {
|
||||
setState(() => visibility = newVisibility);
|
||||
}
|
||||
|
||||
|
|
@ -93,9 +99,11 @@ class AddRoomDialogState extends State<AddRoomDialog> {
|
|||
),
|
||||
),
|
||||
VisibilityToggle(
|
||||
setVisibility: setVisibility,
|
||||
setJoinRules: _setJoinRules,
|
||||
setVisibility: _setVisibility,
|
||||
spaceMode: widget.roomType == AddRoomType.subspace,
|
||||
visibility: visibility,
|
||||
joinRules: joinRules,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(20),
|
||||
|
|
@ -118,6 +126,7 @@ class AddRoomDialogState extends State<AddRoomDialog> {
|
|||
RoomResponse(
|
||||
roomName: _roomNameController.text,
|
||||
roomDescription: _roomDescriptionController.text,
|
||||
joinRules: joinRules,
|
||||
visibility: visibility,
|
||||
),
|
||||
);
|
||||
|
|
@ -138,11 +147,13 @@ class AddRoomDialogState extends State<AddRoomDialog> {
|
|||
class RoomResponse {
|
||||
final String roomName;
|
||||
final String roomDescription;
|
||||
final JoinRules joinRules;
|
||||
final matrix.Visibility visibility;
|
||||
|
||||
RoomResponse({
|
||||
required this.roomName,
|
||||
required this.roomDescription,
|
||||
required this.joinRules,
|
||||
required this.visibility,
|
||||
});
|
||||
|
||||
|
|
@ -150,6 +161,7 @@ class RoomResponse {
|
|||
return {
|
||||
'roomName': roomName,
|
||||
'roomDescripion': roomDescription,
|
||||
'joinRules': joinRules,
|
||||
'visibility': visibility,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,26 +9,35 @@ class VisibilityToggle extends StatelessWidget {
|
|||
final Room? room;
|
||||
final Color? iconColor;
|
||||
final Future<void> Function(matrix.Visibility) setVisibility;
|
||||
final Future<void> Function(JoinRules) setJoinRules;
|
||||
final bool spaceMode;
|
||||
final matrix.Visibility visibility;
|
||||
final JoinRules joinRules;
|
||||
|
||||
final bool showSearchToggle;
|
||||
|
||||
const VisibilityToggle({
|
||||
required this.setVisibility,
|
||||
required this.setJoinRules,
|
||||
this.room,
|
||||
this.iconColor,
|
||||
this.spaceMode = false,
|
||||
this.visibility = matrix.Visibility.private,
|
||||
this.joinRules = JoinRules.invite,
|
||||
this.showSearchToggle = true,
|
||||
super.key,
|
||||
});
|
||||
|
||||
bool get _isPublic => room != null
|
||||
? room!.joinRules == matrix.JoinRules.public
|
||||
: joinRules == matrix.JoinRules.public;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder(
|
||||
future: room != null
|
||||
? Matrix.of(context).client.getRoomVisibilityOnDirectory(room!.id)
|
||||
: null,
|
||||
builder: (context, snapshot) {
|
||||
return SwitchListTile.adaptive(
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SwitchListTile.adaptive(
|
||||
activeColor: AppConfig.activeToggleColor,
|
||||
title: Text(
|
||||
room?.isSpace ?? spaceMode
|
||||
|
|
@ -44,16 +53,44 @@ class VisibilityToggle extends StatelessWidget {
|
|||
foregroundColor: iconColor,
|
||||
child: const Icon(Icons.public_outlined),
|
||||
),
|
||||
value: room != null
|
||||
? snapshot.hasData
|
||||
? snapshot.data == matrix.Visibility.public
|
||||
: false
|
||||
: visibility == matrix.Visibility.public,
|
||||
onChanged: (value) => setVisibility(
|
||||
value ? matrix.Visibility.public : matrix.Visibility.private,
|
||||
value: _isPublic,
|
||||
onChanged: (value) =>
|
||||
setJoinRules(value ? JoinRules.public : JoinRules.invite),
|
||||
),
|
||||
if (_isPublic && showSearchToggle)
|
||||
FutureBuilder(
|
||||
future: room != null
|
||||
? Matrix.of(context)
|
||||
.client
|
||||
.getRoomVisibilityOnDirectory(room!.id)
|
||||
: null,
|
||||
builder: (context, snapshot) {
|
||||
return SwitchListTile.adaptive(
|
||||
activeColor: AppConfig.activeToggleColor,
|
||||
title: Text(
|
||||
room?.isSpace ?? spaceMode
|
||||
? L10n.of(context)!.spaceCanBeFoundViaSearch
|
||||
: L10n.of(context)!.chatCanBeFoundViaSearch,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
secondary: CircleAvatar(
|
||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
foregroundColor: iconColor,
|
||||
child: const Icon(Icons.search_outlined),
|
||||
),
|
||||
value: room != null
|
||||
? room!.joinRules == matrix.JoinRules.public
|
||||
: visibility == matrix.Visibility.public,
|
||||
onChanged: (value) => setVisibility(
|
||||
value ? matrix.Visibility.public : matrix.Visibility.private,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue