veilidchat/lib/contact_invitation/views/paste_invitation_dialog.dart

149 lines
4.4 KiB
Dart
Raw Normal View History

2023-08-05 01:00:46 -04:00
import 'dart:async';
import 'package:awesome_extensions/awesome_extensions.dart';
2024-02-14 21:33:15 -05:00
import 'package:flutter/foundation.dart';
2023-08-05 01:00:46 -04:00
import 'package:flutter/material.dart';
import 'package:flutter_translate/flutter_translate.dart';
2024-01-09 20:58:27 -05:00
import 'package:veilid_support/veilid_support.dart';
2023-08-05 01:00:46 -04:00
2024-01-09 20:58:27 -05:00
import '../../theme/theme.dart';
import '../../tools/tools.dart';
2024-04-05 22:03:04 -04:00
import 'invitation_dialog.dart';
2023-08-05 01:00:46 -04:00
2024-04-05 22:03:04 -04:00
class PasteInvitationDialog extends StatefulWidget {
const PasteInvitationDialog({required this.modalContext, super.key});
2023-08-05 01:00:46 -04:00
@override
2024-04-05 22:03:04 -04:00
PasteInvitationDialogState createState() => PasteInvitationDialogState();
2023-09-23 12:56:54 -04:00
static Future<void> show(BuildContext context) async {
final modalContext = context;
await showPopControlDialog<void>(
2023-09-23 12:56:54 -04:00
context: context,
builder: (context) => StyledDialog(
title: translate('paste_invitation_dialog.title'),
child: PasteInvitationDialog(modalContext: modalContext)));
2024-02-14 21:33:15 -05:00
}
final BuildContext modalContext;
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties
.add(DiagnosticsProperty<BuildContext>('modalContext', modalContext));
2023-09-23 12:56:54 -04:00
}
2023-08-05 01:00:46 -04:00
}
2024-04-05 22:03:04 -04:00
class PasteInvitationDialogState extends State<PasteInvitationDialog> {
2023-08-05 01:00:46 -04:00
final _pasteTextController = TextEditingController();
@override
void initState() {
super.initState();
}
2023-09-27 13:34:19 -04:00
Future<void> _onPasteChanged(
String text,
Future<void> Function({
required Uint8List inviteData,
}) validateInviteData) async {
final lines = text.split('\n');
if (lines.isEmpty) {
2023-08-05 13:50:31 -04:00
return;
2023-08-05 12:38:03 -04:00
}
2023-09-27 13:34:19 -04:00
var firstline =
lines.indexWhere((element) => element.contains('BEGIN VEILIDCHAT'));
firstline += 1;
2023-08-05 13:50:31 -04:00
2023-09-27 13:34:19 -04:00
var lastline =
lines.indexWhere((element) => element.contains('END VEILIDCHAT'));
if (lastline == -1) {
lastline = lines.length;
2023-08-05 13:50:31 -04:00
}
2023-09-27 13:34:19 -04:00
if (lastline <= firstline) {
return;
2023-08-05 12:38:03 -04:00
}
final inviteDataBase64 = lines
.sublist(firstline, lastline)
.join()
.replaceAll(RegExp(r'[^A-Za-z0-9\-_]'), '');
2023-08-05 01:00:46 -04:00
var inviteData = Uint8List(0);
try {
inviteData = base64UrlNoPadDecode(inviteDataBase64);
} on Exception {
//
}
2023-09-27 13:34:19 -04:00
await validateInviteData(inviteData: inviteData);
}
2023-08-05 01:00:46 -04:00
2023-09-27 13:34:19 -04:00
void onValidationCancelled() {
_pasteTextController.clear();
}
2023-08-05 01:15:08 -04:00
2023-09-27 13:34:19 -04:00
void onValidationSuccess() {
//_pasteTextController.clear();
}
2023-09-24 22:35:54 -04:00
2023-09-27 13:34:19 -04:00
void onValidationFailed() {
_pasteTextController.clear();
}
2023-09-24 22:35:54 -04:00
2023-09-27 13:34:19 -04:00
bool inviteControlIsValid() => _pasteTextController.text.isNotEmpty;
2023-09-24 22:35:54 -04:00
2023-09-27 13:34:19 -04:00
Widget buildInviteControl(
BuildContext context,
2024-04-05 22:03:04 -04:00
InvitationDialogState dialogState,
2023-09-27 13:34:19 -04:00
Future<void> Function({required Uint8List inviteData})
validateInviteData) {
final theme = Theme.of(context);
2023-10-09 16:52:37 -04:00
final scale = theme.extension<ScaleScheme>()!;
//final textTheme = theme.textTheme;
2023-09-27 13:34:19 -04:00
//final height = MediaQuery.of(context).size.height;
2023-08-05 01:00:46 -04:00
2023-10-09 16:52:37 -04:00
final monoStyle = TextStyle(
fontFamily: 'Source Code Pro',
fontSize: 11,
2024-04-07 23:16:06 -04:00
color: scale.primaryScale.appText,
2023-10-09 16:52:37 -04:00
);
2023-09-27 13:34:19 -04:00
return Column(mainAxisSize: MainAxisSize.min, children: [
Text(
2024-04-05 22:03:04 -04:00
translate('paste_invitation_dialog.paste_invite_here'),
).paddingLTRB(0, 0, 0, 16),
2023-09-27 13:34:19 -04:00
Container(
constraints: const BoxConstraints(maxHeight: 200),
child: TextField(
enabled: !dialogState.isValidating,
onChanged: (text) async =>
_onPasteChanged(text, validateInviteData),
2023-10-09 16:52:37 -04:00
style: monoStyle,
2023-09-27 13:34:19 -04:00
keyboardType: TextInputType.multiline,
maxLines: null,
controller: _pasteTextController,
decoration: const InputDecoration(
hintText: '--- BEGIN VEILIDCHAT CONTACT INVITE ----\n'
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n'
'---- END VEILIDCHAT CONTACT INVITE -----\n',
2024-04-05 22:03:04 -04:00
//labelText: translate('paste_invitation_dialog.paste')
2023-09-27 13:34:19 -04:00
),
)).paddingLTRB(0, 0, 0, 8)
]);
2023-08-05 01:00:46 -04:00
}
@override
// ignore: prefer_expression_function_bodies
Widget build(BuildContext context) {
2024-04-05 22:03:04 -04:00
return InvitationDialog(
2024-02-14 21:33:15 -05:00
modalContext: widget.modalContext,
2023-09-27 13:34:19 -04:00
onValidationCancelled: onValidationCancelled,
onValidationSuccess: onValidationSuccess,
onValidationFailed: onValidationFailed,
inviteControlIsValid: inviteControlIsValid,
buildInviteControl: buildInviteControl);
2023-08-05 01:00:46 -04:00
}
}