Snippet support import/export.

This commit is contained in:
Junyuan Feng
2022-04-07 20:00:06 +08:00
parent fa73c4feee
commit 4274e8bed1
5 changed files with 128 additions and 13 deletions

View File

@@ -35,7 +35,7 @@ class _SnippetEditPageState extends State<SnippetEditPage>
widget.snippet != null
? IconButton(
onPressed: () {
_provider.delInfo(widget.snippet!);
_provider.del(widget.snippet!);
Navigator.of(context).pop();
},
icon: const Icon(Icons.delete))
@@ -71,9 +71,9 @@ class _SnippetEditPageState extends State<SnippetEditPage>
}
final snippet = Snippet(name, script);
if (widget.snippet != null) {
_provider.updateInfo(widget.snippet!, snippet);
_provider.update(widget.snippet!, snippet);
} else {
_provider.addInfo(snippet);
_provider.add(snippet);
}
Navigator.of(context).pop();
},

View File

@@ -1,3 +1,4 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:toolbox/core/route.dart';
@@ -23,12 +24,20 @@ class SnippetListPage extends StatefulWidget {
class _SnippetListPageState extends State<SnippetListPage> {
late ServerPrivateInfo _selectedIndex;
final _importFieldController = TextEditingController();
final _exportFieldController = TextEditingController();
final _textStyle = TextStyle(color: primaryColor);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Snippet List'),
actions: [
IconButton(
onPressed: () => _showImportExport(),
icon: const Icon(Icons.import_export)),
],
),
body: _buildBody(),
floatingActionButton: FloatingActionButton(
@@ -39,6 +48,97 @@ class _SnippetListPageState extends State<SnippetListPage> {
);
}
Future<void> _showImportExport() async {
await showRoundDialog(
context,
'Choose',
Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: const Text('Import'),
leading: const Icon(Icons.download),
onTap: () => _showImportDialog(),
),
ListTile(
title: const Text('Export'),
leading: const Icon(Icons.file_upload),
onTap: () => _showExportDialog(),
),
],
),
[]);
}
Future<void> _showExportDialog() async {
Navigator.of(context).pop();
_exportFieldController.text = locator<SnippetProvider>().export;
await showRoundDialog(
context,
'Export',
TextField(
decoration: const InputDecoration(
labelText: 'JSON',
),
maxLines: 3,
controller: _exportFieldController,
),
[
TextButton(
child: const Text('OK'),
onPressed: () => Navigator.pop(context),
),
]);
}
Future<void> _showImportDialog() async {
Navigator.of(context).pop();
await showRoundDialog(
context,
'Import',
TextField(
decoration: const InputDecoration(
labelText: 'Url or JSON',
),
maxLines: 2,
controller: _importFieldController,
),
[
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('Cancel')),
TextButton(
onPressed: () async =>
await _import(_importFieldController.text.trim()),
child: const Text('GO'),
)
]);
}
Future<void> _import(String text) async {
if (text.isEmpty) {
showSnackBar(context, const Text('field can not be empty'));
return;
}
final snippetProvider = locator<SnippetProvider>();
if (text.startsWith('http')) {
final resp = await Dio().get(text);
if (resp.statusCode != 200) {
showSnackBar(
context, Text('request failed, status code: ${resp.statusCode}'));
return;
}
for (final snippet in getSnippetList(resp.data)) {
snippetProvider.add(snippet);
}
} else {
for (final snippet in getSnippetList(text)) {
snippetProvider.add(snippet);
}
}
Navigator.of(context).pop();
}
Widget _buildBody() {
return Consumer<SnippetProvider>(
builder: (_, key, __) {