mirror of
https://github.com/localsend/localsend.git
synced 2026-08-07 07:14:52 +00:00
feat: device detail
This commit is contained in:
@@ -213,7 +213,9 @@
|
|||||||
"verify": "Verify",
|
"verify": "Verify",
|
||||||
"info": {
|
"info": {
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"address": "Address"
|
"address": "Address",
|
||||||
|
"version": "Version",
|
||||||
|
"protocol": "Protocol v{version}"
|
||||||
},
|
},
|
||||||
"logs": {
|
"logs": {
|
||||||
"title": "Logs",
|
"title": "Logs",
|
||||||
@@ -225,7 +227,8 @@
|
|||||||
"verifyPage": {
|
"verifyPage": {
|
||||||
"title": "Verify",
|
"title": "Verify",
|
||||||
"icons": "Icons",
|
"icons": "Icons",
|
||||||
"raw": "Raw"
|
"raw": "Raw",
|
||||||
|
"question": "Does it look the same on the other device?"
|
||||||
},
|
},
|
||||||
"receivePage": {
|
"receivePage": {
|
||||||
"subTitle": {
|
"subTitle": {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
/// To regenerate, run: `dart run slang`
|
/// To regenerate, run: `dart run slang`
|
||||||
///
|
///
|
||||||
/// Locales: 55
|
/// Locales: 55
|
||||||
/// Strings: 18572 (337 per locale)
|
/// Strings: 18575 (337 per locale)
|
||||||
|
|
||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
// ignore_for_file: type=lint, unused_import
|
// ignore_for_file: type=lint, unused_import
|
||||||
|
|||||||
@@ -427,6 +427,9 @@ class Translations$verifyPage$en {
|
|||||||
|
|
||||||
/// en: 'Raw'
|
/// en: 'Raw'
|
||||||
String get raw => 'Raw';
|
String get raw => 'Raw';
|
||||||
|
|
||||||
|
/// en: 'Does it look the same on the other device?'
|
||||||
|
String get question => 'Does it look the same on the other device?';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Path: receivePage
|
// Path: receivePage
|
||||||
@@ -1322,6 +1325,12 @@ class Translations$deviceDetailsPage$info$en {
|
|||||||
|
|
||||||
/// en: 'Address'
|
/// en: 'Address'
|
||||||
String get address => 'Address';
|
String get address => 'Address';
|
||||||
|
|
||||||
|
/// en: 'Version'
|
||||||
|
String get version => 'Version';
|
||||||
|
|
||||||
|
/// en: 'Protocol v{version}'
|
||||||
|
String protocol({required Object version}) => 'Protocol v${version}';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Path: deviceDetailsPage.logs
|
// Path: deviceDetailsPage.logs
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ class _DeviceDetailsPageState extends State<DeviceDetailsPage> with Refena {
|
|||||||
BigButton(
|
BigButton(
|
||||||
icon: favoriteEntry != null ? Icons.favorite : Icons.favorite_border,
|
icon: favoriteEntry != null ? Icons.favorite : Icons.favorite_border,
|
||||||
label: t.deviceDetailsPage.favorite,
|
label: t.deviceDetailsPage.favorite,
|
||||||
filled: false,
|
filled: favoriteEntry != null,
|
||||||
onTap: () async => await _toggleFavorite(favoriteEntry),
|
onTap: () async => await _toggleFavorite(favoriteEntry),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 20),
|
const SizedBox(width: 20),
|
||||||
@@ -99,6 +99,7 @@ class _DeviceDetailsPageState extends State<DeviceDetailsPage> with Refena {
|
|||||||
children: [
|
children: [
|
||||||
for (final entry in {
|
for (final entry in {
|
||||||
t.deviceDetailsPage.info.name: device.alias,
|
t.deviceDetailsPage.info.name: device.alias,
|
||||||
|
t.deviceDetailsPage.info.version: t.deviceDetailsPage.info.protocol(version: device.version),
|
||||||
if (device.ip != null) t.deviceDetailsPage.info.address: '${device.ip}:${device.port}',
|
if (device.ip != null) t.deviceDetailsPage.info.address: '${device.ip}:${device.port}',
|
||||||
}.entries)
|
}.entries)
|
||||||
TableRow(
|
TableRow(
|
||||||
|
|||||||
@@ -216,11 +216,13 @@ class SendTab extends StatelessWidget {
|
|||||||
child: vm.sendMode == SendMode.multiple
|
child: vm.sendMode == SendMode.multiple
|
||||||
? _MultiSendDeviceListTile(
|
? _MultiSendDeviceListTile(
|
||||||
device: device,
|
device: device,
|
||||||
|
isFavorite: favoriteEntry != null,
|
||||||
nameOverride: favoriteEntry?.alias,
|
nameOverride: favoriteEntry?.alias,
|
||||||
vm: vm,
|
vm: vm,
|
||||||
)
|
)
|
||||||
: DeviceListTile(
|
: DeviceListTile(
|
||||||
device: device,
|
device: device,
|
||||||
|
isFavorite: favoriteEntry != null,
|
||||||
nameOverride: favoriteEntry?.alias,
|
nameOverride: favoriteEntry?.alias,
|
||||||
onDetailsTap: () async => await context.push(() => DeviceDetailsPage(device: device)),
|
onDetailsTap: () async => await context.push(() => DeviceDetailsPage(device: device)),
|
||||||
onTap: () async => await vm.onTapDevice(context, device),
|
onTap: () async => await vm.onTapDevice(context, device),
|
||||||
@@ -513,11 +515,13 @@ class _SendModeButton extends StatelessWidget {
|
|||||||
/// An advanced list tile which shows the progress of the file transfer.
|
/// An advanced list tile which shows the progress of the file transfer.
|
||||||
class _MultiSendDeviceListTile extends StatelessWidget {
|
class _MultiSendDeviceListTile extends StatelessWidget {
|
||||||
final Device device;
|
final Device device;
|
||||||
|
final bool isFavorite;
|
||||||
final String? nameOverride;
|
final String? nameOverride;
|
||||||
final SendTabVm vm;
|
final SendTabVm vm;
|
||||||
|
|
||||||
const _MultiSendDeviceListTile({
|
const _MultiSendDeviceListTile({
|
||||||
required this.device,
|
required this.device,
|
||||||
|
required this.isFavorite,
|
||||||
required this.nameOverride,
|
required this.nameOverride,
|
||||||
required this.vm,
|
required this.vm,
|
||||||
});
|
});
|
||||||
@@ -548,6 +552,7 @@ class _MultiSendDeviceListTile extends StatelessWidget {
|
|||||||
device: device,
|
device: device,
|
||||||
info: info,
|
info: info,
|
||||||
progress: progress,
|
progress: progress,
|
||||||
|
isFavorite: isFavorite,
|
||||||
nameOverride: nameOverride,
|
nameOverride: nameOverride,
|
||||||
onDetailsTap: () async => await context.push(() => DeviceDetailsPage(device: device)),
|
onDetailsTap: () async => await context.push(() => DeviceDetailsPage(device: device)),
|
||||||
onTap: () async => await vm.onTapDeviceMultiSend(context, device),
|
onTap: () async => await vm.onTapDeviceMultiSend(context, device),
|
||||||
|
|||||||
@@ -66,6 +66,14 @@ class _VerifyPageState extends State<VerifyPage> {
|
|||||||
),
|
),
|
||||||
_VerifyMode.raw => SelectableText(combined),
|
_VerifyMode.raw => SelectableText(combined),
|
||||||
},
|
},
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
t.verifyPage.question,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Theme.of(context).colorScheme.onSurfaceVariant),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import 'package:localsend_isolates/model/device.dart';
|
|||||||
|
|
||||||
class DeviceListTile extends StatelessWidget {
|
class DeviceListTile extends StatelessWidget {
|
||||||
final Device device;
|
final Device device;
|
||||||
|
final bool isFavorite;
|
||||||
|
|
||||||
/// If not null, this name is used instead of [Device.alias].
|
/// If not null, this name is used instead of [Device.alias].
|
||||||
/// This is the case when the device is marked as favorite.
|
/// This is the case when the device is marked as favorite.
|
||||||
@@ -19,6 +20,7 @@ class DeviceListTile extends StatelessWidget {
|
|||||||
|
|
||||||
const DeviceListTile({
|
const DeviceListTile({
|
||||||
required this.device,
|
required this.device,
|
||||||
|
this.isFavorite = false,
|
||||||
this.nameOverride,
|
this.nameOverride,
|
||||||
this.info,
|
this.info,
|
||||||
this.progress,
|
this.progress,
|
||||||
@@ -31,7 +33,16 @@ class DeviceListTile extends StatelessWidget {
|
|||||||
final badgeColor = Color.lerp(Theme.of(context).colorScheme.secondaryContainer, Colors.white, 0.3)!;
|
final badgeColor = Color.lerp(Theme.of(context).colorScheme.secondaryContainer, Colors.white, 0.3)!;
|
||||||
return CustomListTile(
|
return CustomListTile(
|
||||||
icon: Icon(device.deviceType.icon, size: 46),
|
icon: Icon(device.deviceType.icon, size: 46),
|
||||||
title: Text(nameOverride ?? device.alias, style: const TextStyle(fontSize: 20)),
|
title: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(nameOverride ?? device.alias, style: const TextStyle(fontSize: 20)),
|
||||||
|
if (isFavorite) ...[
|
||||||
|
const SizedBox(width: 5),
|
||||||
|
Icon(Icons.check_circle, size: 16),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
trailing: onDetailsTap != null
|
trailing: onDetailsTap != null
|
||||||
? IconButton(
|
? IconButton(
|
||||||
icon: const Icon(Icons.info_outline),
|
icon: const Icon(Icons.info_outline),
|
||||||
@@ -54,7 +65,7 @@ class DeviceListTile extends StatelessWidget {
|
|||||||
DeviceBadge(
|
DeviceBadge(
|
||||||
backgroundColor: badgeColor,
|
backgroundColor: badgeColor,
|
||||||
foregroundColor: Theme.of(context).colorScheme.onSecondaryContainer,
|
foregroundColor: Theme.of(context).colorScheme.onSecondaryContainer,
|
||||||
label: 'LAN • HTTP',
|
label: 'HTTP',
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
DeviceBadge(
|
DeviceBadge(
|
||||||
|
|||||||
Reference in New Issue
Block a user