feat: update favorite device name if unchanged (#1009)

This commit is contained in:
Tien Do Nam
2023-12-08 02:22:20 +01:00
committed by GitHub
parent b06ea9d04a
commit fcdce92df2
5 changed files with 51 additions and 15 deletions

View File

@@ -13,12 +13,18 @@ class FavoriteDevice with FavoriteDeviceMappable {
final int port;
final String alias;
/// If true, the alias was set by the user.
/// If false, the alias is derived from the original device alias and
/// should be updated when the original device alias changes.
final bool customAlias;
const FavoriteDevice({
required this.id,
required this.fingerprint,
required this.ip,
required this.port,
required this.alias,
this.customAlias = false,
});
factory FavoriteDevice.fromValues({
@@ -33,6 +39,7 @@ class FavoriteDevice with FavoriteDeviceMappable {
ip: ip,
port: port,
alias: alias,
customAlias: false,
);
}

View File

@@ -31,6 +31,9 @@ class FavoriteDeviceMapper extends ClassMapperBase<FavoriteDevice> {
static const Field<FavoriteDevice, int> _f$port = Field('port', _$port);
static String _$alias(FavoriteDevice v) => v.alias;
static const Field<FavoriteDevice, String> _f$alias = Field('alias', _$alias);
static bool _$customAlias(FavoriteDevice v) => v.customAlias;
static const Field<FavoriteDevice, bool> _f$customAlias =
Field('customAlias', _$customAlias, opt: true, def: false);
@override
final Map<Symbol, Field<FavoriteDevice, dynamic>> fields = const {
@@ -39,6 +42,7 @@ class FavoriteDeviceMapper extends ClassMapperBase<FavoriteDevice> {
#ip: _f$ip,
#port: _f$port,
#alias: _f$alias,
#customAlias: _f$customAlias,
};
static FavoriteDevice _instantiate(DecodingData data) {
@@ -47,7 +51,8 @@ class FavoriteDeviceMapper extends ClassMapperBase<FavoriteDevice> {
fingerprint: data.dec(_f$fingerprint),
ip: data.dec(_f$ip),
port: data.dec(_f$port),
alias: data.dec(_f$alias));
alias: data.dec(_f$alias),
customAlias: data.dec(_f$customAlias));
}
@override
@@ -106,7 +111,12 @@ extension FavoriteDeviceValueCopy<$R, $Out>
abstract class FavoriteDeviceCopyWith<$R, $In extends FavoriteDevice, $Out>
implements ClassCopyWith<$R, $In, $Out> {
$R call(
{String? id, String? fingerprint, String? ip, int? port, String? alias});
{String? id,
String? fingerprint,
String? ip,
int? port,
String? alias,
bool? customAlias});
FavoriteDeviceCopyWith<$R2, $In, $Out2> $chain<$R2, $Out2>(
Then<$Out2, $R2> t);
}
@@ -125,13 +135,15 @@ class _FavoriteDeviceCopyWithImpl<$R, $Out>
String? fingerprint,
String? ip,
int? port,
String? alias}) =>
String? alias,
bool? customAlias}) =>
$apply(FieldCopyWithData({
if (id != null) #id: id,
if (fingerprint != null) #fingerprint: fingerprint,
if (ip != null) #ip: ip,
if (port != null) #port: port,
if (alias != null) #alias: alias
if (alias != null) #alias: alias,
if (customAlias != null) #customAlias: customAlias
}));
@override
FavoriteDevice $make(CopyWithData data) => FavoriteDevice(
@@ -139,7 +151,8 @@ class _FavoriteDeviceCopyWithImpl<$R, $Out>
fingerprint: data.get(#fingerprint, or: $value.fingerprint),
ip: data.get(#ip, or: $value.ip),
port: data.get(#port, or: $value.port),
alias: data.get(#alias, or: $value.alias));
alias: data.get(#alias, or: $value.alias),
customAlias: data.get(#customAlias, or: $value.customAlias));
@override
FavoriteDeviceCopyWith<$R2, FavoriteDevice, $Out2> $chain<$R2, $Out2>(

View File

@@ -1,8 +1,10 @@
import 'dart:async';
import 'package:collection/collection.dart';
import 'package:localsend_app/model/device.dart';
import 'package:localsend_app/model/persistence/favorite_device.dart';
import 'package:localsend_app/model/state/nearby_devices_state.dart';
import 'package:localsend_app/provider/favorites_provider.dart';
import 'package:localsend_app/provider/logging/discovery_logs_provider.dart';
import 'package:localsend_app/provider/network/multicast_provider.dart';
import 'package:localsend_app/provider/network/targeted_discovery_provider.dart';
@@ -22,6 +24,7 @@ final nearbyDevicesProvider = ReduxProvider<NearbyDevicesService, NearbyDevicesS
discoveryLogs: ref.notifier(discoveryLoggerProvider),
targetedDiscoveryService: ref.accessor(targetedDiscoveryProvider),
multicastService: ref.accessor(multicastProvider),
favoriteService: ref.notifier(favoritesProvider),
);
});
@@ -31,14 +34,17 @@ class NearbyDevicesService extends ReduxNotifier<NearbyDevicesState> {
final DiscoveryLogger _discoveryLogs;
final StateAccessor<TargetedDiscoveryService> _targetedDiscoveryService;
final StateAccessor<MulticastService> _multicastService;
final FavoritesService _favoriteService;
NearbyDevicesService({
required DiscoveryLogger discoveryLogs,
required StateAccessor<TargetedDiscoveryService> targetedDiscoveryService,
required StateAccessor<MulticastService> multicastService,
required FavoritesService favoriteService,
}) : _discoveryLogs = discoveryLogs,
_targetedDiscoveryService = targetedDiscoveryService,
_multicastService = multicastService;
_multicastService = multicastService,
_favoriteService = favoriteService;
@override
NearbyDevicesState init() => const NearbyDevicesState(
@@ -98,7 +104,7 @@ class StartMulticastListener extends AsyncReduxAction<NearbyDevicesService, Near
@override
Future<NearbyDevicesState> reduce() async {
await for (final device in notifier._multicastService.state.startListener()) {
dispatch(RegisterDeviceAction(device));
await dispatchAsync(RegisterDeviceAction(device));
notifier._discoveryLogs.addLog('[DISCOVER/UDP] ${device.alias} (${device.ip}, model: ${device.deviceModel})');
}
return state;
@@ -117,7 +123,7 @@ class ClearFoundDevicesAction extends ReduxAction<NearbyDevicesService, NearbyDe
/// Registers a device in the state.
/// It will override any existing device with the same IP.
class RegisterDeviceAction extends ReduxAction<NearbyDevicesService, NearbyDevicesState> {
class RegisterDeviceAction extends AsyncReduxAction<NearbyDevicesService, NearbyDevicesState> {
final Device device;
RegisterDeviceAction(this.device);
@@ -126,7 +132,12 @@ class RegisterDeviceAction extends ReduxAction<NearbyDevicesService, NearbyDevic
bool get trackOrigin => false;
@override
NearbyDevicesState reduce() {
Future<NearbyDevicesState> reduce() async {
final favoriteDevice = notifier._favoriteService.state.firstWhereOrNull((e) => e.fingerprint == device.fingerprint);
if (favoriteDevice != null && !favoriteDevice.customAlias) {
// Update existing favorite with new alias
await external(notifier._favoriteService).dispatchAsync(UpdateFavoriteAction(favoriteDevice.copyWith(alias: device.alias)));
}
return state.copyWith(
devices: {...state.devices}..update(device.ip, (_) => device, ifAbsent: () => device),
);
@@ -166,7 +177,7 @@ class StartLegacyScan extends AsyncReduxAction<NearbyDevicesService, NearbyDevic
dispatch(_SetRunningIpsAction({...state.runningIps, localIp}));
await for (final device in notifier._getStream(localIp, port, https)) {
dispatch(RegisterDeviceAction(device));
await dispatchAsync(RegisterDeviceAction(device));
}
return state.copyWith(
@@ -191,7 +202,7 @@ class StartFavoriteScan extends AsyncReduxAction<NearbyDevicesService, NearbyDev
}
dispatch(_SetRunningFavoriteScanAction(true));
await for (final device in notifier._getFavoriteStream(devices: devices, https: https)) {
dispatch(RegisterDeviceAction(device));
await dispatchAsync(RegisterDeviceAction(device));
}
return state.copyWith(
runningFavoriteScan: false,

View File

@@ -159,7 +159,7 @@ class ReceiveController {
}
// Save device information
server.ref.redux(nearbyDevicesProvider).dispatch(RegisterDeviceAction(requestDto.toDevice(request.ip, port, https)));
await server.ref.redux(nearbyDevicesProvider).dispatchAsync(RegisterDeviceAction(requestDto.toDevice(request.ip, port, https)));
server.ref.notifier(discoveryLoggerProvider).addLog('[DISCOVER/TCP] Received "/register" HTTP request: ${requestDto.alias} (${request.ip})');
final deviceInfo = server.ref.read(deviceInfoProvider);

View File

@@ -127,16 +127,21 @@ class _FavoriteEditDialogState extends State<FavoriteEditDialog> with Refena {
}
if (widget.favorite != null) {
if (_aliasController.text.trim().isEmpty) {
// Update existing favorite
final existingFavorite = widget.favorite!;
final trimmedNewAlias = _aliasController.text.trim();
if (trimmedNewAlias.isEmpty) {
return;
}
await ref.redux(favoritesProvider).dispatchAsync(UpdateFavoriteAction(widget.favorite!.copyWith(
await ref.redux(favoritesProvider).dispatchAsync(UpdateFavoriteAction(existingFavorite.copyWith(
ip: _ipController.text,
port: int.parse(_portController.text),
alias: _aliasController.text,
alias: trimmedNewAlias,
customAlias: existingFavorite.customAlias || trimmedNewAlias != existingFavorite.alias,
)));
} else {
// Add new favorite
final ip = _ipController.text;
final port = int.parse(_portController.text);
final https = ref.read(settingsProvider).https;