2024-04-30 23:38:49 +08:00
|
|
|
import 'package:fl_clash/common/common.dart';
|
|
|
|
|
import 'package:fl_clash/pages/scan.dart';
|
|
|
|
|
import 'package:fl_clash/state.dart';
|
|
|
|
|
import 'package:fl_clash/widgets/widgets.dart';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
|
|
|
|
class AddProfile extends StatelessWidget {
|
|
|
|
|
final BuildContext context;
|
|
|
|
|
|
2024-10-27 16:59:23 +08:00
|
|
|
const AddProfile({
|
|
|
|
|
super.key,
|
|
|
|
|
required this.context,
|
|
|
|
|
});
|
2024-04-30 23:38:49 +08:00
|
|
|
|
|
|
|
|
_handleAddProfileFormFile() async {
|
2024-05-11 17:02:34 +08:00
|
|
|
globalState.appController.addProfileFormFile();
|
2024-04-30 23:38:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_handleAddProfileFormURL(String url) async {
|
2024-05-11 17:02:34 +08:00
|
|
|
globalState.appController.addProfileFormURL(url);
|
2024-04-30 23:38:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_toScan() async {
|
2024-10-27 16:59:23 +08:00
|
|
|
if (system.isDesktop) {
|
2024-05-11 17:02:34 +08:00
|
|
|
globalState.appController.addProfileFormQrCode();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-10-27 16:59:23 +08:00
|
|
|
final url = await BaseNavigator.push(
|
|
|
|
|
context,
|
|
|
|
|
const ScanPage(),
|
|
|
|
|
);
|
2024-04-30 23:38:49 +08:00
|
|
|
if (url != null) {
|
2024-10-27 16:59:23 +08:00
|
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
2024-06-27 17:23:59 +08:00
|
|
|
_handleAddProfileFormURL(url);
|
|
|
|
|
});
|
2024-04-30 23:38:49 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_toAdd() async {
|
|
|
|
|
final url = await globalState.showCommonDialog<String>(
|
|
|
|
|
child: const URLFormDialog(),
|
|
|
|
|
);
|
|
|
|
|
if (url != null) {
|
|
|
|
|
_handleAddProfileFormURL(url);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(context) {
|
|
|
|
|
return ListView(
|
|
|
|
|
children: [
|
2024-10-27 16:59:23 +08:00
|
|
|
ListItem(
|
2025-03-12 17:15:31 +08:00
|
|
|
leading: const Icon(Icons.qr_code_sharp),
|
2024-10-27 16:59:23 +08:00
|
|
|
title: Text(appLocalizations.qrcode),
|
|
|
|
|
subtitle: Text(appLocalizations.qrcodeDesc),
|
|
|
|
|
onTap: _toScan,
|
|
|
|
|
),
|
2024-04-30 23:38:49 +08:00
|
|
|
ListItem(
|
2025-03-12 17:15:31 +08:00
|
|
|
leading: const Icon(Icons.upload_file_sharp),
|
2024-04-30 23:38:49 +08:00
|
|
|
title: Text(appLocalizations.file),
|
|
|
|
|
subtitle: Text(appLocalizations.fileDesc),
|
2024-07-21 21:51:56 +08:00
|
|
|
onTap: _handleAddProfileFormFile,
|
2024-04-30 23:38:49 +08:00
|
|
|
),
|
|
|
|
|
ListItem(
|
2025-03-12 17:15:31 +08:00
|
|
|
leading: const Icon(Icons.cloud_download_sharp),
|
2024-04-30 23:38:49 +08:00
|
|
|
title: Text(appLocalizations.url),
|
|
|
|
|
subtitle: Text(appLocalizations.urlDesc),
|
2024-07-21 21:51:56 +08:00
|
|
|
onTap: _toAdd,
|
2024-04-30 23:38:49 +08:00
|
|
|
)
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class URLFormDialog extends StatefulWidget {
|
|
|
|
|
const URLFormDialog({super.key});
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
State<URLFormDialog> createState() => _URLFormDialogState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _URLFormDialogState extends State<URLFormDialog> {
|
|
|
|
|
final urlController = TextEditingController();
|
|
|
|
|
|
|
|
|
|
_handleAddProfileFormURL() async {
|
|
|
|
|
final url = urlController.value.text;
|
|
|
|
|
if (url.isEmpty) return;
|
|
|
|
|
Navigator.of(context).pop<String>(url);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
2025-03-12 17:15:31 +08:00
|
|
|
return CommonDialog(
|
|
|
|
|
title: appLocalizations.importFromURL,
|
|
|
|
|
actions: [
|
|
|
|
|
TextButton(
|
|
|
|
|
onPressed: _handleAddProfileFormURL,
|
|
|
|
|
child: Text(appLocalizations.submit),
|
|
|
|
|
)
|
|
|
|
|
],
|
|
|
|
|
child: SizedBox(
|
2024-04-30 23:38:49 +08:00
|
|
|
width: 300,
|
|
|
|
|
child: Wrap(
|
|
|
|
|
runSpacing: 16,
|
|
|
|
|
children: [
|
|
|
|
|
TextField(
|
2024-06-27 01:14:45 +08:00
|
|
|
maxLines: 5,
|
|
|
|
|
minLines: 1,
|
2024-04-30 23:38:49 +08:00
|
|
|
controller: urlController,
|
|
|
|
|
decoration: InputDecoration(
|
|
|
|
|
border: const OutlineInputBorder(),
|
|
|
|
|
labelText: appLocalizations.url,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|