Add caching to session filter and remove some redundant providers
This commit is contained in:
parent
56350ea2c7
commit
e87521df9d
11 changed files with 639 additions and 590 deletions
|
@ -1,17 +1,28 @@
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:contacts_plus_plus/apis/session_api.dart';
|
||||
import 'package:contacts_plus_plus/clients/api_client.dart';
|
||||
import 'package:contacts_plus_plus/clients/settings_client.dart';
|
||||
import 'package:contacts_plus_plus/models/session.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class SessionClient extends ChangeNotifier {
|
||||
final ApiClient apiClient;
|
||||
final SettingsClient settingsClient;
|
||||
|
||||
Future<List<Session>>? _sessionsFuture;
|
||||
|
||||
SessionFilterSettings _filterSettings = SessionFilterSettings.empty();
|
||||
|
||||
SessionClient({required this.apiClient});
|
||||
SessionClient({required this.apiClient, required this.settingsClient}) {
|
||||
_filterSettings = SessionFilterSettings(
|
||||
name: "",
|
||||
hostName: "",
|
||||
includeEnded: settingsClient.currentSettings.sessionViewLastIncludeEnded.valueOrDefault,
|
||||
includeIncompatible: settingsClient.currentSettings.sessionViewLastIncludeIncompatible.valueOrDefault,
|
||||
minActiveUsers: settingsClient.currentSettings.sessionViewLastMinimumUsers.valueOrDefault,
|
||||
includeEmptyHeadless: settingsClient.currentSettings.sessionViewLastIncludeEmpty.valueOrDefault,
|
||||
);
|
||||
}
|
||||
|
||||
SessionFilterSettings get filterSettings => _filterSettings;
|
||||
|
||||
|
@ -22,12 +33,16 @@ class SessionClient extends ChangeNotifier {
|
|||
reloadSessions();
|
||||
}
|
||||
|
||||
void reloadSessions() {
|
||||
void initSessions() {
|
||||
_sessionsFuture = SessionApi.getSessions(apiClient, filterSettings: _filterSettings).then(
|
||||
(value) => value.sorted(
|
||||
(a, b) => b.sessionUsers.length.compareTo(a.sessionUsers.length),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void reloadSessions() {
|
||||
initSessions();
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,17 +8,12 @@ import 'package:contacts_plus_plus/clients/messaging_client.dart';
|
|||
import 'package:contacts_plus_plus/clients/session_client.dart';
|
||||
import 'package:contacts_plus_plus/clients/settings_client.dart';
|
||||
import 'package:contacts_plus_plus/models/sem_ver.dart';
|
||||
import 'package:contacts_plus_plus/widgets/friends/friends_list_app_bar.dart';
|
||||
import 'package:contacts_plus_plus/widgets/homepage.dart';
|
||||
import 'package:contacts_plus_plus/widgets/inventory/inventory_browser_app_bar.dart';
|
||||
import 'package:contacts_plus_plus/widgets/login_screen.dart';
|
||||
import 'package:contacts_plus_plus/widgets/sessions/session_list_app_bar.dart';
|
||||
import 'package:contacts_plus_plus/widgets/settings_app_bar.dart';
|
||||
import 'package:contacts_plus_plus/widgets/update_notifier.dart';
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_downloader/flutter_downloader.dart';
|
||||
import 'package:flutter_phoenix/flutter_phoenix.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
|
@ -35,8 +30,6 @@ void main() async {
|
|||
debug: kDebugMode,
|
||||
);
|
||||
|
||||
Provider.debugCheckInvalidValueType = null;
|
||||
|
||||
await Hive.initFlutter();
|
||||
|
||||
final dateFormat = DateFormat.Hms();
|
||||
|
@ -156,19 +149,19 @@ class _ContactsPlusPlusState extends State<ContactsPlusPlus> {
|
|||
return _authData.isAuthenticated
|
||||
? MultiProvider(
|
||||
providers: [
|
||||
Provider(
|
||||
ChangeNotifierProvider(
|
||||
create: (context) => MessagingClient(
|
||||
apiClient: clientHolder.apiClient,
|
||||
notificationClient: clientHolder.notificationClient,
|
||||
),
|
||||
dispose: (context, value) => value.dispose(),
|
||||
),
|
||||
Provider(
|
||||
ChangeNotifierProvider(
|
||||
create: (context) => SessionClient(
|
||||
apiClient: clientHolder.apiClient,
|
||||
settingsClient: clientHolder.settingsClient,
|
||||
),
|
||||
),
|
||||
Provider(
|
||||
ChangeNotifierProvider(
|
||||
create: (context) => InventoryClient(
|
||||
apiClient: clientHolder.apiClient,
|
||||
),
|
||||
|
|
|
@ -40,31 +40,47 @@ class Settings {
|
|||
final SettingsEntry<String> lastDismissedVersion;
|
||||
final SettingsEntry<String> machineId;
|
||||
final SettingsEntry<int> themeMode;
|
||||
final SettingsEntry<int> sessionViewLastMinimumUsers;
|
||||
final SettingsEntry<bool> sessionViewLastIncludeEnded;
|
||||
final SettingsEntry<bool> sessionViewLastIncludeEmpty;
|
||||
final SettingsEntry<bool> sessionViewLastIncludeIncompatible;
|
||||
|
||||
Settings({
|
||||
SettingsEntry<bool>? notificationsDenied,
|
||||
SettingsEntry<int>? lastOnlineStatus,
|
||||
SettingsEntry<int>? themeMode,
|
||||
SettingsEntry<String>? lastDismissedVersion,
|
||||
SettingsEntry<String>? machineId
|
||||
})
|
||||
: notificationsDenied = notificationsDenied ?? const SettingsEntry<bool>(deflt: false),
|
||||
SettingsEntry<String>? machineId,
|
||||
SettingsEntry<int>? sessionViewLastMinimumUsers,
|
||||
SettingsEntry<bool>? sessionViewLastIncludeEnded,
|
||||
SettingsEntry<bool>? sessionViewLastIncludeEmpty,
|
||||
SettingsEntry<bool>? sessionViewLastIncludeIncompatible,
|
||||
}) : notificationsDenied = notificationsDenied ?? const SettingsEntry<bool>(deflt: false),
|
||||
lastOnlineStatus = lastOnlineStatus ?? SettingsEntry<int>(deflt: OnlineStatus.online.index),
|
||||
themeMode = themeMode ?? SettingsEntry<int>(deflt: ThemeMode.dark.index),
|
||||
lastDismissedVersion = lastDismissedVersion ?? SettingsEntry<String>(deflt: SemVer.zero().toString()),
|
||||
machineId = machineId ?? SettingsEntry<String>(deflt: const Uuid().v4());
|
||||
machineId = machineId ?? SettingsEntry<String>(deflt: const Uuid().v4()),
|
||||
sessionViewLastMinimumUsers = sessionViewLastMinimumUsers ?? const SettingsEntry<int>(deflt: 0),
|
||||
sessionViewLastIncludeEnded = sessionViewLastIncludeEnded ?? const SettingsEntry<bool>(deflt: false),
|
||||
sessionViewLastIncludeEmpty = sessionViewLastIncludeEmpty ?? const SettingsEntry<bool>(deflt: true),
|
||||
sessionViewLastIncludeIncompatible =
|
||||
sessionViewLastIncludeIncompatible ?? const SettingsEntry<bool>(deflt: false);
|
||||
|
||||
factory Settings.fromMap(Map map) {
|
||||
return Settings(
|
||||
notificationsDenied: retrieveEntryOrNull<bool>(map["notificationsDenied"]),
|
||||
lastOnlineStatus: retrieveEntryOrNull<int>(map["lastOnlineStatus"]),
|
||||
themeMode: retrieveEntryOrNull<int>(map["themeMode"]),
|
||||
lastDismissedVersion: retrieveEntryOrNull<String>(map["lastDismissedVersion"]),
|
||||
machineId: retrieveEntryOrNull<String>(map["machineId"]),
|
||||
notificationsDenied: getEntryOrNull<bool>(map["notificationsDenied"]),
|
||||
lastOnlineStatus: getEntryOrNull<int>(map["lastOnlineStatus"]),
|
||||
themeMode: getEntryOrNull<int>(map["themeMode"]),
|
||||
lastDismissedVersion: getEntryOrNull<String>(map["lastDismissedVersion"]),
|
||||
machineId: getEntryOrNull<String>(map["machineId"]),
|
||||
sessionViewLastMinimumUsers: getEntryOrNull<int>(map["sessionViewLastMinimumUsers"]),
|
||||
sessionViewLastIncludeEnded: getEntryOrNull<bool>(map["sessionViewLastIncludeEnded"]),
|
||||
sessionViewLastIncludeEmpty: getEntryOrNull<bool>(map["sessionViewLastIncludeEmpty"]),
|
||||
sessionViewLastIncludeIncompatible: getEntryOrNull<bool>(map["sessionViewLastIncludeIncompatible"]),
|
||||
);
|
||||
}
|
||||
|
||||
static SettingsEntry<T>? retrieveEntryOrNull<T>(Map? map) {
|
||||
static SettingsEntry<T>? getEntryOrNull<T>(Map? map) {
|
||||
if (map == null) return null;
|
||||
try {
|
||||
return SettingsEntry<T>.fromMap(map);
|
||||
|
@ -80,6 +96,10 @@ class Settings {
|
|||
"themeMode": themeMode.toMap(),
|
||||
"lastDismissedVersion": lastDismissedVersion.toMap(),
|
||||
"machineId": machineId.toMap(),
|
||||
"sessionViewLastMinimumUsers": sessionViewLastMinimumUsers.toMap(),
|
||||
"sessionViewLastIncludeEnded": sessionViewLastIncludeEnded.toMap(),
|
||||
"sessionViewLastIncludeEmpty": sessionViewLastIncludeEmpty.toMap(),
|
||||
"sessionViewLastIncludeIncompatible": sessionViewLastIncludeIncompatible.toMap(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -91,6 +111,10 @@ class Settings {
|
|||
int? themeMode,
|
||||
String? lastDismissedVersion,
|
||||
String? machineId,
|
||||
int? sessionViewLastMinimumUsers,
|
||||
bool? sessionViewLastIncludeEnded,
|
||||
bool? sessionViewLastIncludeEmpty,
|
||||
bool? sessionViewLastIncludeIncompatible,
|
||||
}) {
|
||||
return Settings(
|
||||
notificationsDenied: this.notificationsDenied.passThrough(notificationsDenied),
|
||||
|
@ -98,6 +122,11 @@ class Settings {
|
|||
themeMode: this.themeMode.passThrough(themeMode),
|
||||
lastDismissedVersion: this.lastDismissedVersion.passThrough(lastDismissedVersion),
|
||||
machineId: this.machineId.passThrough(machineId),
|
||||
sessionViewLastMinimumUsers: this.sessionViewLastMinimumUsers.passThrough(sessionViewLastMinimumUsers),
|
||||
sessionViewLastIncludeEnded: this.sessionViewLastIncludeEnded.passThrough(sessionViewLastIncludeEnded),
|
||||
sessionViewLastIncludeEmpty: this.sessionViewLastIncludeEmpty.passThrough(sessionViewLastIncludeEmpty),
|
||||
sessionViewLastIncludeIncompatible:
|
||||
this.sessionViewLastIncludeIncompatible.passThrough(sessionViewLastIncludeIncompatible),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@ import 'package:contacts_plus_plus/widgets/friends/friend_list_tile.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
||||
class FriendsList extends StatefulWidget {
|
||||
const FriendsList({super.key});
|
||||
|
||||
|
@ -19,12 +18,13 @@ class _FriendsListState extends State<FriendsList> with AutomaticKeepAliveClient
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return ChangeNotifierProvider.value(
|
||||
value: Provider.of<MessagingClient>(context, listen: false),
|
||||
child: Stack(
|
||||
return Consumer<MessagingClient>(
|
||||
builder: (context, mClient, _) {
|
||||
return Stack(
|
||||
alignment: Alignment.topCenter,
|
||||
children: [
|
||||
Consumer<MessagingClient>(builder: (context, mClient, _) {
|
||||
Builder(
|
||||
builder: (context) {
|
||||
if (mClient.initStatus == null) {
|
||||
return const LinearProgressIndicator();
|
||||
} else if (mClient.initStatus!.isNotEmpty) {
|
||||
|
@ -62,7 +62,8 @@ class _FriendsListState extends State<FriendsList> with AutomaticKeepAliveClient
|
|||
},
|
||||
);
|
||||
}
|
||||
}),
|
||||
},
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: ExpandingInputFab(
|
||||
|
@ -81,7 +82,8 @@ class _FriendsListState extends State<FriendsList> with AutomaticKeepAliveClient
|
|||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,9 +47,7 @@ class _FriendsListAppBarState extends State<FriendsListAppBar> with AutomaticKee
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return ChangeNotifierProvider.value(
|
||||
value: Provider.of<MessagingClient>(context, listen: false),
|
||||
child: AppBar(
|
||||
return AppBar(
|
||||
title: const Text("Contacts++"),
|
||||
actions: [
|
||||
FutureBuilder(
|
||||
|
@ -198,7 +196,6 @@ class _FriendsListAppBarState extends State<FriendsListAppBar> with AutomaticKee
|
|||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,9 +36,7 @@ class _InventoryBrowserState extends State<InventoryBrowser> with AutomaticKeepA
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return ChangeNotifierProvider.value(
|
||||
value: Provider.of<InventoryClient>(context),
|
||||
child: Consumer<InventoryClient>(builder: (BuildContext context, InventoryClient iClient, Widget? child) {
|
||||
return Consumer<InventoryClient>(builder: (BuildContext context, InventoryClient iClient, Widget? child) {
|
||||
return FutureBuilder<NeosDirectory>(
|
||||
future: iClient.directoryFuture,
|
||||
builder: (context, snapshot) {
|
||||
|
@ -224,8 +222,7 @@ class _InventoryBrowserState extends State<InventoryBrowser> with AutomaticKeepA
|
|||
),
|
||||
);
|
||||
});
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -48,9 +48,7 @@ class _InventoryBrowserAppBarState extends State<InventoryBrowserAppBar> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider.value(
|
||||
value: Provider.of<InventoryClient>(context),
|
||||
child: Consumer<InventoryClient>(
|
||||
return Consumer<InventoryClient>(
|
||||
builder: (BuildContext context, InventoryClient iClient, Widget? child) {
|
||||
return AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 350),
|
||||
|
@ -243,7 +241,6 @@ class _InventoryBrowserAppBarState extends State<InventoryBrowserAppBar> {
|
|||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:contacts_plus_plus/client_holder.dart';
|
||||
import 'package:contacts_plus_plus/clients/session_client.dart';
|
||||
import 'package:contacts_plus_plus/clients/settings_client.dart';
|
||||
import 'package:contacts_plus_plus/models/session.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
@ -44,9 +46,20 @@ class _SessionFilterDialogState extends State<SessionFilterDialog> {
|
|||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _updateSettings() async {
|
||||
final settingsClient = ClientHolder.of(context).settingsClient;
|
||||
await settingsClient.changeSettings(settingsClient.currentSettings.copyWith(
|
||||
sessionViewLastMinimumUsers: _currentFilter.minActiveUsers,
|
||||
sessionViewLastIncludeEnded: _currentFilter.includeEnded,
|
||||
sessionViewLastIncludeEmpty: _currentFilter.includeEmptyHeadless,
|
||||
sessionViewLastIncludeIncompatible: _currentFilter.includeIncompatible,
|
||||
));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
insetPadding: const EdgeInsets.all(24),
|
||||
title: const Text("Filter"),
|
||||
content: SizedBox(
|
||||
width: double.infinity,
|
||||
|
@ -109,7 +122,8 @@ class _SessionFilterDialogState extends State<SessionFilterDialog> {
|
|||
IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_currentFilter = _currentFilter.copyWith(minActiveUsers: _currentFilter.minActiveUsers + 1, includeEmptyHeadless: false);
|
||||
_currentFilter = _currentFilter.copyWith(
|
||||
minActiveUsers: _currentFilter.minActiveUsers + 1, includeEmptyHeadless: false);
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.add_circle_outline),
|
||||
|
@ -128,7 +142,9 @@ class _SessionFilterDialogState extends State<SessionFilterDialog> {
|
|||
SessionFilterCheckbox(
|
||||
label: "Include Empty Headless",
|
||||
value: _currentFilter.includeEmptyHeadless && _currentFilter.minActiveUsers == 0,
|
||||
onChanged: _currentFilter.minActiveUsers > 0 ? null : (value) {
|
||||
onChanged: _currentFilter.minActiveUsers > 0
|
||||
? null
|
||||
: (value) {
|
||||
setState(() {
|
||||
_currentFilter = _currentFilter.copyWith(includeEmptyHeadless: value);
|
||||
});
|
||||
|
@ -155,9 +171,10 @@ class _SessionFilterDialogState extends State<SessionFilterDialog> {
|
|||
child: const Text("Cancel"),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
onPressed: () async {
|
||||
Provider.of<SessionClient>(context, listen: false).filterSettings = _currentFilter;
|
||||
Navigator.of(context).pop();
|
||||
await _updateSettings();
|
||||
},
|
||||
child: const Text("Okay"),
|
||||
),
|
||||
|
|
|
@ -21,7 +21,7 @@ class _SessionListState extends State<SessionList> with AutomaticKeepAliveClient
|
|||
super.didChangeDependencies();
|
||||
final sClient = Provider.of<SessionClient>(context, listen: false);
|
||||
if (sClient.sessionsFuture == null) {
|
||||
sClient.reloadSessions();
|
||||
sClient.initSessions();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import 'package:contacts_plus_plus/client_holder.dart';
|
||||
import 'package:contacts_plus_plus/clients/session_client.dart';
|
||||
import 'package:contacts_plus_plus/clients/settings_client.dart';
|
||||
import 'package:contacts_plus_plus/widgets/sessions/session_filter_dialog.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
@ -23,7 +25,7 @@ class _SessionListAppBarState extends State<SessionListAppBar> {
|
|||
final sessionClient = Provider.of<SessionClient>(context, listen: false);
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) => Provider.value(
|
||||
builder: (context) => ChangeNotifierProvider.value(
|
||||
value: sessionClient,
|
||||
child: SessionFilterDialog(
|
||||
lastFilter: sessionClient.filterSettings,
|
||||
|
|
|
@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
version: 1.4.1+1
|
||||
version: 1.4.2+1
|
||||
|
||||
environment:
|
||||
sdk: '>=3.0.1'
|
||||
|
|
Loading…
Reference in a new issue