lemmur-app-android/lib/pages/create_post/create_post_community_picke...

115 lines
4.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:lemmy_api_client/v3.dart';
import 'package:wc_form_validators/wc_form_validators.dart';
import '../../l10n/l10n.dart';
import '../../util/async_store_listener.dart';
import '../../util/extensions/api.dart';
import '../../util/extensions/context.dart';
import '../../util/observer_consumers.dart';
import '../../widgets/avatar.dart';
import 'create_post_store.dart';
class CreatePostCommunityPicker extends HookWidget {
const CreatePostCommunityPicker({super.key});
@override
Widget build(BuildContext context) {
final store = context.read<CreatePostStore>();
final controller = useTextEditingController(
text: store.selectedCommunity != null
? _communityString(store.selectedCommunity!)
: '',
);
return AsyncStoreListener(
asyncStore: context.read<CreatePostStore>().searchCommunitiesState,
child: Focus(
onFocusChange: (hasFocus) {
if (!hasFocus && store.selectedCommunity == null) {
controller.text = '';
}
},
child: ObserverBuilder<CreatePostStore>(builder: (context, store) {
return TypeAheadFormField<CommunityView>(
textFieldConfiguration: TextFieldConfiguration(
controller: controller,
enabled: !store.isEdit,
decoration: InputDecoration(
hintText: L10n.of(context).community,
contentPadding: const EdgeInsets.symmetric(
vertical: 16,
horizontal: 20,
),
suffixIcon:
store.selectedCommunity == null && controller.text.isEmpty
? const Icon(Icons.arrow_drop_down)
: IconButton(
onPressed: () {
store.selectedCommunity = null;
controller.clear();
},
icon: const Icon(Icons.close),
),
),
onChanged: (_) => store.selectedCommunity = null,
),
validator: Validators.required(L10n.of(context).required_field),
suggestionsCallback: (pattern) async {
final communities = await store.searchCommunities(
pattern,
context.defaultJwt(store.instanceHost),
);
return communities ?? [];
},
itemBuilder: (context, community) {
return ListTile(
leading: Avatar(
url: community.community.icon,
radius: 20,
),
title: Text(_communityString(community)),
);
},
onSuggestionSelected: (community) {
store.selectedCommunity = community;
controller.text = _communityString(community);
},
noItemsFoundBuilder: (context) => SizedBox(
width: double.infinity,
child: Padding(
padding: const EdgeInsets.all(8),
child: Text(
L10n.of(context).no_communities_found,
textAlign: TextAlign.center,
),
),
),
loadingBuilder: (context) => Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Padding(
padding: EdgeInsets.all(8),
child: CircularProgressIndicator.adaptive(),
),
],
),
debounceDuration: const Duration(milliseconds: 400),
);
}),
),
);
}
}
String _communityString(CommunityView communityView) {
if (communityView.community.local) {
return communityView.community.title;
} else {
return '${communityView.community.originInstanceHost}/${communityView.community.title}';
}
}