135 lines
3.8 KiB
Dart
135 lines
3.8 KiB
Dart
// SPDX-FileCopyrightText: 2019-Present Christian Kußowski
|
|
// SPDX-FileCopyrightText: 2019-Present Contributors to FluffyChat
|
|
//
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:device_info_plus/device_info_plus.dart';
|
|
import 'package:tatchat/l10n/l10n.dart';
|
|
import 'package:tatchat/pages/new_private_chat/new_private_chat_view.dart';
|
|
import 'package:tatchat/pages/new_private_chat/qr_scanner_modal.dart';
|
|
import 'package:tatchat/utils/adaptive_bottom_sheet.dart';
|
|
import 'package:tatchat/utils/tatu_share.dart';
|
|
import 'package:tatchat/utils/platform_infos.dart';
|
|
import 'package:tatchat/utils/url_launcher.dart';
|
|
import 'package:tatchat/widgets/matrix.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:material_ui/material_ui.dart';
|
|
import 'package:matrix/matrix.dart';
|
|
|
|
import '../../widgets/adaptive_dialogs/user_dialog.dart';
|
|
|
|
class NewPrivateChat extends StatefulWidget {
|
|
final String? deeplink;
|
|
const NewPrivateChat({super.key, required this.deeplink});
|
|
|
|
@override
|
|
NewPrivateChatController createState() => NewPrivateChatController();
|
|
}
|
|
|
|
class NewPrivateChatController extends State<NewPrivateChat> {
|
|
final TextEditingController controller = TextEditingController();
|
|
final FocusNode textFieldFocus = FocusNode();
|
|
|
|
Future<List<Profile>>? searchResponse;
|
|
|
|
Timer? _searchCoolDown;
|
|
|
|
static const Duration _coolDown = Duration(milliseconds: 500);
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
|
|
final deeplink = widget.deeplink;
|
|
if (deeplink != null) {
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
UrlLauncher(context, deeplink).openMatrixToUrl();
|
|
});
|
|
}
|
|
}
|
|
|
|
Future<void> searchUsers([String? input]) async {
|
|
final searchTerm = input ?? controller.text;
|
|
if (searchTerm.isEmpty) {
|
|
_searchCoolDown?.cancel();
|
|
setState(() {
|
|
searchResponse = _searchCoolDown = null;
|
|
});
|
|
return;
|
|
}
|
|
|
|
_searchCoolDown?.cancel();
|
|
_searchCoolDown = Timer(_coolDown, () {
|
|
setState(() {
|
|
searchResponse = _searchUser(searchTerm);
|
|
});
|
|
});
|
|
}
|
|
|
|
Future<List<Profile>> _searchUser(String searchTerm) async {
|
|
final result = await Matrix.of(
|
|
context,
|
|
).client.searchUserDirectory(searchTerm);
|
|
final profiles = result.results;
|
|
|
|
if (searchTerm.isValidMatrixIdStrict() &&
|
|
searchTerm.sigil == '@' &&
|
|
!profiles.any((profile) => profile.userId == searchTerm)) {
|
|
profiles.add(Profile(userId: searchTerm));
|
|
}
|
|
|
|
return profiles;
|
|
}
|
|
|
|
void inviteAction() => TatuShare.shareInviteLink(context);
|
|
|
|
Future<void> openScannerAction() async {
|
|
final l10n = L10n.of(context);
|
|
final scaffoldMessenger = ScaffoldMessenger.of(context);
|
|
if (PlatformInfos.isAndroid) {
|
|
final info = await DeviceInfoPlugin().androidInfo;
|
|
if (!mounted) return;
|
|
if (info.version.sdkInt < 21) {
|
|
scaffoldMessenger.showSnackBar(
|
|
SnackBar(content: Text(l10n.unsupportedAndroidVersionLong)),
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
if (!mounted) return;
|
|
await showAdaptiveBottomSheet(
|
|
context: context,
|
|
builder: (_) => QrScannerModal(
|
|
onScan: (link) => UrlLauncher(context, link).openMatrixToUrl(),
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> copyUserId() async {
|
|
final scaffoldMessenger = ScaffoldMessenger.of(context);
|
|
final l10n = L10n.of(context);
|
|
await Clipboard.setData(
|
|
ClipboardData(text: Matrix.of(context).client.userID!),
|
|
);
|
|
if (!mounted) return;
|
|
scaffoldMessenger.showSnackBar(
|
|
SnackBar(content: Text(l10n.copiedToClipboard)),
|
|
);
|
|
}
|
|
|
|
void openUserModal(Profile profile) =>
|
|
UserDialog.show(context: context, profile: profile);
|
|
|
|
@override
|
|
void dispose() {
|
|
controller.dispose();
|
|
textFieldFocus.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) => NewPrivateChatView(this);
|
|
}
|