✨ E2EE and Keypair
This commit is contained in:
@ -15,9 +15,9 @@ import 'package:uuid/uuid.dart';
|
||||
|
||||
class ChannelEditorScreen extends StatefulWidget {
|
||||
final Channel? editing;
|
||||
final String? realm;
|
||||
final String realm;
|
||||
|
||||
const ChannelEditorScreen({super.key, this.editing, this.realm});
|
||||
const ChannelEditorScreen({super.key, this.editing, this.realm = 'global'});
|
||||
|
||||
@override
|
||||
State<ChannelEditorScreen> createState() => _ChannelEditorScreenState();
|
||||
@ -28,6 +28,8 @@ class _ChannelEditorScreenState extends State<ChannelEditorScreen> {
|
||||
final _nameController = TextEditingController();
|
||||
final _descriptionController = TextEditingController();
|
||||
|
||||
bool _isEncrypted = false;
|
||||
|
||||
bool _isSubmitting = false;
|
||||
|
||||
Future<void> applyChannel(BuildContext context) async {
|
||||
@ -39,9 +41,10 @@ class _ChannelEditorScreenState extends State<ChannelEditorScreen> {
|
||||
return;
|
||||
}
|
||||
|
||||
final scope = widget.realm.isNotEmpty ? widget.realm : 'global';
|
||||
final uri = widget.editing == null
|
||||
? getRequestUri('messaging', '/api/channels/${widget.realm ?? 'global'}')
|
||||
: getRequestUri('messaging', '/api/channels/${widget.realm ?? 'global'}/${widget.editing!.id}');
|
||||
? getRequestUri('messaging', '/api/channels/$scope')
|
||||
: getRequestUri('messaging', '/api/channels/$scope/${widget.editing!.id}');
|
||||
|
||||
final req = Request(widget.editing == null ? 'POST' : 'PUT', uri);
|
||||
req.headers['Content-Type'] = 'application/json';
|
||||
@ -49,6 +52,7 @@ class _ChannelEditorScreenState extends State<ChannelEditorScreen> {
|
||||
'alias': _aliasController.value.text.toLowerCase(),
|
||||
'name': _nameController.value.text,
|
||||
'description': _descriptionController.value.text,
|
||||
'is_encrypted': _isEncrypted,
|
||||
});
|
||||
|
||||
var res = await Response.fromStream(await auth.client!.send(req));
|
||||
@ -57,7 +61,7 @@ class _ChannelEditorScreenState extends State<ChannelEditorScreen> {
|
||||
context.showErrorDialog(message);
|
||||
} else {
|
||||
if (SolianRouter.router.canPop()) {
|
||||
SolianRouter.router.pop(true);
|
||||
SolianRouter.router.pop(_aliasController.value.text.toLowerCase());
|
||||
}
|
||||
}
|
||||
setState(() => _isSubmitting = false);
|
||||
@ -79,6 +83,7 @@ class _ChannelEditorScreenState extends State<ChannelEditorScreen> {
|
||||
_aliasController.text = widget.editing!.alias;
|
||||
_nameController.text = widget.editing!.name;
|
||||
_descriptionController.text = widget.editing!.description;
|
||||
_isEncrypted = widget.editing!.isEncrypted;
|
||||
}
|
||||
|
||||
super.initState();
|
||||
@ -177,6 +182,15 @@ class _ChannelEditorScreenState extends State<ChannelEditorScreen> {
|
||||
),
|
||||
),
|
||||
),
|
||||
const Divider(thickness: 0.3),
|
||||
CheckboxListTile(
|
||||
title: Text(AppLocalizations.of(context)!.chatChannelEncryptedLabel),
|
||||
value: _isEncrypted,
|
||||
onChanged: (widget.editing?.isEncrypted ?? false) ? null : (newValue) {
|
||||
setState(() => _isEncrypted = newValue ?? false);
|
||||
},
|
||||
controlAffinity: ListTileControlAffinity.leading,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -255,6 +255,7 @@ class _ChatWidgetState extends State<ChatWidget> {
|
||||
channel: widget.alias,
|
||||
editing: _editingItem,
|
||||
replying: _replyingItem,
|
||||
isEncrypted: _chat.focusChannel?.isEncrypted ?? false,
|
||||
onReset: () => setState(() {
|
||||
_editingItem = null;
|
||||
_replyingItem = null;
|
||||
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:solian/models/channel.dart';
|
||||
import 'package:solian/providers/auth.dart';
|
||||
import 'package:solian/providers/chat.dart';
|
||||
import 'package:solian/router.dart';
|
||||
import 'package:solian/widgets/chat/channel_deletion.dart';
|
||||
import 'package:solian/widgets/scaffold.dart';
|
||||
@ -23,11 +24,12 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
|
||||
void promptLeaveChannel() async {
|
||||
final did = await showDialog(
|
||||
context: context,
|
||||
builder: (context) => ChannelDeletion(
|
||||
channel: widget.channel,
|
||||
realm: widget.realm,
|
||||
isOwned: _isOwned,
|
||||
),
|
||||
builder: (context) =>
|
||||
ChannelDeletion(
|
||||
channel: widget.channel,
|
||||
realm: widget.realm,
|
||||
isOwned: _isOwned,
|
||||
),
|
||||
);
|
||||
if (did == true && SolianRouter.router.canPop()) {
|
||||
SolianRouter.router.pop('disposed');
|
||||
@ -50,14 +52,23 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final auth = context.read<AuthProvider>();
|
||||
final chat = context.read<ChatProvider>();
|
||||
|
||||
final authorizedItems = [
|
||||
ListTile(
|
||||
leading: const Icon(Icons.settings),
|
||||
title: Text(AppLocalizations.of(context)!.settings),
|
||||
onTap: () async {
|
||||
SolianRouter.router.pushNamed('chat.channel.editor', extra: widget.channel).then((did) {
|
||||
if (did == true) {
|
||||
if (SolianRouter.router.canPop()) SolianRouter.router.pop('refresh');
|
||||
SolianRouter.router
|
||||
.pushNamed(
|
||||
'chat.channel.editor',
|
||||
extra: widget.channel,
|
||||
queryParameters: widget.realm != 'global' ? {'realm': widget.realm} : {},
|
||||
)
|
||||
.then((resp) {
|
||||
if (resp != null) {
|
||||
chat.fetchChannel(context, auth, resp as String, widget.realm);
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -81,8 +92,14 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Text(widget.channel.name, style: Theme.of(context).textTheme.bodyLarge),
|
||||
Text(widget.channel.description, style: Theme.of(context).textTheme.bodySmall),
|
||||
Text(widget.channel.name, style: Theme
|
||||
.of(context)
|
||||
.textTheme
|
||||
.bodyLarge),
|
||||
Text(widget.channel.description, style: Theme
|
||||
.of(context)
|
||||
.textTheme
|
||||
.bodySmall),
|
||||
]),
|
||||
)
|
||||
],
|
||||
|
@ -124,11 +124,10 @@ class _ChatListWidgetState extends State<ChatListWidget> {
|
||||
title: Text(element.name),
|
||||
subtitle: Text(element.description),
|
||||
onTap: () async {
|
||||
String? result;
|
||||
if (['chat.channel', 'realms.chat.channel'].contains(SolianRouter.currentRoute.name)) {
|
||||
chat.fetchChannel(context, auth, element.alias, widget.realm!);
|
||||
} else {
|
||||
result = await SolianRouter.router.pushNamed(
|
||||
SolianRouter.router.pushNamed(
|
||||
widget.realm == null ? 'chat.channel' : 'realms.chat.channel',
|
||||
pathParameters: {
|
||||
'channel': element.alias,
|
||||
@ -136,10 +135,6 @@ class _ChatListWidgetState extends State<ChatListWidget> {
|
||||
},
|
||||
);
|
||||
}
|
||||
switch (result) {
|
||||
case 'refresh':
|
||||
fetchChannels();
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
|
Reference in New Issue
Block a user