Merge pull request #1 from Nutcake/main

chore: merge upstream changes
This commit is contained in:
Garrett 2023-10-28 12:01:26 -04:00 committed by GitHub
commit 022ade9ea0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 168 additions and 12 deletions

View file

@ -1,24 +1,74 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart';
import 'package:recon/apis/record_api.dart'; import 'package:recon/apis/record_api.dart';
import 'package:recon/clients/api_client.dart'; import 'package:recon/clients/api_client.dart';
import 'package:recon/models/inventory/resonite_directory.dart'; import 'package:recon/models/inventory/resonite_directory.dart';
import 'package:recon/models/records/record.dart'; import 'package:recon/models/records/record.dart';
import 'package:flutter/material.dart';
enum SortMode {
name,
date;
int sortFunction(Record a, Record b, {bool reverse = false}) {
final func = switch (this) {
SortMode.name => (Record x, Record y) =>
x.formattedName.toString().toLowerCase().compareTo(y.formattedName.toString().toLowerCase()),
SortMode.date => (Record x, Record y) => x.creationTime.compareTo(y.creationTime),
};
if (reverse) {
return func(b, a);
}
return func(a, b);
}
static const Map<SortMode, IconData> _iconsMap = {
SortMode.name: Icons.sort_by_alpha,
SortMode.date: Icons.access_time_outlined
};
IconData get icon => _iconsMap[this] ?? Icons.question_mark;
}
class InventoryClient extends ChangeNotifier { class InventoryClient extends ChangeNotifier {
final ApiClient apiClient; final ApiClient apiClient;
final Map<String, Record> _selectedRecords = {};
Future<ResoniteDirectory>? _currentDirectory; Future<ResoniteDirectory>? _currentDirectory;
SortMode _sortMode = SortMode.name;
Future<ResoniteDirectory>? get directoryFuture => _currentDirectory; bool _sortReverse = false;
InventoryClient({required this.apiClient}); InventoryClient({required this.apiClient});
final Map<String, Record> _selectedRecords = {}; SortMode get sortMode => _sortMode;
bool get sortReverse => _sortReverse;
set sortMode(SortMode mode) {
if (_sortMode != mode) {
_sortMode = mode;
notifyListeners();
}
}
set sortReverse(bool reverse) {
if (_sortReverse != reverse) {
_sortReverse = reverse;
notifyListeners();
}
}
List<Record> get selectedRecords => _selectedRecords.values.toList(); List<Record> get selectedRecords => _selectedRecords.values.toList();
Future<ResoniteDirectory>? get directoryFuture => _currentDirectory?.then(
(ResoniteDirectory value) {
value.children.sort(
(ResoniteDirectory a, ResoniteDirectory b) => _sortMode.sortFunction(a.record, b.record, reverse: _sortReverse),
);
return value;
},
);
bool get isAnyRecordSelected => _selectedRecords.isNotEmpty; bool get isAnyRecordSelected => _selectedRecords.isNotEmpty;
bool isRecordSelected(Record record) => _selectedRecords.containsKey(record.id); bool isRecordSelected(Record record) => _selectedRecords.containsKey(record.id);
@ -142,7 +192,8 @@ class InventoryClient extends ChangeNotifier {
_currentDirectory = _getDirectory(record).then( _currentDirectory = _getDirectory(record).then(
(records) { (records) {
childDir.children.clear(); childDir.children.clear();
childDir.children.addAll(records.map((record) => ResoniteDirectory.fromRecord(record: record, parent: childDir))); childDir.children
.addAll(records.map((record) => ResoniteDirectory.fromRecord(record: record, parent: childDir)));
return childDir; return childDir;
}, },
).onError((error, stackTrace) { ).onError((error, stackTrace) {

View file

@ -6,6 +6,7 @@ import 'package:recon/apis/session_api.dart';
import 'package:recon/apis/user_api.dart'; import 'package:recon/apis/user_api.dart';
import 'package:recon/clients/api_client.dart'; import 'package:recon/clients/api_client.dart';
import 'package:recon/clients/notification_client.dart'; import 'package:recon/clients/notification_client.dart';
import 'package:recon/clients/settings_client.dart';
import 'package:recon/crypto_helper.dart'; import 'package:recon/crypto_helper.dart';
import 'package:recon/hub_manager.dart'; import 'package:recon/hub_manager.dart';
import 'package:recon/models/hub_events.dart'; import 'package:recon/models/hub_events.dart';
@ -37,6 +38,7 @@ class MessagingClient extends ChangeNotifier {
final HubManager _hubManager = HubManager(); final HubManager _hubManager = HubManager();
final Map<String, Session> _sessionMap = {}; final Map<String, Session> _sessionMap = {};
final Set<String> _knownSessionKeys = {}; final Set<String> _knownSessionKeys = {};
final SettingsClient _settingsClient;
Friend? selectedFriend; Friend? selectedFriend;
Timer? _statusHeartbeat; Timer? _statusHeartbeat;
@ -47,9 +49,11 @@ class MessagingClient extends ChangeNotifier {
UserStatus get userStatus => _userStatus; UserStatus get userStatus => _userStatus;
MessagingClient({required ApiClient apiClient, required NotificationClient notificationClient}) MessagingClient({required ApiClient apiClient, required NotificationClient notificationClient, required SettingsClient settingsClient})
: _apiClient = apiClient, : _apiClient = apiClient,
_notificationClient = notificationClient { _notificationClient = notificationClient,
_settingsClient = settingsClient
{
debugPrint("mClient created: $hashCode"); debugPrint("mClient created: $hashCode");
Hive.openBox(_messageBoxKey).then((box) async { Hive.openBox(_messageBoxKey).then((box) async {
await box.delete(_lastUpdateKey); await box.delete(_lastUpdateKey);
@ -276,7 +280,8 @@ class MessagingClient extends ChangeNotifier {
await _refreshUnreads(); await _refreshUnreads();
_unreadSafeguard = Timer.periodic(_unreadSafeguardDuration, (timer) => _refreshUnreads()); _unreadSafeguard = Timer.periodic(_unreadSafeguardDuration, (timer) => _refreshUnreads());
_hubManager.send("RequestStatus", arguments: [null, false]); _hubManager.send("RequestStatus", arguments: [null, false]);
await setOnlineStatus(OnlineStatus.online); final lastOnline = OnlineStatus.values.elementAtOrNull(_settingsClient.currentSettings.lastOnlineStatus.valueOrDefault);
await setOnlineStatus(lastOnline ?? OnlineStatus.online);
_statusHeartbeat = Timer.periodic(_statusHeartbeatDuration, (timer) { _statusHeartbeat = Timer.periodic(_statusHeartbeatDuration, (timer) {
setOnlineStatus(_userStatus.onlineStatus); setOnlineStatus(_userStatus.onlineStatus);
}); });

View file

@ -164,6 +164,7 @@ class _ReConState extends State<ReCon> {
ChangeNotifierProvider( ChangeNotifierProvider(
create: (context) => MessagingClient( create: (context) => MessagingClient(
apiClient: clientHolder.apiClient, apiClient: clientHolder.apiClient,
settingsClient: clientHolder.settingsClient,
notificationClient: clientHolder.notificationClient, notificationClient: clientHolder.notificationClient,
), ),
), ),

View file

@ -77,8 +77,9 @@ class _InventoryBrowserState extends State<InventoryBrowser> with AutomaticKeepA
} }
final directory = snapshot.data; final directory = snapshot.data;
final records = directory?.records ?? []; final records = directory?.records ?? [];
records.sort(
records.sort((a, b) => a.name.compareTo(b.name)); (Record a, Record b) => iClient.sortMode.sortFunction(a, b, reverse: iClient.sortReverse),
);
final paths = records final paths = records
.where((element) => .where((element) =>
element.recordType == RecordType.link || element.recordType == RecordType.directory) element.recordType == RecordType.link || element.recordType == RecordType.directory)

View file

@ -4,6 +4,7 @@ import 'dart:ui';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_downloader/flutter_downloader.dart'; import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:intl/intl.dart';
import 'package:path/path.dart'; import 'package:path/path.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:recon/auxiliary.dart'; import 'package:recon/auxiliary.dart';
@ -50,7 +51,7 @@ class _InventoryBrowserAppBarState extends State<InventoryBrowserAppBar> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<InventoryClient>( return Consumer<InventoryClient>(
builder: (BuildContext context, InventoryClient iClient, Widget? child) { builder: (BuildContext context, InventoryClient iClient, Widget? _) {
return AnimatedSwitcher( return AnimatedSwitcher(
duration: const Duration(milliseconds: 350), duration: const Duration(milliseconds: 350),
transitionBuilder: (child, animation) => FadeTransition( transitionBuilder: (child, animation) => FadeTransition(
@ -61,6 +62,103 @@ class _InventoryBrowserAppBarState extends State<InventoryBrowserAppBar> {
? AppBar( ? AppBar(
key: const ValueKey("default-appbar"), key: const ValueKey("default-appbar"),
title: const Text("Inventory"), title: const Text("Inventory"),
actions: [
PopupMenuButton(
icon: const Icon(Icons.swap_vert),
onSelected: (value) {
iClient.sortReverse = value;
},
itemBuilder: (context) {
return [
PopupMenuItem(
value: false,
child: Row(
children: [
Icon(
Icons.arrow_upward,
color: iClient.sortReverse == false
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.onSurface,
),
const SizedBox(
width: 8,
),
Text(
"Ascending",
style: TextStyle(
color: iClient.sortReverse == false
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.onSurface,
),
),
],
),
),
PopupMenuItem(
value: true,
child: Row(
children: [
Icon(Icons.arrow_downward,
color: iClient.sortReverse == true
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.onSurface),
const SizedBox(
width: 8,
),
Text(
"Descending",
style: TextStyle(
color: iClient.sortReverse == true
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.onSurface,
),
),
],
),
)
];
},
),
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: PopupMenuButton(
icon: const Icon(Icons.sort),
onSelected: (value) {
iClient.sortMode = value;
},
itemBuilder: (context) {
return SortMode.values
.map(
(e) => PopupMenuItem(
value: e,
child: Row(
children: [
Icon(
e.icon,
color: iClient.sortMode == e
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.onSurface,
),
const SizedBox(
width: 8,
),
Text(
toBeginningOfSentenceCase(e.name) ?? e.name,
style: TextStyle(
color: iClient.sortMode == e
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.onSurface,
),
)
],
),
),
)
.toList();
},
),
),
],
) )
: AppBar( : AppBar(
key: const ValueKey("selection-appbar"), key: const ValueKey("selection-appbar"),

View file

@ -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 # 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 # 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. # of the product and file versions while build-number is used as the build suffix.
version: 0.9.2-beta+1 version: 0.10.0-beta+1
environment: environment:
sdk: '>=3.0.1' sdk: '>=3.0.1'