mirror of
https://github.com/JGeek00/adguard-home-manager.git
synced 2025-04-24 15:56:05 +00:00
New tab list access clients
This commit is contained in:
parent
6ebde52a7f
commit
4e65f80baf
3 changed files with 170 additions and 163 deletions
|
@ -1,10 +1,10 @@
|
||||||
import 'package:adguard_home_manager/constants/enums.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
import 'package:adguard_home_manager/screens/settings/access_settings/clients_list.dart';
|
import 'package:adguard_home_manager/screens/settings/access_settings/clients_list.dart';
|
||||||
|
|
||||||
|
import 'package:adguard_home_manager/constants/enums.dart';
|
||||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||||
|
@ -72,7 +72,7 @@ class _AccessSettingsWidgetState extends State<AccessSettingsWidget> with Ticker
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final serversProvider = Provider.of<ServersProvider>(context);
|
final serversProvider = Provider.of<ServersProvider>(context);
|
||||||
|
print(serversProvider.clients.data!.clientsAllowedBlocked!.blockedHosts.length);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: DefaultTabController(
|
body: DefaultTabController(
|
||||||
length: 3,
|
length: 3,
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
// ignore_for_file: use_build_context_synchronously
|
// ignore_for_file: use_build_context_synchronously
|
||||||
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:adguard_home_manager/constants/enums.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
@ -10,11 +7,13 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
import 'package:adguard_home_manager/screens/settings/access_settings/add_client_modal.dart';
|
import 'package:adguard_home_manager/screens/settings/access_settings/add_client_modal.dart';
|
||||||
import 'package:adguard_home_manager/screens/clients/remove_client_modal.dart';
|
import 'package:adguard_home_manager/screens/clients/remove_client_modal.dart';
|
||||||
|
import 'package:adguard_home_manager/widgets/tab_content_list.dart';
|
||||||
|
|
||||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||||
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
import 'package:adguard_home_manager/providers/app_config_provider.dart';
|
||||||
import 'package:adguard_home_manager/models/clients_allowed_blocked.dart';
|
import 'package:adguard_home_manager/models/clients_allowed_blocked.dart';
|
||||||
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
import 'package:adguard_home_manager/providers/servers_provider.dart';
|
||||||
|
import 'package:adguard_home_manager/constants/enums.dart';
|
||||||
import 'package:adguard_home_manager/services/http_requests.dart';
|
import 'package:adguard_home_manager/services/http_requests.dart';
|
||||||
import 'package:adguard_home_manager/classes/process_modal.dart';
|
import 'package:adguard_home_manager/classes/process_modal.dart';
|
||||||
|
|
||||||
|
@ -209,167 +208,173 @@ class _ClientsListState extends State<ClientsList> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (widget.loadStatus) {
|
return CustomTabContentList(
|
||||||
case LoadStatus.loading:
|
loadingGenerator: () => SizedBox(
|
||||||
return SizedBox(
|
width: double.maxFinite,
|
||||||
width: double.maxFinite,
|
height: MediaQuery.of(context).size.height-171,
|
||||||
height: MediaQuery.of(context).size.height-171,
|
child: Column(
|
||||||
child: Column(
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
const CircularProgressIndicator(),
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
Text(
|
|
||||||
AppLocalizations.of(context)!.loadingClients,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 22,
|
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
case LoadStatus.loaded:
|
|
||||||
return Stack(
|
|
||||||
children: [
|
children: [
|
||||||
RefreshIndicator(
|
const CircularProgressIndicator(),
|
||||||
onRefresh: widget.fetchClients,
|
const SizedBox(height: 30),
|
||||||
child: Column(
|
Text(
|
||||||
mainAxisSize: MainAxisSize.max,
|
AppLocalizations.of(context)!.loadingClients,
|
||||||
children: [
|
textAlign: TextAlign.center,
|
||||||
Padding(
|
style: TextStyle(
|
||||||
padding: const EdgeInsets.all(10),
|
fontSize: 22,
|
||||||
child: Card(
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(20),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.info_rounded,
|
|
||||||
color: Theme.of(context).listTileTheme.iconColor,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 20),
|
|
||||||
Flexible(
|
|
||||||
child: Text(
|
|
||||||
description(),
|
|
||||||
style: TextStyle(
|
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (widget.data.isNotEmpty) Expanded(
|
|
||||||
child: ListView.builder(
|
|
||||||
padding: const EdgeInsets.only(top: 0),
|
|
||||||
itemCount: widget.data.length,
|
|
||||||
itemBuilder: (context, index) => ListTile(
|
|
||||||
title: Text(
|
|
||||||
widget.data[index],
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.normal,
|
|
||||||
color: Theme.of(context).colorScheme.onSurface
|
|
||||||
),
|
|
||||||
),
|
|
||||||
trailing: IconButton(
|
|
||||||
onPressed: () => {
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (context) => RemoveClientModal(
|
|
||||||
onConfirm: () => confirmRemoveItem(widget.data[index], widget.type),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
icon: const Icon(Icons.delete_rounded)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (widget.data.isEmpty) Expanded(
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
noItems(),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 24,
|
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
TextButton.icon(
|
|
||||||
onPressed: widget.fetchClients,
|
|
||||||
icon: const Icon(Icons.refresh_rounded),
|
|
||||||
label: Text(AppLocalizations.of(context)!.refresh),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
AnimatedPositioned(
|
|
||||||
duration: const Duration(milliseconds: 100),
|
|
||||||
curve: Curves.easeInOut,
|
|
||||||
bottom: isVisible ?
|
|
||||||
appConfigProvider.showingSnackbar
|
|
||||||
? 70 : (Platform.isIOS ? 40 : 20)
|
|
||||||
: -70,
|
|
||||||
right: 20,
|
|
||||||
child: FloatingActionButton(
|
|
||||||
onPressed: () {
|
|
||||||
showModalBottomSheet(
|
|
||||||
context: context,
|
|
||||||
builder: (context) => AddClientModal(
|
|
||||||
type: widget.type,
|
|
||||||
onConfirm: confirmAddItem
|
|
||||||
),
|
|
||||||
backgroundColor: Colors.transparent,
|
|
||||||
isScrollControlled: true
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: const Icon(Icons.add),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
]
|
],
|
||||||
);
|
),
|
||||||
|
),
|
||||||
case LoadStatus.error:
|
itemsCount: widget.data.isNotEmpty
|
||||||
return SizedBox(
|
? widget.data.length+1
|
||||||
width: double.maxFinite,
|
: 0,
|
||||||
height: MediaQuery.of(context).size.height-101,
|
contentWidget: (index) {
|
||||||
child: Column(
|
if (index == 0) {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
return Padding(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
padding: const EdgeInsets.all(10),
|
||||||
children: [
|
child: Card(
|
||||||
const Icon(
|
child: Padding(
|
||||||
Icons.error,
|
padding: const EdgeInsets.all(20),
|
||||||
color: Colors.red,
|
child: Row(
|
||||||
size: 50,
|
children: [
|
||||||
),
|
Icon(
|
||||||
const SizedBox(height: 30),
|
Icons.info_rounded,
|
||||||
Text(
|
color: Theme.of(context).listTileTheme.iconColor,
|
||||||
AppLocalizations.of(context)!.clientsNotLoaded,
|
),
|
||||||
textAlign: TextAlign.center,
|
const SizedBox(width: 20),
|
||||||
style: TextStyle(
|
Flexible(
|
||||||
fontSize: 22,
|
child: Text(
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
description(),
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
],
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ListTile(
|
||||||
|
title: Text(
|
||||||
|
widget.data[index-1],
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
color: Theme.of(context).colorScheme.onSurface
|
||||||
|
),
|
||||||
|
),
|
||||||
|
trailing: IconButton(
|
||||||
|
onPressed: () => {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => RemoveClientModal(
|
||||||
|
onConfirm: () => confirmRemoveItem(widget.data[index-1], widget.type),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.delete_rounded)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
noData: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(10),
|
||||||
|
child: Card(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(20),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.info_rounded,
|
||||||
|
color: Theme.of(context).listTileTheme.iconColor,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 20),
|
||||||
|
Flexible(
|
||||||
|
child: Text(
|
||||||
|
description(),
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
Expanded(
|
||||||
|
child: Column(
|
||||||
default:
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
return const SizedBox();
|
children: [
|
||||||
}
|
Text(
|
||||||
|
noItems(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 24,
|
||||||
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 30),
|
||||||
|
TextButton.icon(
|
||||||
|
onPressed: widget.fetchClients,
|
||||||
|
icon: const Icon(Icons.refresh_rounded),
|
||||||
|
label: Text(AppLocalizations.of(context)!.refresh),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
errorGenerator: () => SizedBox(
|
||||||
|
width: double.maxFinite,
|
||||||
|
height: MediaQuery.of(context).size.height-101,
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Icon(
|
||||||
|
Icons.error,
|
||||||
|
color: Colors.red,
|
||||||
|
size: 50,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 30),
|
||||||
|
Text(
|
||||||
|
AppLocalizations.of(context)!.clientsNotLoaded,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 22,
|
||||||
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
loadStatus: widget.loadStatus,
|
||||||
|
onRefresh: widget.fetchClients,
|
||||||
|
refreshIndicatorOffset: 0,
|
||||||
|
fab: FloatingActionButton(
|
||||||
|
onPressed: () {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AddClientModal(
|
||||||
|
type: widget.type,
|
||||||
|
onConfirm: confirmAddItem
|
||||||
|
),
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
isScrollControlled: true
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Icon(Icons.add),
|
||||||
|
),
|
||||||
|
fabVisible: isVisible,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -12,6 +12,7 @@ class CustomTabContentList extends StatelessWidget {
|
||||||
final Widget Function() errorGenerator;
|
final Widget Function() errorGenerator;
|
||||||
final LoadStatus loadStatus;
|
final LoadStatus loadStatus;
|
||||||
final Future<void> Function() onRefresh;
|
final Future<void> Function() onRefresh;
|
||||||
|
final double? refreshIndicatorOffset;
|
||||||
final Widget? fab;
|
final Widget? fab;
|
||||||
final bool? fabVisible;
|
final bool? fabVisible;
|
||||||
|
|
||||||
|
@ -24,6 +25,7 @@ class CustomTabContentList extends StatelessWidget {
|
||||||
required this.errorGenerator,
|
required this.errorGenerator,
|
||||||
required this.loadStatus,
|
required this.loadStatus,
|
||||||
required this.onRefresh,
|
required this.onRefresh,
|
||||||
|
this.refreshIndicatorOffset,
|
||||||
this.fab,
|
this.fab,
|
||||||
this.fabVisible
|
this.fabVisible
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
@ -65,7 +67,7 @@ class CustomTabContentList extends StatelessWidget {
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return RefreshIndicator(
|
return RefreshIndicator(
|
||||||
onRefresh: onRefresh,
|
onRefresh: onRefresh,
|
||||||
edgeOffset: 95,
|
edgeOffset: refreshIndicatorOffset ?? 95,
|
||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
slivers: <Widget>[
|
slivers: <Widget>[
|
||||||
SliverOverlapInjector(
|
SliverOverlapInjector(
|
||||||
|
|
Loading…
Add table
Reference in a new issue