import 'package:flutter/material.dart'; import 'package:cross_file/cross_file.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/matrix.dart'; abstract class ShareItem {} class TextShareItem extends ShareItem { final String value; TextShareItem(this.value); } class ContentShareItem extends ShareItem { final Map value; ContentShareItem(this.value); } class FileShareItem extends ShareItem { final XFile value; FileShareItem(this.value); } class ShareScaffoldDialog extends StatefulWidget { final List items; const ShareScaffoldDialog({required this.items, super.key}); @override State createState() => _ShareScaffoldDialogState(); } class _ShareScaffoldDialogState extends State { final TextEditingController _filterController = TextEditingController(); String? selectedRoomId; void _toggleRoom(String roomId) { setState(() { selectedRoomId = roomId; }); } void _forwardAction() async { final roomId = selectedRoomId; if (roomId == null) { throw Exception( 'Started forward action before room was selected. This should never happen.', ); } while (context.canPop()) { context.pop(); } context.go('/rooms/$roomId', extra: widget.items); } @override Widget build(BuildContext context) { final theme = Theme.of(context); final rooms = Matrix.of(context) .client .rooms .where( (room) => room.canSendDefaultMessages && !room.isSpace && room.membership == Membership.join, ) .toList(); final filter = _filterController.text.trim().toLowerCase(); return Scaffold( appBar: AppBar( leading: Center(child: CloseButton(onPressed: context.pop)), title: Text(L10n.of(context).share), ), body: CustomScrollView( slivers: [ SliverAppBar( floating: true, toolbarHeight: 72, scrolledUnderElevation: 0, backgroundColor: Colors.transparent, automaticallyImplyLeading: false, title: TextField( controller: _filterController, onChanged: (_) => setState(() {}), textInputAction: TextInputAction.search, decoration: InputDecoration( filled: true, fillColor: theme.colorScheme.secondaryContainer, border: OutlineInputBorder( borderSide: BorderSide.none, borderRadius: BorderRadius.circular(99), ), contentPadding: EdgeInsets.zero, hintText: L10n.of(context).search, hintStyle: TextStyle( color: theme.colorScheme.onPrimaryContainer, fontWeight: FontWeight.normal, ), floatingLabelBehavior: FloatingLabelBehavior.never, prefixIcon: IconButton( onPressed: () {}, icon: Icon( Icons.search_outlined, color: theme.colorScheme.onPrimaryContainer, ), ), ), ), ), SliverList.builder( itemCount: rooms.length, itemBuilder: (context, i) { final room = rooms[i]; final displayname = room.getLocalizedDisplayname( MatrixLocals(L10n.of(context)), ); final value = selectedRoomId == room.id; final filterOut = !displayname.toLowerCase().contains(filter); if (!value && filterOut) { return const SizedBox.shrink(); } return Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), child: Opacity( opacity: filterOut ? 0.5 : 1, child: RadioListTile.adaptive( controlAffinity: ListTileControlAffinity.trailing, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppConfig.borderRadius), ), secondary: Avatar( mxContent: room.avatar, name: displayname, size: Avatar.defaultSize * 0.75, ), title: Text(displayname), groupValue: selectedRoomId, value: room.id, onChanged: (_) => _toggleRoom(room.id), ), ), ); }, ), ], ), bottomNavigationBar: AnimatedSize( duration: FluffyThemes.animationDuration, curve: FluffyThemes.animationCurve, child: selectedRoomId == null ? const SizedBox.shrink() : Material( elevation: 8, shadowColor: theme.appBarTheme.shadowColor, child: Padding( padding: const EdgeInsets.all(16.0), child: ElevatedButton( onPressed: _forwardAction, child: Text(L10n.of(context).forward), ), ), ), ), ); } }