mirror of
https://github.com/mitchell/selfpass.git
synced 2025-12-15 13:47:21 +00:00
Added repositories using provider package
This commit is contained in:
parent
cad969d98c
commit
d0505a4a58
30 changed files with 1539 additions and 63 deletions
|
|
@ -1,4 +1,9 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../types/abstracts.dart';
|
||||
|
||||
import '../widgets/obfuscated_text_field.dart';
|
||||
|
||||
class Authentication extends StatefulWidget {
|
||||
@override
|
||||
|
|
@ -6,42 +11,58 @@ class Authentication extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _AuthenticationState extends State<Authentication> {
|
||||
static const String _masterpass = 'hunter#2';
|
||||
bool _invalid = false;
|
||||
bool _passesDontMatch = false;
|
||||
String _masterpass;
|
||||
ConfigRepo _config;
|
||||
Future<bool> _passwordIsSet;
|
||||
|
||||
@override
|
||||
didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
_config = Provider.of<ConfigRepo>(context);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_passwordIsSet == null) {
|
||||
_passwordIsSet = _config.passwordSet;
|
||||
}
|
||||
|
||||
return CupertinoPageScaffold(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 50.0),
|
||||
child: Column(
|
||||
children: _buildColumnChildren(context),
|
||||
child: FutureBuilder<bool>(
|
||||
future: _passwordIsSet,
|
||||
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) =>
|
||||
snapshot.connectionState == ConnectionState.done
|
||||
? Column(children: _buildColumnChildren(snapshot.data))
|
||||
: Container(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _buildColumnChildren(BuildContext context) {
|
||||
final children = [
|
||||
List<Widget> _buildColumnChildren(bool passwordIsSet) {
|
||||
List<Widget> children = [
|
||||
const Spacer(flex: 4),
|
||||
const Flexible(child: Text('Master password:')),
|
||||
Flexible(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 5.0),
|
||||
child: CupertinoTextField(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: CupertinoColors.black),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(5.0)),
|
||||
),
|
||||
clearButtonMode: OverlayVisibilityMode.editing,
|
||||
textAlign: TextAlign.center,
|
||||
onSubmitted: _makeTextFieldOnSubmittedHandler(context),
|
||||
obscureText: true,
|
||||
),
|
||||
),
|
||||
child: ObfuscatedTextField(
|
||||
onSubmittedBuilder:
|
||||
_buildMasterpassSubmittedBuilder(passwordIsSet)),
|
||||
),
|
||||
];
|
||||
|
||||
if (!passwordIsSet) {
|
||||
children.add(const Flexible(child: Text('Re-enter password:')));
|
||||
children.add(Flexible(
|
||||
child: ObfuscatedTextField(
|
||||
onSubmittedBuilder:
|
||||
_buildConfirmPassSubmittedBuilder(passwordIsSet)),
|
||||
));
|
||||
}
|
||||
|
||||
if (_invalid) {
|
||||
children.add(const Flexible(
|
||||
child: Text(
|
||||
|
|
@ -49,6 +70,20 @@ class _AuthenticationState extends State<Authentication> {
|
|||
style: TextStyle(color: CupertinoColors.destructiveRed),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
if (_passesDontMatch) {
|
||||
children.add(const Flexible(
|
||||
child: Text(
|
||||
'passwords don\'t match',
|
||||
style: TextStyle(color: CupertinoColors.destructiveRed),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
if (_passesDontMatch) {
|
||||
children.add(const Spacer(flex: 1));
|
||||
} else if (_invalid || !passwordIsSet) {
|
||||
children.add(const Spacer(flex: 2));
|
||||
} else {
|
||||
children.add(const Spacer(flex: 3));
|
||||
|
|
@ -57,16 +92,40 @@ class _AuthenticationState extends State<Authentication> {
|
|||
return children;
|
||||
}
|
||||
|
||||
ValueChanged<String> _makeTextFieldOnSubmittedHandler(BuildContext context) {
|
||||
return (String pass) {
|
||||
if (pass != _masterpass) {
|
||||
this.setState(() {
|
||||
_invalid = true;
|
||||
});
|
||||
return;
|
||||
}
|
||||
OnSubmittedBuilder _buildMasterpassSubmittedBuilder(bool passwordIsSet) {
|
||||
return (BuildContext context) {
|
||||
return (String pass) async {
|
||||
if (passwordIsSet) {
|
||||
if (await _config.matchesPasswordHash(pass)) {
|
||||
Navigator.of(context).pushReplacementNamed('/home',
|
||||
arguments: await _config.connectionConfig);
|
||||
return;
|
||||
}
|
||||
|
||||
Navigator.of(context).pushReplacementNamed('/home');
|
||||
this.setState(() => _invalid = true);
|
||||
return;
|
||||
}
|
||||
|
||||
_masterpass = pass;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
OnSubmittedBuilder _buildConfirmPassSubmittedBuilder(bool passwordIsSet) {
|
||||
return (BuildContext context) {
|
||||
return (String pass) async {
|
||||
if (pass != _masterpass) {
|
||||
this.setState(() {
|
||||
_passesDontMatch = true;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
_config.setPassword(_masterpass);
|
||||
_passwordIsSet = Future<bool>.value(true);
|
||||
Navigator.of(context).pushReplacementNamed('/home',
|
||||
arguments: await _config.connectionConfig);
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,29 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
import '../types/credential.dart';
|
||||
|
||||
import '../widgets/tappable_text_list.dart';
|
||||
|
||||
class Credentials extends StatelessWidget {
|
||||
final List<Metadata> metadatas;
|
||||
|
||||
const Credentials(this.metadatas);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
child: TappableTextList(tappableText: _buildTappableText(context)),
|
||||
navigationBar: const CupertinoNavigationBar(middle: Text('Credentials')),
|
||||
navigationBar: CupertinoNavigationBar(),
|
||||
);
|
||||
}
|
||||
|
||||
static Map<String, GestureTapCallback> _buildTappableText(
|
||||
BuildContext context) {
|
||||
Map<String, GestureTapCallback> _buildTappableText(BuildContext context) {
|
||||
var handleOnTap = () {};
|
||||
|
||||
Map<String, GestureTapCallback> tappableText = {
|
||||
'm@mjfs.us': handleOnTap,
|
||||
'm-mjfs': handleOnTap,
|
||||
'mitchelljfsimon@gmail.com-mitchelljfsimon': handleOnTap,
|
||||
};
|
||||
Map<String, GestureTapCallback> tappableText = {};
|
||||
|
||||
metadatas.forEach(
|
||||
(Metadata metadata) => tappableText[metadata.id] = handleOnTap);
|
||||
|
||||
return tappableText;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,71 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
// import 'package:provider/provider.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../types/abstracts.dart';
|
||||
import '../types/credential.dart';
|
||||
|
||||
// import '../types/abstracts.dart';
|
||||
// import '../types/credential.dart';
|
||||
import '../widgets/tappable_text_list.dart';
|
||||
|
||||
class Home extends StatelessWidget {
|
||||
class Home extends StatefulWidget {
|
||||
@override
|
||||
State createState() => _HomeState();
|
||||
}
|
||||
|
||||
class _HomeState extends State<Home> {
|
||||
CredentialsRepo _client;
|
||||
Future<List<Metadata>> _metadatas;
|
||||
|
||||
@override
|
||||
didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
_client = Provider.of<CredentialsRepo>(context);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_metadatas == null) {
|
||||
_metadatas = _client.getAllMetadata('').toList();
|
||||
}
|
||||
|
||||
return CupertinoPageScaffold(
|
||||
child: TappableTextList(tappableText: _buildTappableText(context)),
|
||||
navigationBar:
|
||||
const CupertinoNavigationBar(middle: Text('Credentials Hosts')),
|
||||
child: FutureBuilder<List<Metadata>>(
|
||||
future: _metadatas,
|
||||
builder: (BuildContext context,
|
||||
AsyncSnapshot<List<Metadata>> snapshot) =>
|
||||
(snapshot.connectionState == ConnectionState.done)
|
||||
? TappableTextList(
|
||||
tappableText: _buildTappableText(context, snapshot.data))
|
||||
: Container(),
|
||||
),
|
||||
navigationBar: CupertinoNavigationBar(),
|
||||
);
|
||||
}
|
||||
|
||||
static Map<String, GestureTapCallback> _buildTappableText(
|
||||
BuildContext context) {
|
||||
var handleOnTap = () => Navigator.of(context).pushNamed('/credentials');
|
||||
Map<String, GestureTapCallback> tappableText = {
|
||||
"google.com": handleOnTap,
|
||||
"amazon.com": handleOnTap,
|
||||
"linkedin.com": handleOnTap,
|
||||
};
|
||||
Map<String, GestureTapCallback> _buildTappableText(
|
||||
BuildContext context,
|
||||
List<Metadata> metadatas,
|
||||
) {
|
||||
final Map<String, List<Metadata>> metaMap = {};
|
||||
|
||||
metadatas.sort((a, b) => a.id.compareTo(b.id));
|
||||
|
||||
for (var metadata in metadatas) {
|
||||
final source = metadata.sourceHost;
|
||||
|
||||
if (metaMap[source] == null) {
|
||||
metaMap[source] = [metadata];
|
||||
} else {
|
||||
metaMap[source].add(metadata);
|
||||
}
|
||||
}
|
||||
|
||||
final handleOnTap = (List<Metadata> metadatas) => () =>
|
||||
Navigator.of(context).pushNamed('/credentials', arguments: metadatas);
|
||||
|
||||
final Map<String, GestureTapCallback> tappableText = {};
|
||||
|
||||
metaMap.forEach((String key, List<Metadata> value) =>
|
||||
tappableText[key] = handleOnTap(value));
|
||||
|
||||
return tappableText;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue