import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:git_bindings/git_bindings.dart'; import 'package:gitjournal/setup/screens.dart'; import 'package:gitjournal/setup/sshkey.dart'; import 'package:gitjournal/screens/settings_widgets.dart'; import 'package:gitjournal/settings.dart'; import 'package:gitjournal/state_container.dart'; import 'package:gitjournal/utils.dart'; import 'package:gitjournal/utils/logger.dart'; import 'package:provider/provider.dart'; import 'package:path/path.dart' as p; class GitRemoteSettingsScreen extends StatefulWidget { @override _GitRemoteSettingsScreenState createState() => _GitRemoteSettingsScreenState(); } class _GitRemoteSettingsScreenState extends State { String publicKey = ""; @override void initState() { super.initState(); getSSHPublicKey().then((String val) { if (!mounted) return; setState(() { publicKey = val; }); }); } @override Widget build(BuildContext context) { var textTheme = Theme.of(context).textTheme; var settings = Settings.instance; var body = Column( children: [ Text( "SSH Public Key -", style: textTheme.bodyText1, textAlign: TextAlign.left, ), const SizedBox(height: 16.0), PublicKeyWidget(publicKey), const SizedBox(height: 16.0), const Divider(), Builder( builder: (BuildContext context) => Button( text: "Copy Key", onPressed: () => _copyKeyToClipboard(context), ), ), Builder( builder: (BuildContext context) => Button( text: "Regenerate Key", onPressed: () => _generateSshKey(context), ), ), ListPreference( title: "Sync Frequency", currentOption: settings.remoteSyncFrequency.toPublicString(), options: RemoteSyncFrequency.options .map((f) => f.toPublicString()) .toList(), onChange: (String publicStr) { var val = RemoteSyncFrequency.fromPublicString(publicStr); Settings.instance.remoteSyncFrequency = val; Settings.instance.save(); setState(() {}); }, ), RedButton( text: "Reset Git Host", onPressed: () => _resetGitHost(context), ), ], crossAxisAlignment: CrossAxisAlignment.start, ); return Scaffold( appBar: AppBar( title: Text(tr("settings.gitRemote.title")), leading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: () { Navigator.of(context).pop(); }, ), ), body: Padding( padding: const EdgeInsets.all(16.0), child: body, ), ); } void _copyKeyToClipboard(BuildContext context) { Clipboard.setData(ClipboardData(text: publicKey)); showSnackbar(context, "Public Key copied to Clipboard"); } void _generateSshKey(BuildContext context) { var comment = "GitJournal-" + Platform.operatingSystem + "-" + DateTime.now().toIso8601String().substring(0, 10); // only the date generateSSHKeys(comment: comment).then((String publicKey) { setState(() { this.publicKey = publicKey; Log.d("PublicKey: " + publicKey); _copyKeyToClipboard(context); }); }); } void _resetGitHost(BuildContext context) async { var ok = await showDialog( context: context, builder: (_) => HostChangeConfirmationDialog(), ); if (ok == null) { return; } var stateContainer = Provider.of(context); var gitDir = stateContainer.appState.gitBaseDirectory; // Figure out the next available folder String repoFolderName = "journal_"; var num = 0; while (true) { var repoFolderPath = p.join(gitDir, "$repoFolderName$num"); if (!Directory(repoFolderPath).existsSync()) { break; } num++; } repoFolderName = repoFolderName + num.toString(); var route = MaterialPageRoute( builder: (context) => GitHostSetupScreen( repoFolderName, stateContainer.completeGitHostSetup, ), settings: const RouteSettings(name: '/setupRemoteGit'), ); await Navigator.of(context).push(route); Navigator.of(context).popUntil((route) => route.isFirst); } } class Button extends StatelessWidget { final String text; final Function onPressed; Button({@required this.text, @required this.onPressed}); @override Widget build(BuildContext context) { return SizedBox( width: double.infinity, child: RaisedButton( child: Text( text, textAlign: TextAlign.center, style: Theme.of(context).textTheme.button, ), color: Theme.of(context).primaryColor, onPressed: onPressed, ), ); } } class RedButton extends StatelessWidget { final String text; final Function onPressed; RedButton({@required this.text, @required this.onPressed}); @override Widget build(BuildContext context) { return SizedBox( width: double.infinity, child: RaisedButton( child: Text( text, textAlign: TextAlign.center, style: Theme.of(context).textTheme.button, ), color: Colors.red, onPressed: onPressed, ), ); } } class HostChangeConfirmationDialog extends StatelessWidget { @override Widget build(BuildContext context) { return AlertDialog( title: Text(tr("settings.gitRemote.changeHost.title")), content: Text(tr("settings.gitRemote.changeHost.subtitle")), actions: [ FlatButton( child: Text(tr("settings.gitRemote.changeHost.ok")), onPressed: () => Navigator.of(context).pop(true), ), FlatButton( child: Text(tr("settings.gitRemote.changeHost.cancel")), onPressed: () => Navigator.of(context).pop(), ), ], ); } }