Theme update (#23)
This commit is contained in:
parent
ee89f8b6cd
commit
cf90a090e1
Binary file not shown.
Before Width: | Height: | Size: 126 KiB |
|
@ -1,10 +1,8 @@
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:vikunja_app/global.dart';
|
import 'package:vikunja_app/global.dart';
|
||||||
import 'package:vikunja_app/pages/home_page.dart';
|
import 'package:vikunja_app/pages/home_page.dart';
|
||||||
import 'package:vikunja_app/pages/login_page.dart';
|
import 'package:vikunja_app/pages/login_page.dart';
|
||||||
import 'package:vikunja_app/style.dart';
|
import 'package:vikunja_app/theme/theme.dart';
|
||||||
|
|
||||||
void main() => runApp(VikunjaGlobal(
|
void main() => runApp(VikunjaGlobal(
|
||||||
child: new VikunjaApp(home: HomePage()),
|
child: new VikunjaApp(home: HomePage()),
|
||||||
|
|
|
@ -102,7 +102,7 @@ class _ListPageState extends State<ListPage> {
|
||||||
builder: (_) => AddDialog(
|
builder: (_) => AddDialog(
|
||||||
onAdd: _addItem,
|
onAdd: _addItem,
|
||||||
decoration: new InputDecoration(
|
decoration: new InputDecoration(
|
||||||
labelText: 'List Item', hintText: 'eg. Milk')));
|
labelText: 'Task Name', hintText: 'eg. Milk')));
|
||||||
}
|
}
|
||||||
|
|
||||||
_addItem(String name) {
|
_addItem(String name) {
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:vikunja_app/global.dart';
|
import 'package:vikunja_app/global.dart';
|
||||||
import 'package:vikunja_app/pages/register_page.dart';
|
import 'package:vikunja_app/pages/register_page.dart';
|
||||||
|
import 'package:vikunja_app/theme/button.dart';
|
||||||
|
import 'package:vikunja_app/theme/buttonText.dart';
|
||||||
|
import 'package:vikunja_app/theme/constants.dart';
|
||||||
import 'package:vikunja_app/utils/validator.dart';
|
import 'package:vikunja_app/utils/validator.dart';
|
||||||
|
|
||||||
class LoginPage extends StatefulWidget {
|
class LoginPage extends StatefulWidget {
|
||||||
|
@ -30,7 +33,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: vStandardVerticalPadding,
|
||||||
child: Image(
|
child: Image(
|
||||||
image: AssetImage('assets/vikunja_logo.png'),
|
image: AssetImage('assets/vikunja_logo.png'),
|
||||||
height: 128.0,
|
height: 128.0,
|
||||||
|
@ -38,37 +41,40 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.all(8.0),
|
padding: vStandardVerticalPadding,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
onSaved: (serverAddress) => _server = serverAddress,
|
onSaved: (serverAddress) => _server = serverAddress,
|
||||||
validator: (address) {
|
validator: (address) {
|
||||||
return isUrl(address) ? null : 'Invalid URL';
|
return isUrl(address) ? null : 'Invalid URL';
|
||||||
},
|
},
|
||||||
decoration: new InputDecoration(
|
decoration: new InputDecoration(
|
||||||
|
border: OutlineInputBorder(),
|
||||||
labelText: 'Server Address'),
|
labelText: 'Server Address'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: vStandardVerticalPadding,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
onSaved: (username) => _username = username,
|
onSaved: (username) => _username = username,
|
||||||
decoration:
|
decoration:
|
||||||
new InputDecoration(labelText: 'Username'),
|
new InputDecoration(
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
labelText: 'Username'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: vStandardVerticalPadding,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
onSaved: (password) => _password = password,
|
onSaved: (password) => _password = password,
|
||||||
decoration:
|
decoration:
|
||||||
new InputDecoration(labelText: 'Password'),
|
new InputDecoration(
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
labelText: 'Password'),
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Builder(
|
Builder(
|
||||||
builder: (context) => ButtonTheme(
|
builder: (context) => FancyButton(
|
||||||
height: _loading ? 55.0 : 36.0,
|
|
||||||
child: RaisedButton(
|
|
||||||
onPressed: !_loading
|
onPressed: !_loading
|
||||||
? () {
|
? () {
|
||||||
if (_formKey.currentState
|
if (_formKey.currentState
|
||||||
|
@ -80,21 +86,17 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
: null,
|
: null,
|
||||||
child: _loading
|
child: _loading
|
||||||
? CircularProgressIndicator()
|
? CircularProgressIndicator()
|
||||||
: Text('Login'),
|
: VikunjaButtonText('Login'),
|
||||||
))),
|
)),
|
||||||
Builder(
|
Builder(
|
||||||
builder: (context) => ButtonTheme(
|
builder: (context) => FancyButton(
|
||||||
height: _loading ? 55.0 : 36.0,
|
|
||||||
child: RaisedButton(
|
|
||||||
onPressed: () => Navigator.push(
|
onPressed: () => Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
RegisterPage())),
|
RegisterPage())),
|
||||||
child: _loading
|
child: VikunjaButtonText('Register'),
|
||||||
? CircularProgressIndicator()
|
)),
|
||||||
: Text('Register'),
|
|
||||||
))),
|
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:vikunja_app/global.dart';
|
import 'package:vikunja_app/global.dart';
|
||||||
|
import 'package:vikunja_app/theme/button.dart';
|
||||||
|
import 'package:vikunja_app/theme/buttonText.dart';
|
||||||
|
import 'package:vikunja_app/theme/constants.dart';
|
||||||
import 'package:vikunja_app/utils/validator.dart';
|
import 'package:vikunja_app/utils/validator.dart';
|
||||||
|
|
||||||
class RegisterPage extends StatefulWidget {
|
class RegisterPage extends StatefulWidget {
|
||||||
|
@ -29,7 +32,7 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: vStandardVerticalPadding,
|
||||||
child: Image(
|
child: Image(
|
||||||
image: AssetImage('assets/vikunja_logo.png'),
|
image: AssetImage('assets/vikunja_logo.png'),
|
||||||
height: 128.0,
|
height: 128.0,
|
||||||
|
@ -37,18 +40,19 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.all(8.0),
|
padding: vStandardVerticalPadding,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
onSaved: (serverAddress) => _server = serverAddress,
|
onSaved: (serverAddress) => _server = serverAddress,
|
||||||
validator: (address) {
|
validator: (address) {
|
||||||
return isUrl(address) ? null : 'Invalid URL';
|
return isUrl(address) ? null : 'Invalid URL';
|
||||||
},
|
},
|
||||||
decoration: new InputDecoration(
|
decoration: new InputDecoration(
|
||||||
|
border: OutlineInputBorder(),
|
||||||
labelText: 'Server Address'),
|
labelText: 'Server Address'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: vStandardVerticalPadding,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
onSaved: (username) => _username = username.trim(),
|
onSaved: (username) => _username = username.trim(),
|
||||||
validator: (username) {
|
validator: (username) {
|
||||||
|
@ -56,12 +60,13 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||||
? null
|
? null
|
||||||
: 'Please specify a username';
|
: 'Please specify a username';
|
||||||
},
|
},
|
||||||
decoration:
|
decoration: new InputDecoration(
|
||||||
new InputDecoration(labelText: 'Username'),
|
border: OutlineInputBorder(),
|
||||||
|
labelText: 'Username'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: vStandardVerticalPadding,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
onSaved: (email) => _email = email,
|
onSaved: (email) => _email = email,
|
||||||
validator: (email) {
|
validator: (email) {
|
||||||
|
@ -69,12 +74,13 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||||
? null
|
? null
|
||||||
: 'Email adress is invalid';
|
: 'Email adress is invalid';
|
||||||
},
|
},
|
||||||
decoration:
|
decoration: new InputDecoration(
|
||||||
new InputDecoration(labelText: 'Email Address'),
|
border: OutlineInputBorder(),
|
||||||
|
labelText: 'Email Address'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: vStandardVerticalPadding,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
controller: passwordController,
|
controller: passwordController,
|
||||||
onSaved: (password) => _password = password,
|
onSaved: (password) => _password = password,
|
||||||
|
@ -83,13 +89,14 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||||
? null
|
? null
|
||||||
: 'Please use at least 8 characters';
|
: 'Please use at least 8 characters';
|
||||||
},
|
},
|
||||||
decoration:
|
decoration: new InputDecoration(
|
||||||
new InputDecoration(labelText: 'Password'),
|
border: OutlineInputBorder(),
|
||||||
|
labelText: 'Password'),
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: vStandardVerticalPadding,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
validator: (password) {
|
validator: (password) {
|
||||||
return passwordController.text == password
|
return passwordController.text == password
|
||||||
|
@ -97,14 +104,13 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||||
: 'Passwords don\'t match.';
|
: 'Passwords don\'t match.';
|
||||||
},
|
},
|
||||||
decoration: new InputDecoration(
|
decoration: new InputDecoration(
|
||||||
|
border: OutlineInputBorder(),
|
||||||
labelText: 'Repeat Password'),
|
labelText: 'Repeat Password'),
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Builder(
|
Builder(
|
||||||
builder: (context) => ButtonTheme(
|
builder: (context) => FancyButton(
|
||||||
height: _loading ? 55.0 : 36.0,
|
|
||||||
child: RaisedButton(
|
|
||||||
onPressed: !_loading
|
onPressed: !_loading
|
||||||
? () {
|
? () {
|
||||||
if (_formKey.currentState
|
if (_formKey.currentState
|
||||||
|
@ -118,8 +124,8 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||||
: null,
|
: null,
|
||||||
child: _loading
|
child: _loading
|
||||||
? CircularProgressIndicator()
|
? CircularProgressIndicator()
|
||||||
: Text('Register'),
|
: VikunjaButtonText('Register'),
|
||||||
))),
|
)),
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
const vBlue = Color(0xFF455486);
|
|
||||||
const vBlueLight = Color(0xFF7480b7);
|
|
||||||
const vBlueDark = Color(0xFF152c5a);
|
|
||||||
const vBlack = Color(0xFFFFFFFF);
|
|
||||||
|
|
||||||
ThemeData buildVikunjaTheme() {
|
|
||||||
var base = ThemeData.light();
|
|
||||||
return base.copyWith(
|
|
||||||
primaryColor: vBlue,
|
|
||||||
primaryColorLight: vBlueLight,
|
|
||||||
primaryColorDark: vBlueDark,
|
|
||||||
textTheme: base.textTheme.copyWith(
|
|
||||||
headline: base.textTheme.headline.copyWith(
|
|
||||||
fontFamily: 'Quicksand',
|
|
||||||
fontSize: 72.0,
|
|
||||||
),
|
|
||||||
title: base.textTheme.title.copyWith(
|
|
||||||
fontFamily: 'Quicksand',
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
43
lib/theme/button.dart
Normal file
43
lib/theme/button.dart
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:vikunja_app/theme/constants.dart';
|
||||||
|
|
||||||
|
class FancyButton extends StatelessWidget {
|
||||||
|
final double width;
|
||||||
|
final double height;
|
||||||
|
final Function onPressed;
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
const FancyButton({
|
||||||
|
Key key,
|
||||||
|
@required this.child,
|
||||||
|
this.width = double.infinity,
|
||||||
|
this.height = 35,
|
||||||
|
this.onPressed,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: vStandardVerticalPadding,
|
||||||
|
child: Container(
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
decoration: BoxDecoration(boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: vButtonShadow,
|
||||||
|
offset: Offset(-5, 5),
|
||||||
|
blurRadius: 10,
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
child: Material(
|
||||||
|
borderRadius: BorderRadius.circular(3),
|
||||||
|
color: vButtonColor,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: onPressed,
|
||||||
|
child: Center(
|
||||||
|
child: child,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
19
lib/theme/buttonText.dart
Normal file
19
lib/theme/buttonText.dart
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:vikunja_app/theme/constants.dart';
|
||||||
|
|
||||||
|
class VikunjaButtonText extends StatelessWidget {
|
||||||
|
final String text;
|
||||||
|
|
||||||
|
const VikunjaButtonText(
|
||||||
|
this.text, {
|
||||||
|
Key key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Text(
|
||||||
|
text,
|
||||||
|
style: TextStyle(color: vButtonTextColor, fontWeight: FontWeight.w600),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
25
lib/theme/constants.dart
Normal file
25
lib/theme/constants.dart
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/////////
|
||||||
|
// Colors
|
||||||
|
//////
|
||||||
|
const vBlue = Color(0xFF7F23FF);
|
||||||
|
const vBlueLight = Color(0xFF7480b7);
|
||||||
|
const vBlueDark = Color(0xFF152c5a);
|
||||||
|
const vPrimary = Color(0xFF0c86ff);
|
||||||
|
const vPrimaryDark = Color(0xFF1A73E8);
|
||||||
|
const vRed = Color(0xFFff4136);
|
||||||
|
const vOrange = Color(0xFFff851b);
|
||||||
|
const vWhite = Color(0xFFffffff);
|
||||||
|
const vGreen = Color(0xFF00CE6E);
|
||||||
|
|
||||||
|
const vButtonColor = vPrimary;
|
||||||
|
const vButtonTextColor = vWhite;
|
||||||
|
const vButtonShadow = Color(0xFFb2d9ff);
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// Paddings
|
||||||
|
////////
|
||||||
|
const vStandardVerticalPadding = EdgeInsets.symmetric(vertical: 5.0);
|
||||||
|
const vStandardHorizontalPadding = EdgeInsets.symmetric(horizontal: 5.0);
|
||||||
|
const vStandardPadding = EdgeInsets.symmetric(horizontal: 5.0, vertical: 5.0);
|
37
lib/theme/fancyAppBar.dart
Normal file
37
lib/theme/fancyAppBar.dart
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class FancyAppBar extends StatelessWidget {
|
||||||
|
final String title;
|
||||||
|
final double barHeight = 80.0;
|
||||||
|
|
||||||
|
FancyAppBar(this.title);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return new Container(
|
||||||
|
height: barHeight,
|
||||||
|
width: double.infinity,
|
||||||
|
decoration: new BoxDecoration(color: Colors.blue),
|
||||||
|
child: new Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 38, horizontal: 10),
|
||||||
|
child: new Text(title,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontFamily: 'Quicksand',
|
||||||
|
fontSize: 21)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Usage:
|
||||||
|
return new Scaffold(
|
||||||
|
body: new Column(
|
||||||
|
children: <Widget>[
|
||||||
|
new FancyAppBar('Login to Vikunja'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
*/
|
34
lib/theme/theme.dart
Normal file
34
lib/theme/theme.dart
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:vikunja_app/theme/constants.dart';
|
||||||
|
|
||||||
|
ThemeData buildVikunjaTheme() {
|
||||||
|
var base = ThemeData.light();
|
||||||
|
return base.copyWith(
|
||||||
|
errorColor: vRed,
|
||||||
|
primaryColor: vPrimaryDark,
|
||||||
|
primaryColorLight: vPrimary,
|
||||||
|
primaryColorDark: vBlueDark,
|
||||||
|
buttonTheme: base.buttonTheme.copyWith(
|
||||||
|
buttonColor: vPrimary,
|
||||||
|
textTheme: ButtonTextTheme.normal,
|
||||||
|
colorScheme: base.buttonTheme.colorScheme.copyWith(
|
||||||
|
// Why does this not work?
|
||||||
|
onSurface: vWhite,
|
||||||
|
onSecondary: vWhite,
|
||||||
|
background: vBlue,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
textTheme: base.textTheme.copyWith(
|
||||||
|
headline: base.textTheme.headline.copyWith(
|
||||||
|
fontFamily: 'Quicksand',
|
||||||
|
),
|
||||||
|
title: base.textTheme.title.copyWith(
|
||||||
|
fontFamily: 'Quicksand',
|
||||||
|
),
|
||||||
|
button: base.textTheme.button.copyWith(
|
||||||
|
color:
|
||||||
|
vWhite, // This does not work, looks like a bug in Flutter: https://github.com/flutter/flutter/issues/19623
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
|
@ -32,7 +32,6 @@ flutter_icons:
|
||||||
flutter:
|
flutter:
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
assets:
|
assets:
|
||||||
- assets/graphics/background.jpg
|
|
||||||
- assets/graphics/hypnotize.png
|
- assets/graphics/hypnotize.png
|
||||||
- assets/vikunja_logo.png
|
- assets/vikunja_logo.png
|
||||||
fonts:
|
fonts:
|
||||||
|
|
Reference in New Issue
Block a user