mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2026-01-31 13:25:10 +01:00
rollback: write script to /dev/shm (#474)
This commit is contained in:
@@ -305,6 +305,8 @@ class BackupPage extends StatelessWidget {
|
||||
final url = TextEditingController(text: Stores.setting.webdavUrl.fetch());
|
||||
final user = TextEditingController(text: Stores.setting.webdavUser.fetch());
|
||||
final pwd = TextEditingController(text: Stores.setting.webdavPwd.fetch());
|
||||
final nodeUser = FocusNode();
|
||||
final nodePwd = FocusNode();
|
||||
final result = await context.showRoundDialog<bool>(
|
||||
title: 'WebDAV',
|
||||
child: Column(
|
||||
@@ -314,14 +316,19 @@ class BackupPage extends StatelessWidget {
|
||||
label: 'URL',
|
||||
hint: 'https://example.com/webdav/',
|
||||
controller: url,
|
||||
onSubmitted: (p0) => FocusScope.of(context).requestFocus(nodeUser),
|
||||
),
|
||||
Input(
|
||||
label: l10n.user,
|
||||
controller: user,
|
||||
node: nodeUser,
|
||||
onSubmitted: (p0) => FocusScope.of(context).requestFocus(nodePwd),
|
||||
),
|
||||
Input(
|
||||
label: l10n.pwd,
|
||||
controller: pwd,
|
||||
node: nodePwd,
|
||||
onSubmitted: (_) => context.pop(true),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -118,32 +118,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
||||
Widget _buildFAB() {
|
||||
return FloatingActionButton(
|
||||
tooltip: l10n.save,
|
||||
onPressed: () async {
|
||||
final name = _nameController.text;
|
||||
final key = _standardizeLineSeparators(_keyController.text.trim());
|
||||
final pwd = _pwdController.text;
|
||||
if (name.isEmpty || key.isEmpty) {
|
||||
context.showSnackBar(l10n.fieldMustNotEmpty);
|
||||
return;
|
||||
}
|
||||
FocusScope.of(context).unfocus();
|
||||
_loading.value = UIs.centerSizedLoading;
|
||||
try {
|
||||
final decrypted = await Computer.shared.start(decyptPem, [key, pwd]);
|
||||
final pki = PrivateKeyInfo(id: name, key: decrypted);
|
||||
if (widget.pki != null) {
|
||||
Pros.key.update(widget.pki!, pki);
|
||||
} else {
|
||||
Pros.key.add(pki);
|
||||
}
|
||||
} catch (e) {
|
||||
context.showSnackBar(e.toString());
|
||||
rethrow;
|
||||
} finally {
|
||||
_loading.value = null;
|
||||
}
|
||||
context.pop();
|
||||
},
|
||||
onPressed: _onTapSave,
|
||||
child: const Icon(Icons.save),
|
||||
);
|
||||
}
|
||||
@@ -206,6 +181,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
||||
obscureText: true,
|
||||
label: l10n.pwd,
|
||||
icon: Icons.password,
|
||||
onSubmitted: (_) => _onTapSave(),
|
||||
),
|
||||
SizedBox(height: MediaQuery.of(context).size.height * 0.1),
|
||||
ValBuilder(
|
||||
@@ -215,4 +191,31 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
void _onTapSave() async {
|
||||
final name = _nameController.text;
|
||||
final key = _standardizeLineSeparators(_keyController.text.trim());
|
||||
final pwd = _pwdController.text;
|
||||
if (name.isEmpty || key.isEmpty) {
|
||||
context.showSnackBar(l10n.fieldMustNotEmpty);
|
||||
return;
|
||||
}
|
||||
FocusScope.of(context).unfocus();
|
||||
_loading.value = UIs.centerSizedLoading;
|
||||
try {
|
||||
final decrypted = await Computer.shared.start(decyptPem, [key, pwd]);
|
||||
final pki = PrivateKeyInfo(id: name, key: decrypted);
|
||||
if (widget.pki != null) {
|
||||
Pros.key.update(widget.pki!, pki);
|
||||
} else {
|
||||
Pros.key.add(pki);
|
||||
}
|
||||
} catch (e) {
|
||||
context.showSnackBar(e.toString());
|
||||
rethrow;
|
||||
} finally {
|
||||
_loading.value = null;
|
||||
}
|
||||
context.pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class _ProcessPageState extends State<ProcessPage> {
|
||||
Future<void> _refresh() async {
|
||||
if (mounted) {
|
||||
final result =
|
||||
await _client?.run(ShellFunc.process.exec(widget.spi.id)).string;
|
||||
await _client?.run(ShellFunc.process.exec).string;
|
||||
if (result == null || result.isEmpty) {
|
||||
context.showSnackBar(l10n.noResult);
|
||||
return;
|
||||
|
||||
@@ -174,6 +174,7 @@ class _ServerEditPageState extends State<ServerEditPage> {
|
||||
|
||||
Widget _buildForm() {
|
||||
final children = [
|
||||
_buildWriteScriptTip(),
|
||||
Input(
|
||||
autoFocus: true,
|
||||
controller: _nameController,
|
||||
@@ -638,4 +639,19 @@ class _ServerEditPageState extends State<ServerEditPage> {
|
||||
|
||||
context.pop();
|
||||
}
|
||||
|
||||
Widget _buildWriteScriptTip() {
|
||||
return ListTile(
|
||||
leading: const Icon(Icons.tips_and_updates).paddingOnly(left: 13),
|
||||
title: Text(l10n.attention),
|
||||
onTap: () {
|
||||
context.showRoundDialog(
|
||||
title: l10n.attention,
|
||||
child: SimpleMarkdown(data: l10n.writeScriptTip),
|
||||
actions: Btns.oks(onTap: () => context.pop(true)),
|
||||
);
|
||||
},
|
||||
trailing: const Icon(Icons.keyboard_arrow_right),
|
||||
).cardx;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ class _ServerPageState extends State<ServerPage>
|
||||
Stores.setting.showSuspendTip.put(false);
|
||||
}
|
||||
srv.client?.execWithPwd(
|
||||
ShellFunc.suspend.exec(srv.id),
|
||||
ShellFunc.suspend.exec,
|
||||
context: context,
|
||||
id: srv.id,
|
||||
);
|
||||
@@ -370,7 +370,7 @@ class _ServerPageState extends State<ServerPage>
|
||||
IconTextBtn(
|
||||
onPressed: () => _askFor(
|
||||
func: () => srv.client?.execWithPwd(
|
||||
ShellFunc.shutdown.exec(srv.id),
|
||||
ShellFunc.shutdown.exec,
|
||||
context: context,
|
||||
id: srv.id,
|
||||
),
|
||||
@@ -383,7 +383,7 @@ class _ServerPageState extends State<ServerPage>
|
||||
IconTextBtn(
|
||||
onPressed: () => _askFor(
|
||||
func: () => srv.client?.execWithPwd(
|
||||
ShellFunc.reboot.exec(srv.id),
|
||||
ShellFunc.reboot.exec,
|
||||
context: context,
|
||||
id: srv.id,
|
||||
),
|
||||
|
||||
@@ -581,6 +581,35 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
void _mkdir() {
|
||||
context.pop();
|
||||
final textController = TextEditingController();
|
||||
|
||||
void onSubmitted() async {
|
||||
if (textController.text.isEmpty) {
|
||||
context.showRoundDialog(
|
||||
child: Text(l10n.fieldMustNotEmpty),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => context.pop(),
|
||||
child: Text(l10n.ok),
|
||||
),
|
||||
],
|
||||
);
|
||||
return;
|
||||
}
|
||||
context.pop();
|
||||
try {
|
||||
await context.showLoadingDialog(
|
||||
fn: () async {
|
||||
final dir = '${_status.path!.path}/${textController.text}';
|
||||
await _status.client!.mkdir(dir);
|
||||
},
|
||||
onErr: (e, s) {},
|
||||
);
|
||||
_listDir();
|
||||
} catch (e, s) {
|
||||
context.showErrDialog(e: e, s: s, operation: l10n.createFolder);
|
||||
}
|
||||
}
|
||||
|
||||
context.showRoundDialog(
|
||||
title: l10n.createFolder,
|
||||
child: Input(
|
||||
@@ -588,6 +617,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
icon: Icons.folder,
|
||||
controller: textController,
|
||||
label: l10n.name,
|
||||
onSubmitted: (_) => onSubmitted(),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
@@ -595,33 +625,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
child: Text(l10n.cancel),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
if (textController.text.isEmpty) {
|
||||
context.showRoundDialog(
|
||||
child: Text(l10n.fieldMustNotEmpty),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => context.pop(),
|
||||
child: Text(l10n.ok),
|
||||
),
|
||||
],
|
||||
);
|
||||
return;
|
||||
}
|
||||
context.pop();
|
||||
try {
|
||||
await context.showLoadingDialog(
|
||||
fn: () async {
|
||||
final dir = '${_status.path!.path}/${textController.text}';
|
||||
await _status.client!.mkdir(dir);
|
||||
},
|
||||
onErr: (e, s) {},
|
||||
);
|
||||
_listDir();
|
||||
} catch (e, s) {
|
||||
context.showErrDialog(e: e, s: s, operation: l10n.createFolder);
|
||||
}
|
||||
},
|
||||
onPressed: onSubmitted,
|
||||
child: Text(l10n.ok, style: UIs.textRed),
|
||||
),
|
||||
],
|
||||
@@ -631,6 +635,36 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
void _newFile() {
|
||||
context.pop();
|
||||
final textController = TextEditingController();
|
||||
|
||||
void onSubmitted() async {
|
||||
if (textController.text.isEmpty) {
|
||||
context.showRoundDialog(
|
||||
title: l10n.attention,
|
||||
child: Text(l10n.fieldMustNotEmpty),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => context.pop(),
|
||||
child: Text(l10n.ok),
|
||||
),
|
||||
],
|
||||
);
|
||||
return;
|
||||
}
|
||||
context.pop();
|
||||
try {
|
||||
await context.showLoadingDialog(
|
||||
fn: () async {
|
||||
final path = '${_status.path!.path}/${textController.text}';
|
||||
await _client!.run('touch "$path"');
|
||||
},
|
||||
onErr: (e, s) {},
|
||||
);
|
||||
_listDir();
|
||||
} catch (e, s) {
|
||||
context.showErrDialog(e: e, s: s, operation: l10n.createFile);
|
||||
}
|
||||
}
|
||||
|
||||
context.showRoundDialog(
|
||||
title: l10n.createFile,
|
||||
child: Input(
|
||||
@@ -638,37 +672,11 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
icon: Icons.insert_drive_file,
|
||||
controller: textController,
|
||||
label: l10n.name,
|
||||
onSubmitted: (_) => onSubmitted(),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
if (textController.text.isEmpty) {
|
||||
context.showRoundDialog(
|
||||
title: l10n.attention,
|
||||
child: Text(l10n.fieldMustNotEmpty),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => context.pop(),
|
||||
child: Text(l10n.ok),
|
||||
),
|
||||
],
|
||||
);
|
||||
return;
|
||||
}
|
||||
context.pop();
|
||||
try {
|
||||
await context.showLoadingDialog(
|
||||
fn: () async {
|
||||
final path = '${_status.path!.path}/${textController.text}';
|
||||
await _client!.run('touch "$path"');
|
||||
},
|
||||
onErr: (e, s) {},
|
||||
);
|
||||
_listDir();
|
||||
} catch (e, s) {
|
||||
context.showErrDialog(e: e, s: s, operation: l10n.createFile);
|
||||
}
|
||||
},
|
||||
onPressed: onSubmitted,
|
||||
child: Text(l10n.ok, style: UIs.textRed),
|
||||
),
|
||||
],
|
||||
@@ -678,6 +686,36 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
void _rename(SftpName file) {
|
||||
context.pop();
|
||||
final textController = TextEditingController(text: file.filename);
|
||||
|
||||
void onSubmitted() async {
|
||||
if (textController.text.isEmpty) {
|
||||
context.showRoundDialog(
|
||||
title: l10n.attention,
|
||||
child: Text(l10n.fieldMustNotEmpty),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => context.pop(),
|
||||
child: Text(l10n.ok),
|
||||
),
|
||||
],
|
||||
);
|
||||
return;
|
||||
}
|
||||
context.pop();
|
||||
try {
|
||||
await context.showLoadingDialog(
|
||||
fn: () async {
|
||||
final newName = textController.text;
|
||||
await _status.client?.rename(file.filename, newName);
|
||||
},
|
||||
onErr: (e, s) {},
|
||||
);
|
||||
_listDir();
|
||||
} catch (e, s) {
|
||||
context.showErrDialog(e: e, s: s, operation: l10n.rename);
|
||||
}
|
||||
}
|
||||
|
||||
context.showRoundDialog(
|
||||
title: l10n.rename,
|
||||
child: Input(
|
||||
@@ -685,38 +723,12 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
icon: Icons.abc,
|
||||
controller: textController,
|
||||
label: l10n.name,
|
||||
onSubmitted: (_) => onSubmitted(),
|
||||
),
|
||||
actions: [
|
||||
TextButton(onPressed: () => context.pop(), child: Text(l10n.cancel)),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
if (textController.text.isEmpty) {
|
||||
context.showRoundDialog(
|
||||
title: l10n.attention,
|
||||
child: Text(l10n.fieldMustNotEmpty),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => context.pop(),
|
||||
child: Text(l10n.ok),
|
||||
),
|
||||
],
|
||||
);
|
||||
return;
|
||||
}
|
||||
context.pop();
|
||||
try {
|
||||
await context.showLoadingDialog(
|
||||
fn: () async {
|
||||
final newName = textController.text;
|
||||
await _status.client?.rename(file.filename, newName);
|
||||
},
|
||||
onErr: (e, s) {},
|
||||
);
|
||||
_listDir();
|
||||
} catch (e, s) {
|
||||
context.showErrDialog(e: e, s: s, operation: l10n.rename);
|
||||
}
|
||||
},
|
||||
onPressed: onSubmitted,
|
||||
child: Text(l10n.rename, style: UIs.textRed),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user