commit 31c13956455a68e1df6f8fadba3b4c40bf891ec9
parent 0ab42680c51605fd221eff8dbab4b08149701b40
Author: Marcel <mtrnord1@gmail.com>
Date: Sun, 23 Feb 2020 20:04:56 +0100
Add basic Profile Page and basic stations list
Took 27 minutes
Diffstat:
7 files changed, 265 insertions(+), 136 deletions(-)
diff --git a/lib/views/HomePage.dart b/lib/views/HomePage.dart
@@ -2,13 +2,14 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:http/http.dart' as http;
-import 'package:rs_flutter_app/views/tabs/rankingsTab.dart';
import '../blocs/MapBloc.dart';
import '../repos/RailwayStationsApiClient.dart';
import '../repos/repositories.dart';
import 'tabs/MapTab.dart';
+import 'tabs/RankingsTab.dart';
import 'tabs/SettingsTab.dart';
+import 'tabs/StationsTab.dart';
class HomePage extends StatelessWidget {
@override
@@ -21,7 +22,8 @@ class HomePage extends StatelessWidget {
);
return DefaultTabController(
- length: 3,
+ length: 4,
+ initialIndex: 3,
child: Scaffold(
bottomNavigationBar: Container(
color: Theme.of(context).primaryColor,
@@ -29,20 +31,36 @@ class HomePage extends StatelessWidget {
labelColor: Colors.white,
unselectedLabelColor: Colors.white70,
indicatorSize: TabBarIndicatorSize.tab,
- indicatorPadding: EdgeInsets.all(5.0),
+ //indicatorPadding: EdgeInsets.all(5.0),
indicatorColor: Theme.of(context).accentColor,
tabs: [
Tab(
- icon: Icon(CupertinoIcons.location),
+ icon: Icon(
+ CupertinoIcons.location,
+ size: 20,
+ ),
text: 'Map',
),
Tab(
- icon: Icon(CupertinoIcons.info),
+ icon: Icon(
+ CupertinoIcons.info,
+ size: 20,
+ ),
text: 'Rangliste',
),
Tab(
- icon: Icon(CupertinoIcons.settings),
- text: 'Einstellungen',
+ icon: Icon(
+ CupertinoIcons.train_style_one,
+ size: 20,
+ ),
+ text: 'Bahnhöfe',
+ ),
+ Tab(
+ icon: Icon(
+ CupertinoIcons.profile_circled,
+ size: 20,
+ ),
+ text: 'Meine Daten',
),
],
),
@@ -70,7 +88,15 @@ class HomePage extends StatelessWidget {
),
Scaffold(
appBar: AppBar(
- title: Text("Einstellungen"),
+ title: Text("Bahnhöfe"),
+ ),
+ body: StationsTab(
+ railwayStationsRepository: railwayStationsRepository,
+ ),
+ ),
+ Scaffold(
+ appBar: AppBar(
+ title: Text("Meine Daten"),
),
body: SettingsTab(),
),
diff --git a/lib/views/tabs/RankingsTab.dart b/lib/views/tabs/RankingsTab.dart
@@ -0,0 +1,101 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import '../../repos/repositories.dart';
+
+class RankingsTab extends StatelessWidget {
+ final RailwayStationsRepository railwayStationsRepository;
+
+ RankingsTab({@required this.railwayStationsRepository})
+ : assert(railwayStationsRepository != null);
+
+ Future<List<List<String>>> getScores() {
+ return this.railwayStationsRepository.getScores();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return FutureBuilder(
+ future: getScores(),
+ builder:
+ (BuildContext context, AsyncSnapshot<List<List<String>>> snapshot) {
+ switch (snapshot.connectionState) {
+ case ConnectionState.done:
+ if (snapshot.hasError) {
+ // TODO handle error
+ debugPrint(snapshot.error.toString());
+ }
+ if (snapshot.hasData) {
+ List<List<String>> scores = snapshot.data;
+ scores.removeAt(0);
+ scores.sort(
+ (a, b) => (int.parse(b.first)).compareTo(int.parse(a.first)),
+ );
+
+ return ListView.separated(
+ itemCount: scores.length,
+ separatorBuilder: (BuildContext context, int index) {
+ return Divider();
+ },
+ itemBuilder: (BuildContext context, int index) {
+ if (index == 0) {
+ return ListTile(
+ leading: SvgPicture.asset(
+ "assets/crown_gold.svg",
+ semanticsLabel: 'Golden Crown',
+ width: 50,
+ height: 50,
+ ),
+ title: Text(scores[index][1]),
+ );
+ } else if (index == 1) {
+ return ListTile(
+ leading: SvgPicture.asset(
+ "assets/crown_silver.svg",
+ semanticsLabel: 'Silver Crown',
+ width: 50,
+ height: 50,
+ ),
+ title: Text(scores[index][1]),
+ );
+ } else if (index == 2) {
+ return ListTile(
+ leading: SvgPicture.asset(
+ "assets/crown_bronze.svg",
+ semanticsLabel: 'Bronze Crown',
+ width: 50,
+ height: 50,
+ ),
+ title: Text(scores[index][1]),
+ );
+ } else {
+ return ListTile(
+ leading: SizedBox(
+ width: 50,
+ height: 50,
+ child: Center(
+ child: Text(
+ "${(index + 1)}.",
+ style: TextStyle(
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ ),
+ ),
+ title: Text(scores[index][1]),
+ );
+ }
+ },
+ );
+ }
+ // TODO handle missing date
+ return Container();
+ default:
+ return Center(
+ child: CircularProgressIndicator(),
+ );
+ }
+ },
+ );
+ }
+}
diff --git a/lib/views/tabs/SettingsTab.dart b/lib/views/tabs/SettingsTab.dart
@@ -1,6 +1,5 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
-import 'package:settings_ui/settings_ui.dart';
class SettingsTab extends StatefulWidget {
@override
@@ -9,30 +8,69 @@ class SettingsTab extends StatefulWidget {
class SettingsTabState extends State<SettingsTab>
with AutomaticKeepAliveClientMixin<SettingsTab> {
+ final _formKey = GlobalKey<FormState>();
+
@override
Widget build(BuildContext context) {
super.build(context);
- return SettingsList(sections: [
- SettingsSection(
- title: 'Bahnhofsdaten',
- tiles: [
- SettingsTile(
- title: 'Länderdaten aktualisieren',
- leading: Icon(Icons.language),
- onTap: () {},
- ),
- ],
- ),
- SettingsSection(
- title: 'Lizensierung',
- tiles: [],
- ),
- SettingsSection(
- title: 'Verlinkung',
- tiles: [],
+ return Padding(
+ padding: EdgeInsets.all(16),
+ child: Form(
+ key: _formKey,
+ child: Column(
+ children: <Widget>[
+ Text("Profil"),
+ TextFormField(
+ decoration: InputDecoration(hintText: "Nickname"),
+ // The validator receives the text that the user has entered.
+ validator: (value) {
+ if (value.isEmpty) {
+ return 'Please enter a nickname';
+ }
+ return null;
+ },
+ ),
+ TextFormField(
+ decoration: InputDecoration(hintText: "E-Mail"),
+ // The validator receives the text that the user has entered.
+ validator: (value) {
+ if (value.isEmpty) {
+ return 'Please enter an E-Mail';
+ }
+ return null;
+ },
+ ),
+ // TODO add checkboxes
+ TextFormField(
+ decoration: InputDecoration(hintText: "Dein Link"),
+ // The validator receives the text that the user has entered.
+ validator: (value) {
+ if (value.isEmpty) {
+ return 'Please enter an E-Mail';
+ }
+ return null;
+ },
+ ),
+ RaisedButton(
+ onPressed: () {
+ // Validate returns true if the form is valid, otherwise false.
+ if (_formKey.currentState.validate()) {
+ // If the form is valid, display a snackbar. In the real world,
+ // you'd often call a server or save the information in a database.
+
+ Scaffold.of(context)
+ .showSnackBar(SnackBar(content: Text('Processing Data')));
+
+ // TODO do stuff
+ }
+ },
+ child: Text('Speichern'),
+ ),
+ ],
+ ),
),
- ]);
+ );
}
@override
diff --git a/lib/views/tabs/StationsTab.dart b/lib/views/tabs/StationsTab.dart
@@ -0,0 +1,71 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+
+import '../../models/models.dart';
+import '../../repos/repositories.dart';
+import '../DetailsPage.dart';
+
+class StationsTab extends StatelessWidget {
+ final RailwayStationsRepository railwayStationsRepository;
+
+ StationsTab({@required this.railwayStationsRepository})
+ : assert(railwayStationsRepository != null);
+
+ Future<List<Station>> getStations() {
+ return this.railwayStationsRepository.getStations();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return FutureBuilder(
+ future: getStations(),
+ builder: (BuildContext context, AsyncSnapshot<List<Station>> snapshot) {
+ switch (snapshot.connectionState) {
+ case ConnectionState.done:
+ if (snapshot.hasError) {
+ // TODO handle error
+ debugPrint(snapshot.error.toString());
+ }
+ if (snapshot.hasData) {
+ List<Station> stations = snapshot.data;
+ stations.sort(
+ (a, b) => (a.title).compareTo(b.title),
+ );
+
+ return ListView.separated(
+ itemCount: stations.length,
+ separatorBuilder: (BuildContext context, int index) {
+ return Divider();
+ },
+ itemBuilder: (BuildContext context, int index) {
+ return ListTile(
+ trailing: stations[index].photoUrl != ""
+ ? Icon(Icons.image)
+ : null,
+ title: Text(stations[index].title),
+ onTap: () {
+ Navigator.of(context).push(
+ MaterialPageRoute(
+ builder: (BuildContext context) => DetailsPage(
+ station: stations[index],
+ railwayStationsRepository:
+ railwayStationsRepository,
+ ),
+ ),
+ );
+ },
+ );
+ },
+ );
+ }
+ // TODO handle missing date
+ return Container();
+ default:
+ return Center(
+ child: CircularProgressIndicator(),
+ );
+ }
+ },
+ );
+ }
+}
diff --git a/lib/views/tabs/rankingsTab.dart b/lib/views/tabs/rankingsTab.dart
@@ -1,99 +0,0 @@
-import 'package:flutter/cupertino.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_svg/flutter_svg.dart';
-import '../../repos/repositories.dart';
-
-class RankingsTab extends StatelessWidget {
- final RailwayStationsRepository railwayStationsRepository;
-
- RankingsTab({@required this.railwayStationsRepository})
- : assert(railwayStationsRepository != null);
-
- Future<List<List<String>>> getScores() {
- return this.railwayStationsRepository.getScores();
- }
-
- @override
- Widget build(BuildContext context) {
- return FutureBuilder(
- future: getScores(),
- builder:
- (BuildContext context, AsyncSnapshot<List<List<String>>> snapshot) {
- switch (snapshot.connectionState) {
- case ConnectionState.done:
- if (snapshot.hasError) {
- // TODO handle error
- debugPrint(snapshot.error.toString());
- }
- if (snapshot.hasData) {
- List<List<String>> scores = snapshot.data;
- scores.removeAt(0);
- scores.sort(
- (a, b) => (int.parse(b.first)).compareTo(int.parse(a.first)),
- );
-
- return ListView.separated(
- itemCount: scores.length,
- separatorBuilder: (BuildContext context, int index) {
- return Divider();
- },
- itemBuilder: (BuildContext context, int index) {
- if (index == 0) {
- return ListTile(
- leading: SvgPicture.asset(
- "assets/crown_gold.svg",
- semanticsLabel: 'Golden Crown',
- width: 50,
- height: 50,
- ),
- title: Text(scores[index][1]),
- );
- } else if (index == 1) {
- return ListTile(
- leading: SvgPicture.asset(
- "assets/crown_silver.svg",
- semanticsLabel: 'Silver Crown',
- width: 50,
- height: 50,
- ),
- title: Text(scores[index][1]),
- );
- } else if (index == 2) {
- return ListTile(
- leading: SvgPicture.asset(
- "assets/crown_bronze.svg",
- semanticsLabel: 'Bronze Crown',
- width: 50,
- height: 50,
- ),
- title: Text(scores[index][1]),
- );
- } else {
- return ListTile(
- leading: SizedBox(
- width: 50,
- height: 50,
- child: Center(
- child: Text(
- "${(index + 1)}.",
- style: TextStyle(
- fontWeight: FontWeight.bold,
- ),
- ),
- ),
- ),
- title: Text(scores[index][1]),
- );
- }
- },
- );
- }
- // TODO handle missing date
- return Container();
- default:
- return CircularProgressIndicator();
- }
- },
- );
- }
-}
diff --git a/pubspec.lock b/pubspec.lock
@@ -474,13 +474,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.23.1"
- settings_ui:
- dependency: "direct main"
- description:
- name: settings_ui
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.2.0"
shelf:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
@@ -31,11 +31,10 @@ dependencies:
flutter_map: ^0.8.2
latlong: ^0.6.1
flutter_map_marker_cluster: ^0.2.7
+
url_launcher: ^5.4.2
maps_launcher: ^1.2.0
- settings_ui: ^0.2.0
-
flutter_cache_manager: ^1.1.3
grizzly_io: ^2.2.0