mirror of
https://github.com/JGeek00/adguard-home-manager.git
synced 2025-04-25 08:16:06 +00:00
Improvements clients view
This commit is contained in:
parent
dafff9b242
commit
769238cff9
3 changed files with 206 additions and 157 deletions
|
@ -131,7 +131,7 @@ class _ClientsWidgetState extends State<ClientsWidget> with TickerProviderStateM
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget tabBarView() {
|
Widget tabBarView(bool sliver) {
|
||||||
return TabBarView(
|
return TabBarView(
|
||||||
controller: tabController,
|
controller: tabController,
|
||||||
children: [
|
children: [
|
||||||
|
@ -149,6 +149,7 @@ class _ClientsWidgetState extends State<ClientsWidget> with TickerProviderStateM
|
||||||
)
|
)
|
||||||
)),
|
)),
|
||||||
splitView: false,
|
splitView: false,
|
||||||
|
sliver: sliver,
|
||||||
),
|
),
|
||||||
AddedList(
|
AddedList(
|
||||||
scrollController: scrollController,
|
scrollController: scrollController,
|
||||||
|
@ -169,32 +170,32 @@ class _ClientsWidgetState extends State<ClientsWidget> with TickerProviderStateM
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(Platform.isAndroid || Platform.isIOS)) {
|
if (width > 900) {
|
||||||
if (width > 900) {
|
return SplitView.material(
|
||||||
return SplitView.material(
|
hideDivider: true,
|
||||||
hideDivider: true,
|
flexWidth: const FlexWidth(mainViewFlexWidth: 1, secondaryViewFlexWidth: 2),
|
||||||
flexWidth: const FlexWidth(mainViewFlexWidth: 1, secondaryViewFlexWidth: 2),
|
placeholder: Center(
|
||||||
placeholder: Center(
|
child: Padding(
|
||||||
child: Padding(
|
padding: const EdgeInsets.all(24),
|
||||||
padding: const EdgeInsets.all(24),
|
child: Text(
|
||||||
child: Text(
|
AppLocalizations.of(context)!.selectClientLeftColumn,
|
||||||
AppLocalizations.of(context)!.selectClientLeftColumn,
|
textAlign: TextAlign.center,
|
||||||
textAlign: TextAlign.center,
|
style: TextStyle(
|
||||||
style: TextStyle(
|
fontSize: 24,
|
||||||
fontSize: 24,
|
color: Theme.of(context).colorScheme.onSurfaceVariant
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: ClientsDesktopView(
|
),
|
||||||
serversProvider: serversProvider,
|
child: ClientsDesktopView(
|
||||||
appConfigProvider: appConfigProvider,
|
serversProvider: serversProvider,
|
||||||
fetchClients: fetchClients,
|
appConfigProvider: appConfigProvider,
|
||||||
)
|
fetchClients: fetchClients,
|
||||||
);
|
)
|
||||||
}
|
);
|
||||||
else {
|
}
|
||||||
|
else {
|
||||||
|
if (!(Platform.isAndroid || Platform.isIOS)) {
|
||||||
return DefaultTabController(
|
return DefaultTabController(
|
||||||
length: 2,
|
length: 2,
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
|
@ -217,87 +218,87 @@ class _ClientsWidgetState extends State<ClientsWidget> with TickerProviderStateM
|
||||||
],
|
],
|
||||||
bottom: tabBar()
|
bottom: tabBar()
|
||||||
),
|
),
|
||||||
body: tabBarView(),
|
body: tabBarView(false),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
else {
|
return DefaultTabController(
|
||||||
return DefaultTabController(
|
length: 2,
|
||||||
length: 2,
|
child: NestedScrollView(
|
||||||
child: NestedScrollView(
|
controller: scrollController,
|
||||||
controller: scrollController,
|
headerSliverBuilder: ((context, innerBoxIsScrolled) {
|
||||||
headerSliverBuilder: ((context, innerBoxIsScrolled) {
|
return [
|
||||||
return [
|
SliverOverlapAbsorber(
|
||||||
SliverOverlapAbsorber(
|
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
|
||||||
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
|
sliver: SliverAppBar(
|
||||||
sliver: SliverAppBar(
|
title: searchMode == true
|
||||||
title: searchMode == true
|
? Row(
|
||||||
? Row(
|
children: [
|
||||||
children: [
|
IconButton(
|
||||||
IconButton(
|
onPressed: () {
|
||||||
onPressed: () {
|
setState(() {
|
||||||
setState(() {
|
searchMode = false;
|
||||||
searchMode = false;
|
searchController.text = "";
|
||||||
searchController.text = "";
|
serversProvider.setSearchTermClients(null);
|
||||||
serversProvider.setSearchTermClients(null);
|
});
|
||||||
});
|
},
|
||||||
},
|
icon: const Icon(Icons.arrow_back_rounded)
|
||||||
icon: const Icon(Icons.arrow_back_rounded)
|
),
|
||||||
),
|
const SizedBox(width: 16),
|
||||||
const SizedBox(width: 16),
|
Expanded(
|
||||||
Expanded(
|
child: TextField(
|
||||||
child: TextField(
|
controller: searchController,
|
||||||
controller: searchController,
|
onChanged: (value) => serversProvider.setSearchTermClients(value),
|
||||||
onChanged: (value) => serversProvider.setSearchTermClients(value),
|
decoration: InputDecoration(
|
||||||
decoration: InputDecoration(
|
suffixIcon: IconButton(
|
||||||
suffixIcon: IconButton(
|
onPressed: () {
|
||||||
onPressed: () {
|
setState(() {
|
||||||
setState(() {
|
searchController.text = "";
|
||||||
searchController.text = "";
|
serversProvider.setSearchTermClients(null);
|
||||||
serversProvider.setSearchTermClients(null);
|
});
|
||||||
});
|
},
|
||||||
},
|
icon: const Icon(Icons.clear_rounded)
|
||||||
icon: const Icon(Icons.clear_rounded)
|
),
|
||||||
|
hintText: AppLocalizations.of(context)!.search,
|
||||||
|
hintStyle: const TextStyle(
|
||||||
|
fontWeight: FontWeight.normal,
|
||||||
|
fontSize: 18
|
||||||
|
),
|
||||||
|
border: InputBorder.none,
|
||||||
),
|
),
|
||||||
hintText: AppLocalizations.of(context)!.search,
|
style: const TextStyle(
|
||||||
hintStyle: const TextStyle(
|
|
||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
fontSize: 18
|
fontSize: 18
|
||||||
),
|
),
|
||||||
border: InputBorder.none,
|
|
||||||
),
|
),
|
||||||
style: const TextStyle(
|
)
|
||||||
fontWeight: FontWeight.normal,
|
],
|
||||||
fontSize: 18
|
)
|
||||||
),
|
: Text(AppLocalizations.of(context)!.clients),
|
||||||
),
|
pinned: true,
|
||||||
)
|
floating: true,
|
||||||
],
|
centerTitle: false,
|
||||||
)
|
forceElevated: innerBoxIsScrolled,
|
||||||
: Text(AppLocalizations.of(context)!.clients),
|
actions: [
|
||||||
pinned: true,
|
if (serversProvider.clients.loadStatus == LoadStatus.loaded && searchMode == false) ...[
|
||||||
floating: true,
|
IconButton(
|
||||||
centerTitle: false,
|
onPressed: () => setState(() => searchMode = true),
|
||||||
forceElevated: innerBoxIsScrolled,
|
icon: const Icon(Icons.search),
|
||||||
actions: [
|
tooltip: AppLocalizations.of(context)!.searchClients,
|
||||||
if (serversProvider.clients.loadStatus == LoadStatus.loaded && searchMode == false) ...[
|
),
|
||||||
IconButton(
|
const SizedBox(width: 10),
|
||||||
onPressed: () => setState(() => searchMode = true),
|
]
|
||||||
icon: const Icon(Icons.search),
|
],
|
||||||
tooltip: AppLocalizations.of(context)!.searchClients,
|
bottom: tabBar()
|
||||||
),
|
),
|
||||||
const SizedBox(width: 10),
|
)
|
||||||
]
|
];
|
||||||
],
|
}),
|
||||||
bottom: tabBar()
|
body: tabBarView(true)
|
||||||
),
|
)
|
||||||
)
|
);
|
||||||
];
|
}
|
||||||
}),
|
|
||||||
body: tabBarView()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_split_view/flutter_split_view.dart';
|
import 'package:flutter_split_view/flutter_split_view.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
@ -84,7 +86,7 @@ class _ClientsDesktopViewState extends State<ClientsDesktopView> with TickerPro
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget tabBarView() {
|
Widget tabBarView(bool sliver) {
|
||||||
return TabBarView(
|
return TabBarView(
|
||||||
controller: tabController,
|
controller: tabController,
|
||||||
children: [
|
children: [
|
||||||
|
@ -107,7 +109,8 @@ class _ClientsDesktopViewState extends State<ClientsDesktopView> with TickerPro
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
selectedClient: selectedActiveClient,
|
selectedClient: selectedActiveClient,
|
||||||
splitView: true
|
splitView: true,
|
||||||
|
sliver: sliver,
|
||||||
),
|
),
|
||||||
AddedList(
|
AddedList(
|
||||||
scrollController: scrollController,
|
scrollController: scrollController,
|
||||||
|
@ -134,69 +137,112 @@ class _ClientsDesktopViewState extends State<ClientsDesktopView> with TickerPro
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefaultTabController(
|
Widget title() {
|
||||||
length: 2,
|
if (searchMode == true) {
|
||||||
child: Scaffold(
|
return Row(
|
||||||
appBar: AppBar(
|
children: [
|
||||||
title: searchMode == true
|
IconButton(
|
||||||
? Row(
|
onPressed: () {
|
||||||
children: [
|
setState(() {
|
||||||
IconButton(
|
searchMode = false;
|
||||||
|
searchController.text = "";
|
||||||
|
serversProvider.setSearchTermClients(null);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.arrow_back_rounded)
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
Expanded(
|
||||||
|
child: TextField(
|
||||||
|
controller: searchController,
|
||||||
|
onChanged: (value) => serversProvider.setSearchTermClients(value),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
suffixIcon: IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
searchMode = false;
|
|
||||||
searchController.text = "";
|
searchController.text = "";
|
||||||
serversProvider.setSearchTermClients(null);
|
serversProvider.setSearchTermClients(null);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.arrow_back_rounded)
|
icon: const Icon(Icons.clear_rounded)
|
||||||
),
|
),
|
||||||
const SizedBox(width: 16),
|
hintText: AppLocalizations.of(context)!.search,
|
||||||
Expanded(
|
hintStyle: const TextStyle(
|
||||||
child: TextField(
|
fontWeight: FontWeight.normal,
|
||||||
controller: searchController,
|
fontSize: 18
|
||||||
onChanged: (value) => serversProvider.setSearchTermClients(value),
|
),
|
||||||
decoration: InputDecoration(
|
border: InputBorder.none,
|
||||||
suffixIcon: IconButton(
|
),
|
||||||
onPressed: () {
|
style: const TextStyle(
|
||||||
setState(() {
|
fontWeight: FontWeight.normal,
|
||||||
searchController.text = "";
|
fontSize: 18
|
||||||
serversProvider.setSearchTermClients(null);
|
),
|
||||||
});
|
|
||||||
},
|
|
||||||
icon: const Icon(Icons.clear_rounded)
|
|
||||||
),
|
|
||||||
hintText: AppLocalizations.of(context)!.search,
|
|
||||||
hintStyle: const TextStyle(
|
|
||||||
fontWeight: FontWeight.normal,
|
|
||||||
fontSize: 18
|
|
||||||
),
|
|
||||||
border: InputBorder.none,
|
|
||||||
),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.normal,
|
|
||||||
fontSize: 18
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
: Text(AppLocalizations.of(context)!.clients),
|
|
||||||
centerTitle: false,
|
|
||||||
actions: [
|
|
||||||
if (serversProvider.clients.loadStatus == LoadStatus.loaded && searchMode == false) ...[
|
|
||||||
IconButton(
|
|
||||||
onPressed: () => setState(() => searchMode = true),
|
|
||||||
icon: const Icon(Icons.search),
|
|
||||||
tooltip: AppLocalizations.of(context)!.searchClients,
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: 10),
|
)
|
||||||
]
|
|
||||||
],
|
],
|
||||||
bottom: tabBar()
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Text(AppLocalizations.of(context)!.clients);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(Platform.isAndroid || Platform.isIOS)) {
|
||||||
|
return DefaultTabController(
|
||||||
|
length: 2,
|
||||||
|
child: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: title(),
|
||||||
|
centerTitle: false,
|
||||||
|
actions: [
|
||||||
|
if (serversProvider.clients.loadStatus == LoadStatus.loaded && searchMode == false) ...[
|
||||||
|
IconButton(
|
||||||
|
onPressed: () => setState(() => searchMode = true),
|
||||||
|
icon: const Icon(Icons.search),
|
||||||
|
tooltip: AppLocalizations.of(context)!.searchClients,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
bottom: tabBar()
|
||||||
|
),
|
||||||
|
body: tabBarView(false),
|
||||||
),
|
),
|
||||||
body: tabBarView(),
|
);
|
||||||
),
|
}
|
||||||
);
|
else {
|
||||||
|
return DefaultTabController(
|
||||||
|
length: 2,
|
||||||
|
child: NestedScrollView(
|
||||||
|
controller: scrollController,
|
||||||
|
headerSliverBuilder: ((context, innerBoxIsScrolled) {
|
||||||
|
return [
|
||||||
|
SliverOverlapAbsorber(
|
||||||
|
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
|
||||||
|
sliver: SliverAppBar(
|
||||||
|
title: title(),
|
||||||
|
pinned: true,
|
||||||
|
floating: true,
|
||||||
|
centerTitle: false,
|
||||||
|
forceElevated: innerBoxIsScrolled,
|
||||||
|
actions: [
|
||||||
|
if (serversProvider.clients.loadStatus == LoadStatus.loaded && searchMode == false) ...[
|
||||||
|
IconButton(
|
||||||
|
onPressed: () => setState(() => searchMode = true),
|
||||||
|
icon: const Icon(Icons.search),
|
||||||
|
tooltip: AppLocalizations.of(context)!.searchClients,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
]
|
||||||
|
],
|
||||||
|
bottom: tabBar()
|
||||||
|
),
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}),
|
||||||
|
body: tabBarView(true)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -18,6 +18,7 @@ class ClientsList extends StatelessWidget {
|
||||||
final void Function(AutoClient) onClientSelected;
|
final void Function(AutoClient) onClientSelected;
|
||||||
final AutoClient? selectedClient;
|
final AutoClient? selectedClient;
|
||||||
final bool splitView;
|
final bool splitView;
|
||||||
|
final bool sliver;
|
||||||
|
|
||||||
const ClientsList({
|
const ClientsList({
|
||||||
Key? key,
|
Key? key,
|
||||||
|
@ -27,7 +28,8 @@ class ClientsList extends StatelessWidget {
|
||||||
required this.fetchClients,
|
required this.fetchClients,
|
||||||
required this.onClientSelected,
|
required this.onClientSelected,
|
||||||
this.selectedClient,
|
this.selectedClient,
|
||||||
required this.splitView
|
required this.splitView,
|
||||||
|
required this.sliver
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -36,7 +38,7 @@ class ClientsList extends StatelessWidget {
|
||||||
listPadding: splitView == true
|
listPadding: splitView == true
|
||||||
? const EdgeInsets.only(top: 8)
|
? const EdgeInsets.only(top: 8)
|
||||||
: null,
|
: null,
|
||||||
noSliver: !(Platform.isAndroid || Platform.isIOS),
|
noSliver: !sliver,
|
||||||
loadingGenerator: () => SizedBox(
|
loadingGenerator: () => SizedBox(
|
||||||
width: double.maxFinite,
|
width: double.maxFinite,
|
||||||
height: MediaQuery.of(context).size.height-171,
|
height: MediaQuery.of(context).size.height-171,
|
||||||
|
|
Loading…
Add table
Reference in a new issue