mirror of
https://github.com/localsend/localsend.git
synced 2026-06-23 04:10:07 +00:00
Add alias re-generation and system name buttons to settings page (#1829)
This commit is contained in:
committed by
GitHub
parent
66d88bf818
commit
6d356ed751
@@ -130,6 +130,8 @@
|
||||
"deviceModel": "Device model",
|
||||
"port": "Port",
|
||||
"discoveryTimeout": "Discovery Timeout",
|
||||
"useSystemName": "Use system name",
|
||||
"generateRandomAlias": "Generate random alias",
|
||||
"portWarning": "You might not be detected by other devices because you are using a custom port. (default: {defaultPort})",
|
||||
"encryption": "Encryption",
|
||||
"multicastGroup": "Multicast address",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/// To regenerate, run: `dart run slang`
|
||||
///
|
||||
/// Locales: 43
|
||||
/// Strings: 13481 (313 per locale)
|
||||
/// Strings: 13483 (313 per locale)
|
||||
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
|
||||
@@ -637,6 +637,8 @@ class _StringsSettingsTabNetworkEn {
|
||||
String get deviceModel => 'Device model';
|
||||
String get port => 'Port';
|
||||
String get discoveryTimeout => 'Discovery Timeout';
|
||||
String get useSystemName => 'Use system name';
|
||||
String get generateRandomAlias => 'Generate random alias';
|
||||
String portWarning({required Object defaultPort}) => 'You might not be detected by other devices because you are using a custom port. (default: ${defaultPort})';
|
||||
String get encryption => 'Encryption';
|
||||
String get multicastGroup => 'Multicast address';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:io';
|
||||
import 'package:common/constants.dart';
|
||||
import 'package:common/model/device.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
@@ -12,6 +13,7 @@ import 'package:localsend_app/pages/language_page.dart';
|
||||
import 'package:localsend_app/pages/tabs/settings_tab_controller.dart';
|
||||
import 'package:localsend_app/provider/settings_provider.dart';
|
||||
import 'package:localsend_app/provider/version_provider.dart';
|
||||
import 'package:localsend_app/util/alias_generator.dart';
|
||||
import 'package:localsend_app/util/device_type_ext.dart';
|
||||
import 'package:localsend_app/util/native/pick_directory_path.dart';
|
||||
import 'package:localsend_app/util/native/platform_check.dart';
|
||||
@@ -21,6 +23,7 @@ import 'package:localsend_app/widget/dialogs/pin_dialog.dart';
|
||||
import 'package:localsend_app/widget/dialogs/quick_save_from_favorites_notice.dart';
|
||||
import 'package:localsend_app/widget/dialogs/quick_save_notice.dart';
|
||||
import 'package:localsend_app/widget/dialogs/text_field_tv.dart';
|
||||
import 'package:localsend_app/widget/dialogs/text_field_with_actions.dart';
|
||||
import 'package:localsend_app/widget/labeled_checkbox.dart';
|
||||
import 'package:localsend_app/widget/local_send_logo.dart';
|
||||
import 'package:localsend_app/widget/responsive_list_view.dart';
|
||||
@@ -310,12 +313,43 @@ class SettingsTab extends StatelessWidget {
|
||||
),
|
||||
_SettingsEntry(
|
||||
label: t.settingsTab.network.alias,
|
||||
child: TextFieldTv(
|
||||
child: TextFieldWithActions(
|
||||
name: t.settingsTab.network.alias,
|
||||
controller: vm.aliasController,
|
||||
onChanged: (s) async {
|
||||
await ref.notifier(settingsProvider).setAlias(s);
|
||||
},
|
||||
actions: [
|
||||
Tooltip(
|
||||
message: t.settingsTab.network.generateRandomAlias,
|
||||
child: IconButton(
|
||||
onPressed: () async {
|
||||
// Generates random alias
|
||||
final newAlias = generateRandomAlias();
|
||||
|
||||
// Update the TextField with the new alias
|
||||
vm.aliasController.text = newAlias;
|
||||
|
||||
// Persist the new alias using the settingsProvider
|
||||
await ref.notifier(settingsProvider).setAlias(newAlias);
|
||||
},
|
||||
icon: const Icon(Icons.casino),
|
||||
),
|
||||
),
|
||||
Tooltip(
|
||||
message: t.settingsTab.network.useSystemName,
|
||||
child: IconButton(
|
||||
onPressed: () async {
|
||||
// Uses dart.io to find the systems hostname
|
||||
final newAlias = Platform.localHostname;
|
||||
|
||||
vm.aliasController.text = newAlias;
|
||||
await ref.notifier(settingsProvider).setAlias(newAlias);
|
||||
},
|
||||
icon: const Icon(Icons.desktop_windows_rounded),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (vm.advanced)
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:localsend_app/config/theme.dart';
|
||||
import 'package:localsend_app/gen/strings.g.dart';
|
||||
import 'package:routerino/routerino.dart';
|
||||
|
||||
/// A [AlertDialog] on all devices.
|
||||
/// The button opens a dialog box with actions.
|
||||
class TextFieldWithActions extends StatefulWidget {
|
||||
final String name;
|
||||
final TextEditingController controller;
|
||||
final ValueChanged<String> onChanged;
|
||||
final List<Widget> actions;
|
||||
|
||||
const TextFieldWithActions({
|
||||
required this.name,
|
||||
required this.controller,
|
||||
required this.onChanged,
|
||||
required this.actions,
|
||||
});
|
||||
|
||||
@override
|
||||
State<TextFieldWithActions> createState() => _TextFieldWithActionsState();
|
||||
}
|
||||
|
||||
class _TextFieldWithActionsState extends State<TextFieldWithActions> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Theme.of(context).inputDecorationTheme.fillColor,
|
||||
shape: RoundedRectangleBorder(borderRadius: Theme.of(context).inputDecorationTheme.borderRadius),
|
||||
foregroundColor: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
onPressed: () async {
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text(widget.name),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// Display actions inside the dialog
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: widget.actions,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
TextFormField(
|
||||
controller: widget.controller,
|
||||
textAlign: TextAlign.center,
|
||||
onChanged: widget.onChanged,
|
||||
autofocus: true,
|
||||
onFieldSubmitted: (_) => context.pop(),
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||
foregroundColor: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
onPressed: () => context.pop(),
|
||||
child: Text(t.general.confirm),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 5),
|
||||
child: Text(
|
||||
widget.controller.text,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -88,6 +88,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2.2"
|
||||
dio:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dio
|
||||
sha256: "5598aa796bbf4699afd5c67c0f5f6e2ed542afc956884b9cd58c306966efc260"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.7.0"
|
||||
dio_web_adapter:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dio_web_adapter
|
||||
sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -376,6 +392,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
Reference in New Issue
Block a user