jld3103
2 years ago
4 changed files with 130 additions and 1 deletions
@ -0,0 +1,101 @@ |
|||||||
|
import 'package:flutter/material.dart'; |
||||||
|
import 'package:neon/src/blocs/accounts.dart'; |
||||||
|
import 'package:neon/src/models/account.dart'; |
||||||
|
import 'package:neon/src/widgets/group_avatar.dart'; |
||||||
|
import 'package:neon/src/widgets/user_avatar.dart'; |
||||||
|
import 'package:nextcloud/core.dart' as core; |
||||||
|
import 'package:provider/provider.dart'; |
||||||
|
|
||||||
|
class NeonAutocomplete extends StatelessWidget { |
||||||
|
const NeonAutocomplete({ |
||||||
|
required this.account, |
||||||
|
required this.itemType, |
||||||
|
required this.itemId, |
||||||
|
required this.shareTypes, |
||||||
|
required this.onSelected, |
||||||
|
this.sorter, |
||||||
|
this.limit = 10, |
||||||
|
this.validator, |
||||||
|
this.decoration, |
||||||
|
this.onFieldSubmitted, |
||||||
|
super.key, |
||||||
|
}); |
||||||
|
|
||||||
|
final Account account; |
||||||
|
|
||||||
|
final String itemType; |
||||||
|
final String itemId; |
||||||
|
final List<int> shareTypes; |
||||||
|
final void Function(core.AutocompleteResult entry) onSelected; |
||||||
|
final String? sorter; |
||||||
|
final int limit; |
||||||
|
final FormFieldValidator<String>? validator; |
||||||
|
final InputDecoration? decoration; |
||||||
|
final ValueChanged<String>? onFieldSubmitted; |
||||||
|
|
||||||
|
@override |
||||||
|
Widget build(final BuildContext context) => Autocomplete<core.AutocompleteResult>( |
||||||
|
fieldViewBuilder: ( |
||||||
|
final context, |
||||||
|
final controller, |
||||||
|
final focusNode, |
||||||
|
final onFieldSubmitted, |
||||||
|
) => |
||||||
|
TextFormField( |
||||||
|
controller: controller, |
||||||
|
focusNode: focusNode, |
||||||
|
validator: validator, |
||||||
|
decoration: decoration, |
||||||
|
onFieldSubmitted: (final value) { |
||||||
|
onFieldSubmitted(); |
||||||
|
this.onFieldSubmitted?.call(value); |
||||||
|
}, |
||||||
|
), |
||||||
|
optionsBuilder: (final text) async { |
||||||
|
final result = await account.client.core.autoComplete.$get( |
||||||
|
search: text.text, |
||||||
|
itemType: itemType, |
||||||
|
itemId: itemId, |
||||||
|
shareTypes: shareTypes, |
||||||
|
); |
||||||
|
return result.body.ocs.data; |
||||||
|
}, |
||||||
|
displayStringForOption: (final option) => option.id, |
||||||
|
optionsViewBuilder: (final context, final onSelected, final options) => Align( |
||||||
|
alignment: Alignment.topLeft, |
||||||
|
child: Material( |
||||||
|
elevation: 4, |
||||||
|
child: ConstrainedBox( |
||||||
|
constraints: const BoxConstraints(maxHeight: 200), |
||||||
|
child: ListView.builder( |
||||||
|
padding: EdgeInsets.zero, |
||||||
|
shrinkWrap: true, |
||||||
|
itemCount: options.length, |
||||||
|
itemBuilder: (final context, final index) { |
||||||
|
final option = options.elementAt(index); |
||||||
|
Widget? icon; |
||||||
|
switch (option.source) { |
||||||
|
case 'users': |
||||||
|
icon = NeonUserAvatar( |
||||||
|
username: option.id, |
||||||
|
account: Provider.of<AccountsBloc>(context, listen: false).activeAccount.value!, |
||||||
|
); |
||||||
|
case 'groups': |
||||||
|
icon = const NeonGroupAvatar(); |
||||||
|
} |
||||||
|
return ListTile( |
||||||
|
title: Text(option.label), |
||||||
|
subtitle: Text(option.id), |
||||||
|
leading: icon, |
||||||
|
onTap: () { |
||||||
|
onSelected(option); |
||||||
|
}, |
||||||
|
); |
||||||
|
}, |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
onSelected: onSelected, |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
import 'package:flutter/material.dart'; |
||||||
|
import 'package:neon/src/theme/sizes.dart'; |
||||||
|
|
||||||
|
class NeonGroupAvatar extends StatelessWidget { |
||||||
|
const NeonGroupAvatar({ |
||||||
|
this.icon = Icons.group, |
||||||
|
this.backgroundColor, |
||||||
|
this.foregroundColor, |
||||||
|
super.key, |
||||||
|
}); |
||||||
|
|
||||||
|
final IconData icon; |
||||||
|
final Color? backgroundColor; |
||||||
|
final Color? foregroundColor; |
||||||
|
|
||||||
|
@override |
||||||
|
Widget build(final BuildContext context) => CircleAvatar( |
||||||
|
radius: smallIconSize, |
||||||
|
backgroundColor: backgroundColor, |
||||||
|
child: Icon( |
||||||
|
icon, |
||||||
|
color: foregroundColor, |
||||||
|
size: smallIconSize, |
||||||
|
), |
||||||
|
); |
||||||
|
} |
Loading…
Reference in new issue