Username hint

This commit is contained in:
LittleSheep 2024-08-06 18:34:46 +08:00
parent c48bd3e758
commit dea743a307
2 changed files with 41 additions and 8 deletions

View File

@ -11,6 +11,7 @@ import 'package:solian/platform.dart';
import 'package:solian/providers/attachment_uploader.dart'; import 'package:solian/providers/attachment_uploader.dart';
import 'package:solian/providers/auth.dart'; import 'package:solian/providers/auth.dart';
import 'package:solian/providers/stickers.dart'; import 'package:solian/providers/stickers.dart';
import 'package:solian/widgets/account/account_avatar.dart';
import 'package:solian/widgets/attachments/attachment_editor.dart'; import 'package:solian/widgets/attachments/attachment_editor.dart';
import 'package:solian/widgets/chat/chat_event.dart'; import 'package:solian/widgets/chat/chat_event.dart';
import 'package:badges/badges.dart' as badges; import 'package:badges/badges.dart' as badges;
@ -55,8 +56,8 @@ class ChatMessageInput extends StatefulWidget {
} }
class _ChatMessageInputState extends State<ChatMessageInput> { class _ChatMessageInputState extends State<ChatMessageInput> {
TextEditingController _textController = TextEditingController(); final TextEditingController _textController = TextEditingController();
FocusNode _focusNode = FocusNode(); final FocusNode _focusNode = FocusNode();
final List<int> _attachments = List.empty(growable: true); final List<int> _attachments = List.empty(growable: true);
@ -241,6 +242,14 @@ class _ChatMessageInputState extends State<ChatMessageInput> {
); );
} }
if (suggestion.type == 'users') {
insertText = '${suggestion.content} ';
startText = replaceText.replaceFirstMapped(
RegExp(r'(?:\s|^)@([a-z0-9_+-]+)$'),
(Match m) => insertText,
);
}
if (insertText.isNotEmpty && startText.isNotEmpty) { if (insertText.isNotEmpty && startText.isNotEmpty) {
_textController.text = startText + afterText; _textController.text = startText + afterText;
_textController.selection = TextSelection( _textController.selection = TextSelection(
@ -311,13 +320,11 @@ class _ChatMessageInputState extends State<ChatMessageInput> {
controller: _textController, controller: _textController,
focusNode: _focusNode, focusNode: _focusNode,
hideOnSelect: false, hideOnSelect: false,
debounceDuration: const Duration(milliseconds: 50), debounceDuration: const Duration(milliseconds: 500),
onSelected: (value) { onSelected: (value) {
_insertSuggestion(value); _insertSuggestion(value);
}, },
itemBuilder: (context, item) { itemBuilder: (context, item) => _buildSuggestion(item),
return _buildSuggestion(item);
},
builder: (context, controller, focusNode) { builder: (context, controller, focusNode) {
return TextField( return TextField(
controller: _textController, controller: _textController,
@ -336,7 +343,7 @@ class _ChatMessageInputState extends State<ChatMessageInput> {
FocusManager.instance.primaryFocus?.unfocus(), FocusManager.instance.primaryFocus?.unfocus(),
); );
}, },
suggestionsCallback: (search) { suggestionsCallback: (search) async {
final searchText = _textController.text final searchText = _textController.text
.substring(0, _textController.selection.baseOffset); .substring(0, _textController.selection.baseOffset);
@ -370,6 +377,33 @@ class _ChatMessageInputState extends State<ChatMessageInput> {
.toList(); .toList();
} }
final userMatch = RegExp(r'(?:\s|^)@([a-z0-9_+-]+)$')
.firstMatch(searchText);
if (userMatch != null) {
final userSearch = userMatch[1]!.toLowerCase();
final AuthProvider auth = Get.find();
final client = auth.configureClient('auth');
final resp = await client.get(
'/users/search?probe=$userSearch',
);
final List<Account> result = resp.body
.map((x) => Account.fromJson(x))
.toList()
.cast<Account>();
return result
.map(
(x) => ChatMessageSuggestion(
type: 'users',
leading: AccountAvatar(content: x.avatar),
display: x.nick,
content: '@${x.name}',
),
)
.toList();
}
return null; return null;
}, },
), ),

View File

@ -503,7 +503,6 @@ class _MeasureSize extends SingleChildRenderObjectWidget {
final _OnWidgetSizeChange onChange; final _OnWidgetSizeChange onChange;
const _MeasureSize({ const _MeasureSize({
super.key,
required this.onChange, required this.onChange,
required Widget super.child, required Widget super.child,
}); });