Initial commit
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
// SPDX-FileCopyrightText: 2019-Present Christian Kußowski
|
||||
// SPDX-FileCopyrightText: 2019-Present Contributors to FluffyChat
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import 'package:tatchat/l10n/l10n.dart';
|
||||
import 'package:tatchat/pages/chat_permissions_settings/chat_permissions_settings_view.dart';
|
||||
import 'package:tatchat/widgets/future_loading_dialog.dart';
|
||||
import 'package:tatchat/widgets/matrix.dart';
|
||||
import 'package:tatchat/widgets/permission_slider_dialog.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:material_ui/material_ui.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
class ChatPermissionsSettings extends StatefulWidget {
|
||||
const ChatPermissionsSettings({super.key});
|
||||
|
||||
@override
|
||||
ChatPermissionsSettingsController createState() =>
|
||||
ChatPermissionsSettingsController();
|
||||
}
|
||||
|
||||
class ChatPermissionsSettingsController extends State<ChatPermissionsSettings> {
|
||||
String? get roomId => GoRouterState.of(context).pathParameters['roomid'];
|
||||
Future<void> editPowerLevel(
|
||||
BuildContext context,
|
||||
String key,
|
||||
int currentLevel, {
|
||||
int? newLevel,
|
||||
String? category,
|
||||
}) async {
|
||||
final room = Matrix.of(context).client.getRoomById(roomId!)!;
|
||||
if (!room.canSendEvent(EventTypes.RoomPowerLevels)) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text(L10n.of(context).noPermission)));
|
||||
return;
|
||||
}
|
||||
newLevel ??= await showPermissionChooser(
|
||||
context,
|
||||
currentLevel: currentLevel,
|
||||
);
|
||||
if (newLevel == null) return;
|
||||
if (!context.mounted) return;
|
||||
final content = Map<String, dynamic>.from(
|
||||
room.getState(EventTypes.RoomPowerLevels)!.content,
|
||||
);
|
||||
if (category != null) {
|
||||
if (!content.containsKey(category)) {
|
||||
content[category] = <String, dynamic>{};
|
||||
}
|
||||
content[category][key] = newLevel;
|
||||
} else {
|
||||
content[key] = newLevel;
|
||||
}
|
||||
await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => room.client.setRoomStateWithKey(
|
||||
room.id,
|
||||
EventTypes.RoomPowerLevels,
|
||||
'',
|
||||
content,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Stream get onChanged => Matrix.of(context).client.onSync.stream.where(
|
||||
(e) =>
|
||||
(e.rooms?.join?.containsKey(roomId) ?? false) &&
|
||||
(e.rooms!.join![roomId!]?.timeline?.events?.any(
|
||||
(s) => s.type == EventTypes.RoomPowerLevels,
|
||||
) ??
|
||||
false),
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => ChatPermissionsSettingsView(this);
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
// SPDX-FileCopyrightText: 2019-Present Christian Kußowski
|
||||
// SPDX-FileCopyrightText: 2019-Present Contributors to FluffyChat
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import 'package:tatchat/l10n/l10n.dart';
|
||||
import 'package:tatchat/pages/chat_permissions_settings/chat_permissions_settings.dart';
|
||||
import 'package:tatchat/pages/chat_permissions_settings/permission_list_tile.dart';
|
||||
import 'package:tatchat/utils/matrix_live_kit_calls/matrix_live_kit_call_member.dart';
|
||||
import 'package:tatchat/widgets/layouts/max_width_body.dart';
|
||||
import 'package:tatchat/widgets/matrix.dart';
|
||||
import 'package:material_ui/material_ui.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
class ChatPermissionsSettingsView extends StatelessWidget {
|
||||
final ChatPermissionsSettingsController controller;
|
||||
|
||||
const ChatPermissionsSettingsView(this.controller, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: const Center(child: BackButton()),
|
||||
title: Text(L10n.of(context).chatPermissions),
|
||||
),
|
||||
body: MaxWidthBody(
|
||||
child: StreamBuilder(
|
||||
stream: controller.onChanged,
|
||||
builder: (context, _) {
|
||||
final roomId = controller.roomId;
|
||||
final room = roomId == null
|
||||
? null
|
||||
: Matrix.of(context).client.getRoomById(roomId);
|
||||
if (room == null) {
|
||||
return Center(child: Text(L10n.of(context).noRoomsFound));
|
||||
}
|
||||
final powerLevelsContent = Map<String, Object?>.from(
|
||||
room.getState(EventTypes.RoomPowerLevels)?.content ?? {},
|
||||
);
|
||||
final powerLevels = Map<String, dynamic>.from(powerLevelsContent)
|
||||
..removeWhere((k, v) => v is! int);
|
||||
final eventsPowerLevels = Map<String, int?>.from(
|
||||
powerLevelsContent.tryGetMap<String, int?>('events') ?? {},
|
||||
)..removeWhere((k, v) => v is! int);
|
||||
eventsPowerLevels[MatrixRtcCallMember.eventType] ??=
|
||||
powerLevelsContent['state_default'] as int? ?? 50;
|
||||
return Column(
|
||||
children: [
|
||||
ListTile(
|
||||
leading: const Icon(Icons.info_outlined),
|
||||
subtitle: Text(L10n.of(context).chatPermissionsDescription),
|
||||
),
|
||||
Divider(color: theme.dividerColor),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context).chatPermissions,
|
||||
style: TextStyle(
|
||||
color: theme.colorScheme.primary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
Column(
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
for (final entry in powerLevels.entries)
|
||||
PermissionsListTile(
|
||||
permissionKey: entry.key,
|
||||
permission: entry.value,
|
||||
onChanged: (level) => controller.editPowerLevel(
|
||||
context,
|
||||
entry.key,
|
||||
entry.value,
|
||||
newLevel: level,
|
||||
),
|
||||
canEdit: room.canChangePowerLevel,
|
||||
),
|
||||
Divider(color: theme.dividerColor),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context).notifications,
|
||||
style: TextStyle(
|
||||
color: theme.colorScheme.primary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
Builder(
|
||||
builder: (context) {
|
||||
const key = 'rooms';
|
||||
final value =
|
||||
powerLevelsContent.containsKey('notifications')
|
||||
? powerLevelsContent
|
||||
.tryGetMap<String, Object?>(
|
||||
'notifications',
|
||||
)
|
||||
?.tryGet<int>('rooms') ??
|
||||
0
|
||||
: 0;
|
||||
return PermissionsListTile(
|
||||
permissionKey: key,
|
||||
permission: value,
|
||||
category: 'notifications',
|
||||
canEdit: room.canChangePowerLevel,
|
||||
onChanged: (level) => controller.editPowerLevel(
|
||||
context,
|
||||
key,
|
||||
value,
|
||||
newLevel: level,
|
||||
category: 'notifications',
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
Divider(color: theme.dividerColor),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context).configureChat,
|
||||
style: TextStyle(
|
||||
color: theme.colorScheme.primary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
for (final entry in eventsPowerLevels.entries)
|
||||
PermissionsListTile(
|
||||
permissionKey: entry.key,
|
||||
category: 'events',
|
||||
permission: entry.value ?? 0,
|
||||
canEdit: room.canChangePowerLevel,
|
||||
onChanged: (level) => controller.editPowerLevel(
|
||||
context,
|
||||
entry.key,
|
||||
entry.value ?? 0,
|
||||
newLevel: level,
|
||||
category: 'events',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
130
lib/pages/chat_permissions_settings/permission_list_tile.dart
Normal file
130
lib/pages/chat_permissions_settings/permission_list_tile.dart
Normal file
@@ -0,0 +1,130 @@
|
||||
// SPDX-FileCopyrightText: 2019-Present Christian Kußowski
|
||||
// SPDX-FileCopyrightText: 2019-Present Contributors to FluffyChat
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import 'package:tatchat/config/app_config.dart';
|
||||
import 'package:tatchat/l10n/l10n.dart';
|
||||
import 'package:tatchat/utils/matrix_live_kit_calls/matrix_live_kit_call_member.dart';
|
||||
import 'package:material_ui/material_ui.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
class PermissionsListTile extends StatelessWidget {
|
||||
final String permissionKey;
|
||||
final int permission;
|
||||
final String? category;
|
||||
final void Function(int? level)? onChanged;
|
||||
final bool canEdit;
|
||||
|
||||
const PermissionsListTile({
|
||||
super.key,
|
||||
required this.permissionKey,
|
||||
required this.permission,
|
||||
this.category,
|
||||
required this.onChanged,
|
||||
required this.canEdit,
|
||||
});
|
||||
|
||||
String getLocalizedPowerLevelString(BuildContext context) {
|
||||
if (category == null) {
|
||||
switch (permissionKey) {
|
||||
case 'users_default':
|
||||
return L10n.of(context).defaultPermissionLevel;
|
||||
case 'events_default':
|
||||
return L10n.of(context).sendMessages;
|
||||
case 'state_default':
|
||||
return L10n.of(context).changeGeneralChatSettings;
|
||||
case 'ban':
|
||||
return L10n.of(context).banFromChat;
|
||||
case 'kick':
|
||||
return L10n.of(context).kickFromChat;
|
||||
case 'redact':
|
||||
return L10n.of(context).deleteMessage;
|
||||
case 'invite':
|
||||
return L10n.of(context).inviteOtherUsers;
|
||||
}
|
||||
} else if (category == 'notifications') {
|
||||
switch (permissionKey) {
|
||||
case 'rooms':
|
||||
return L10n.of(context).sendRoomNotifications;
|
||||
}
|
||||
} else if (category == 'events') {
|
||||
switch (permissionKey) {
|
||||
case EventTypes.RoomName:
|
||||
return L10n.of(context).changeTheNameOfTheGroup;
|
||||
case EventTypes.RoomTopic:
|
||||
return L10n.of(context).changeTheDescriptionOfTheGroup;
|
||||
case EventTypes.RoomPowerLevels:
|
||||
return L10n.of(context).changeTheChatPermissions;
|
||||
case EventTypes.HistoryVisibility:
|
||||
return L10n.of(context).changeTheVisibilityOfChatHistory;
|
||||
case EventTypes.RoomCanonicalAlias:
|
||||
return L10n.of(context).changeTheCanonicalRoomAlias;
|
||||
case EventTypes.RoomAvatar:
|
||||
return L10n.of(context).editRoomAvatar;
|
||||
case EventTypes.RoomTombstone:
|
||||
return L10n.of(context).replaceRoomWithNewerVersion;
|
||||
case EventTypes.Encryption:
|
||||
return L10n.of(context).enableEncryption;
|
||||
case 'm.room.server_acl':
|
||||
return L10n.of(context).editBlockedServers;
|
||||
case MatrixRtcCallMember.eventType:
|
||||
return 'Create or join a group call';
|
||||
}
|
||||
}
|
||||
return permissionKey;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
final color = permission >= 100
|
||||
? Colors.orangeAccent
|
||||
: permission >= 50
|
||||
? Colors.blueAccent
|
||||
: Colors.greenAccent;
|
||||
return ListTile(
|
||||
title: Text(
|
||||
getLocalizedPowerLevelString(context),
|
||||
style: theme.textTheme.titleSmall,
|
||||
),
|
||||
trailing: Material(
|
||||
color: color.withAlpha(32),
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2),
|
||||
child: DropdownButton<int>(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2),
|
||||
underline: const SizedBox.shrink(),
|
||||
onChanged: canEdit ? onChanged : null,
|
||||
value: permission,
|
||||
items: [
|
||||
DropdownMenuItem(
|
||||
value: permission < 50 ? permission : 0,
|
||||
child: Text(
|
||||
L10n.of(context).userLevel(permission < 50 ? permission : 0),
|
||||
),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: permission < 100 && permission >= 50 ? permission : 50,
|
||||
child: Text(
|
||||
L10n.of(context).moderatorLevel(
|
||||
permission < 100 && permission >= 50 ? permission : 50,
|
||||
),
|
||||
),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: permission >= 100 ? permission : 100,
|
||||
child: Text(
|
||||
L10n.of(
|
||||
context,
|
||||
).adminLevel(permission >= 100 ? permission : 100),
|
||||
),
|
||||
),
|
||||
DropdownMenuItem(value: null, child: Text(L10n.of(context).custom)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user