add multi_trigger_autocomplete_plus

This commit is contained in:
DenserMeerkat
2025-02-15 20:54:01 +05:30
parent 21c65615e9
commit 2eedd1b41a
35 changed files with 3106 additions and 69 deletions

View File

@@ -0,0 +1,71 @@
import 'package:example/src/data.dart';
import 'package:flutter/material.dart';
import 'package:example/src/models.dart';
class EmojiAutocompleteOptions extends StatelessWidget {
const EmojiAutocompleteOptions({
Key? key,
required this.query,
required this.onEmojiTap,
}) : super(key: key);
final String query;
final ValueSetter<Emoji> onEmojiTap;
@override
Widget build(BuildContext context) {
final emojis = kEmojis.where((it) {
final normalizedOption = it.shortName.toLowerCase();
final normalizedQuery = query.toLowerCase();
return normalizedOption.contains(normalizedQuery);
});
if (emojis.isEmpty) return const SizedBox.shrink();
return Card(
margin: const EdgeInsets.all(8),
elevation: 2,
// color: _streamChatTheme.colorTheme.barsBg,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
clipBehavior: Clip.hardEdge,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
color: const Color(0xFFF7F7F8),
child: ListTile(
dense: true,
horizontalTitleGap: 0,
title: Text("Emoji's matching '$query'"),
),
),
const Divider(height: 0),
LimitedBox(
maxHeight: MediaQuery.of(context).size.height * 0.3,
child: ListView.separated(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: emojis.length,
separatorBuilder: (_, __) => const Divider(height: 0),
itemBuilder: (context, i) {
final emoji = emojis.elementAt(i);
return ListTile(
dense: true,
leading: Text(
emoji.char,
style: const TextStyle(fontSize: 24),
),
title: Text(emoji.shortName),
onTap: () => onEmojiTap(emoji),
);
},
),
),
],
),
);
}
}

View File

@@ -0,0 +1,78 @@
import 'package:example/src/data.dart';
import 'package:flutter/material.dart';
import 'package:example/src/models.dart';
class HashtagAutocompleteOptions extends StatelessWidget {
const HashtagAutocompleteOptions({
Key? key,
required this.query,
required this.onHashtagTap,
}) : super(key: key);
final String query;
final ValueSetter<Hashtag> onHashtagTap;
@override
Widget build(BuildContext context) {
final hashtags = kHashtags.where((it) {
final normalizedOption = it.name.toLowerCase();
final normalizedQuery = query.toLowerCase();
return normalizedOption.contains(normalizedQuery);
});
if (hashtags.isEmpty) return const SizedBox.shrink();
return Card(
margin: const EdgeInsets.all(8),
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
clipBehavior: Clip.hardEdge,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
color: const Color(0xFFE9EAF4),
child: ListTile(
dense: true,
horizontalTitleGap: 0,
title: Text("Hashtags matching '$query'"),
),
),
const Divider(height: 0),
LimitedBox(
maxHeight: MediaQuery.of(context).size.height * 0.3,
child: ListView.separated(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: hashtags.length,
separatorBuilder: (_, __) => const Divider(height: 0),
itemBuilder: (context, i) {
final hashtag = hashtags.elementAt(i);
return ListTile(
dense: true,
leading: CircleAvatar(
backgroundColor: const Color(0xFFF7F7F8),
backgroundImage: NetworkImage(
hashtag.image,
scale: 0.5,
),
),
title: Text('#${hashtag.name}'),
subtitle: Text(
hashtag.description,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
onTap: () => onHashtagTap(hashtag),
);
},
),
),
],
),
);
}
}

View File

@@ -0,0 +1,71 @@
import 'package:example/src/data.dart';
import 'package:flutter/material.dart';
import 'package:example/src/models.dart';
class MentionAutocompleteOptions extends StatelessWidget {
const MentionAutocompleteOptions({
Key? key,
required this.query,
required this.onMentionUserTap,
}) : super(key: key);
final String query;
final ValueSetter<User> onMentionUserTap;
@override
Widget build(BuildContext context) {
final users = kUsers.where((it) {
final normalizedId = it.id.toLowerCase();
final normalizedName = it.name.toLowerCase();
final normalizedQuery = query.toLowerCase();
return normalizedId.contains(normalizedQuery) ||
normalizedName.contains(normalizedQuery);
});
if (users.isEmpty) return const SizedBox.shrink();
return Card(
margin: const EdgeInsets.all(8),
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
clipBehavior: Clip.hardEdge,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
color: const Color(0xFFF7F7F8),
child: ListTile(
dense: true,
horizontalTitleGap: 0,
title: Text("Users matching '$query'"),
),
),
LimitedBox(
maxHeight: MediaQuery.of(context).size.height * 0.3,
child: ListView.separated(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: users.length,
separatorBuilder: (_, __) => const Divider(height: 0),
itemBuilder: (context, i) {
final user = users.elementAt(i);
return ListTile(
dense: true,
leading: CircleAvatar(
backgroundImage: NetworkImage(user.avatar),
),
title: Text(user.name),
subtitle: Text('@${user.id}'),
onTap: () => onMentionUserTap(user),
);
},
),
),
],
),
);
}
}

View File

@@ -0,0 +1,3 @@
export 'emoji_autocomplete_options.dart';
export 'hashtag_autocomplete_options.dart';
export 'mention_autocomplete_options.dart';