kopia lustrzana https://gitlab.com/mysocialportal/relatica
				
				
				
			
		
			
				
	
	
		
			176 wiersze
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Dart
		
	
	
			
		
		
	
	
			176 wiersze
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Dart
		
	
	
import 'package:flutter/material.dart';
 | 
						|
import 'package:go_router/go_router.dart';
 | 
						|
import 'package:logging/logging.dart';
 | 
						|
import 'package:provider/provider.dart';
 | 
						|
 | 
						|
import '../controls/app_bottom_nav_bar.dart';
 | 
						|
import '../controls/current_profile_button.dart';
 | 
						|
import '../controls/image_control.dart';
 | 
						|
import '../controls/linear_status_indicator.dart';
 | 
						|
import '../controls/responsive_max_width.dart';
 | 
						|
import '../controls/standard_app_drawer.dart';
 | 
						|
import '../controls/status_and_refresh_button.dart';
 | 
						|
import '../globals.dart';
 | 
						|
import '../models/connection.dart';
 | 
						|
import '../routes.dart';
 | 
						|
import '../services/auth_service.dart';
 | 
						|
import '../services/connections_manager.dart';
 | 
						|
import '../services/network_status_service.dart';
 | 
						|
import '../utils/active_profile_selector.dart';
 | 
						|
import '../utils/snackbar_builder.dart';
 | 
						|
 | 
						|
class ContactsScreen extends StatefulWidget {
 | 
						|
  const ContactsScreen({super.key});
 | 
						|
 | 
						|
  @override
 | 
						|
  State<ContactsScreen> createState() => _ContactsScreenState();
 | 
						|
}
 | 
						|
 | 
						|
class _ContactsScreenState extends State<ContactsScreen> {
 | 
						|
  static final _logger = Logger('$ContactsScreen');
 | 
						|
  var filterText = '';
 | 
						|
  var updateBeingProcessed = false;
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) {
 | 
						|
    context.watch<AccountsService>();
 | 
						|
    final nss = getIt<NetworkStatusService>();
 | 
						|
    final manager = context
 | 
						|
        .watch<ActiveProfileSelector<ConnectionsManager>>()
 | 
						|
        .activeEntry
 | 
						|
        .value;
 | 
						|
    final allContacts = manager.getMyContacts();
 | 
						|
    final filterTextLC = filterText.toLowerCase();
 | 
						|
    final contacts = allContacts
 | 
						|
        .where((c) =>
 | 
						|
            filterText.isEmpty ||
 | 
						|
            c.name.toLowerCase().contains(filterTextLC) ||
 | 
						|
            c.handle.toLowerCase().contains(filterTextLC))
 | 
						|
        .toList();
 | 
						|
    contacts.sort((c1, c2) => c1.name.compareTo(c2.name));
 | 
						|
    _logger.finer(
 | 
						|
      () => '# Contacts: ${allContacts.length}, #filtered: ${contacts.length}',
 | 
						|
    );
 | 
						|
    late Widget body;
 | 
						|
    if (contacts.isEmpty) {
 | 
						|
      body = const SingleChildScrollView(
 | 
						|
          physics: AlwaysScrollableScrollPhysics(),
 | 
						|
          child: Center(
 | 
						|
            child: Text('No contacts'),
 | 
						|
          ));
 | 
						|
    } else {
 | 
						|
      body = ResponsiveMaxWidth(
 | 
						|
        child: ListView.separated(
 | 
						|
            physics: const AlwaysScrollableScrollPhysics(),
 | 
						|
            itemBuilder: (context, index) {
 | 
						|
              final contact = contacts[index];
 | 
						|
              return ListTile(
 | 
						|
                onTap: () {
 | 
						|
                  context.pushNamed(ScreenPaths.userProfile,
 | 
						|
                      pathParameters: {'id': contact.id});
 | 
						|
                },
 | 
						|
                leading: ImageControl(
 | 
						|
                  imageUrl: contact.avatarUrl.toString(),
 | 
						|
                  iconOverride: const Icon(Icons.person),
 | 
						|
                  width: 32.0,
 | 
						|
                ),
 | 
						|
                title: Text(
 | 
						|
                  '${contact.name} (${contact.handle})',
 | 
						|
                  softWrap: true,
 | 
						|
                ),
 | 
						|
                subtitle: Text(
 | 
						|
                  'Last Status: ${contact.lastStatus?.toIso8601String() ?? "Unknown"}',
 | 
						|
                  softWrap: true,
 | 
						|
                ),
 | 
						|
                trailing: Text(contact.status.label()),
 | 
						|
              );
 | 
						|
            },
 | 
						|
            separatorBuilder: (context, index) => const Divider(),
 | 
						|
            itemCount: contacts.length),
 | 
						|
      );
 | 
						|
    }
 | 
						|
 | 
						|
    return Scaffold(
 | 
						|
      drawer: const StandardAppDrawer(skipPopDismiss: false),
 | 
						|
      body: SafeArea(
 | 
						|
        child: RefreshIndicator(
 | 
						|
          onRefresh: () async {
 | 
						|
            await performFullUpdate(nss, manager);
 | 
						|
          },
 | 
						|
          child: Column(
 | 
						|
            children: [
 | 
						|
              Row(
 | 
						|
                children: [
 | 
						|
                  SizedBox(
 | 
						|
                      width: 50.0, child: buildCurrentProfileButton(context)!),
 | 
						|
                  Expanded(
 | 
						|
                    child: Padding(
 | 
						|
                      padding: const EdgeInsets.all(8.0),
 | 
						|
                      child: TextField(
 | 
						|
                        onChanged: (value) {
 | 
						|
                          setState(() {
 | 
						|
                            filterText = value.toLowerCase();
 | 
						|
                          });
 | 
						|
                        },
 | 
						|
                        decoration: InputDecoration(
 | 
						|
                          labelText: 'Filter By Name',
 | 
						|
                          alignLabelWithHint: true,
 | 
						|
                          border: OutlineInputBorder(
 | 
						|
                            borderSide: BorderSide(
 | 
						|
                              color: Theme.of(context).highlightColor,
 | 
						|
                            ),
 | 
						|
                            borderRadius: BorderRadius.circular(5.0),
 | 
						|
                          ),
 | 
						|
                        ),
 | 
						|
                      ),
 | 
						|
                    ),
 | 
						|
                  ),
 | 
						|
                  Padding(
 | 
						|
                    padding: const EdgeInsets.all(8.0),
 | 
						|
                    child: StatusAndRefreshButton(
 | 
						|
                        valueListenable: nss.connectionUpdateStatus,
 | 
						|
                        refreshFunction: () async {
 | 
						|
                          await performFullUpdate(nss, manager);
 | 
						|
                        }),
 | 
						|
                  )
 | 
						|
                ],
 | 
						|
              ),
 | 
						|
              Text(manager.lastUpdateStatus),
 | 
						|
              StandardLinearProgressIndicator(nss.connectionUpdateStatus),
 | 
						|
              Expanded(child: body),
 | 
						|
            ],
 | 
						|
          ),
 | 
						|
        ),
 | 
						|
      ),
 | 
						|
      bottomNavigationBar: const AppBottomNavBar(
 | 
						|
        currentButton: NavBarButtons.contacts,
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  Future<void> performFullUpdate(
 | 
						|
    NetworkStatusService nss,
 | 
						|
    ConnectionsManager manager,
 | 
						|
  ) async {
 | 
						|
    if (nss.connectionUpdateStatus.value) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (updateBeingProcessed) {
 | 
						|
      buildSnackbar(
 | 
						|
        context,
 | 
						|
        'Update already underway and cannot be requested again.',
 | 
						|
      );
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    buildSnackbar(
 | 
						|
      context,
 | 
						|
      'Beginning updating contact list which takes some time...',
 | 
						|
    );
 | 
						|
    updateBeingProcessed = true;
 | 
						|
    await manager.updateAllContacts(false);
 | 
						|
    updateBeingProcessed = false;
 | 
						|
  }
 | 
						|
}
 |