You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			179 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			179 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Dart
		
	
import 'package:flutter/material.dart';
 | 
						|
 | 
						|
import 'package:cross_file/cross_file.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/l10n/l10n.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<String, Object?> value;
 | 
						|
  ContentShareItem(this.value);
 | 
						|
}
 | 
						|
 | 
						|
class FileShareItem extends ShareItem {
 | 
						|
  final XFile value;
 | 
						|
  FileShareItem(this.value);
 | 
						|
}
 | 
						|
 | 
						|
class ShareScaffoldDialog extends StatefulWidget {
 | 
						|
  final List<ShareItem> items;
 | 
						|
 | 
						|
  const ShareScaffoldDialog({required this.items, super.key});
 | 
						|
 | 
						|
  @override
 | 
						|
  State<ShareScaffoldDialog> createState() => _ShareScaffoldDialogState();
 | 
						|
}
 | 
						|
 | 
						|
class _ShareScaffoldDialogState extends State<ShareScaffoldDialog> {
 | 
						|
  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: CheckboxListTile.adaptive(
 | 
						|
                    checkboxShape: RoundedRectangleBorder(
 | 
						|
                      borderRadius: BorderRadius.circular(90),
 | 
						|
                    ),
 | 
						|
                    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),
 | 
						|
                    value: selectedRoomId == 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),
 | 
						|
                  ),
 | 
						|
                ),
 | 
						|
              ),
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 |