presentation stuff

This commit is contained in:
Moritz Weber 2020-03-28 09:39:59 +01:00
parent 0c66eb006c
commit 72b26274d6
9 changed files with 236 additions and 145 deletions

View file

@ -1,8 +1,15 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_audio_query/flutter_audio_query.dart';
import 'package:mosh/system/datasources/local_music_fetcher.dart';
import 'package:mosh/system/datasources/moor_music_data_source.dart';
import 'package:mosh/system/repositories/music_data_repository_impl.dart';
import 'package:provider/provider.dart';
import 'presentation/pages/home.dart'; import 'presentation/pages/home_page.dart';
import 'presentation/pages/library.dart'; import 'presentation/pages/library_page.dart';
import 'presentation/pages/settings.dart'; import 'presentation/pages/settings_page.dart';
import 'presentation/state/music_store.dart';
import 'presentation/theming.dart';
import 'presentation/widgets/navbar.dart'; import 'presentation/widgets/navbar.dart';
void main() => runApp(MyApp()); void main() => runApp(MyApp());
@ -12,28 +19,23 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
title: 'Flutter Demo', title: 'mosh',
theme: ThemeData( theme: theme(),
// Define the default brightness and colors. home: Provider<MusicStore>(
brightness: Brightness.dark, child: RootPage(),
primaryColor: Colors.amber, create: (BuildContext context) => MusicStore(
accentColor: Colors.amberAccent, MusicDataRepositoryImpl(
// https://api.flutter.dev/flutter/material/TextTheme-class.html localMusicFetcher: LocalMusicFetcherImpl(FlutterAudioQuery()),
textTheme: TextTheme( musicDataSource: MoorMusicDataSource(),
headline: TextStyle(fontSize: 72.0, fontWeight: FontWeight.bold), ),
title: const TextStyle(fontSize: 20.0), //, fontWeight: FontWeight.w300),
body1: const TextStyle(fontSize: 14.0, fontFamily: 'Hind'),
), ),
), ),
home: RootPage(title: 'Flutter Demo Home Page'),
); );
} }
} }
class RootPage extends StatefulWidget { class RootPage extends StatefulWidget {
RootPage({Key key, this.title}) : super(key: key); RootPage({Key key}) : super(key: key);
final String title;
@override @override
_RootPageState createState() => _RootPageState(); _RootPageState createState() => _RootPageState();
@ -42,7 +44,21 @@ class RootPage extends StatefulWidget {
class _RootPageState extends State<RootPage> { class _RootPageState extends State<RootPage> {
var navIndex = 0; var navIndex = 0;
final _pages = <Widget>[HomePage(), LibraryPage(), SettingsPage()]; List<Widget> _pages;
MusicStore _musicStore;
@override
void didChangeDependencies() {
_musicStore = Provider.of<MusicStore>(context);
_musicStore.fetchAlbums();
_pages = <Widget>[
HomePage(),
LibraryPage(store: _musicStore),
SettingsPage(store: _musicStore),
];
super.didChangeDependencies();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mosh/presentation/theming.dart';
import '../widgets/album_art.dart'; import '../widgets/album_art.dart';
import '../widgets/queue_card.dart'; import '../widgets/queue_card.dart';
@ -17,95 +18,98 @@ class _CurrentlyPlayingPageState extends State<CurrentlyPlayingPage> {
return Scaffold( return Scaffold(
body: SafeArea( body: SafeArea(
child: LayoutBuilder( child: LayoutBuilder(
builder: (context, constraints) => Stack(children: [ builder: (BuildContext context, BoxConstraints constraints) => Stack(
Padding( children: <Widget>[
padding: const EdgeInsets.only( Padding(
left: 12.0, padding: const EdgeInsets.only(
right: 12.0, left: 12.0,
top: 8.0, right: 12.0,
), top: 8.0,
child: Column( ),
crossAxisAlignment: CrossAxisAlignment.start, child: Column(
children: [ crossAxisAlignment: CrossAxisAlignment.start,
Row( children: [
children: [ Row(
IconButton(
icon: Icon(Icons.expand_more),
onPressed: () {
Navigator.pop(context);
},
),
IconButton(
icon: Icon(Icons.more_vert),
onPressed: () {},
)
],
mainAxisAlignment: MainAxisAlignment.spaceBetween,
),
Spacer(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: AlbumArt(),
),
Spacer(
flex: 3,
),
Row(
children: [
Icon(
Icons.link,
size: 20.0,
),
Container(
width: 40,
),
Icon(
Icons.favorite,
size: 20.0,
),
Container(
width: 40,
),
Icon(
Icons.remove_circle_outline,
size: 20.0,
),
],
mainAxisAlignment: MainAxisAlignment.center,
),
Container(
height: 24,
),
TimeProgressIndicator(),
Container(
height: 20,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Row(
children: [ children: [
Icon(Icons.repeat, size: 20.0), IconButton(
Icon(Icons.skip_previous, size: 40.0), icon: Icon(Icons.expand_more),
Icon( onPressed: () {
Icons.play_circle_filled, Navigator.pop(context);
size: 64.0, },
), ),
Icon(Icons.skip_next, size: 40.0), IconButton(
Icon(Icons.shuffle, size: 20.0), icon: Icon(Icons.more_vert),
onPressed: () {},
)
], ],
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
), ),
), Spacer(),
Container( Padding(
height: 72, padding: const EdgeInsets.symmetric(horizontal: 16.0),
), child: AlbumArt(),
], ),
Spacer(
flex: 3,
),
Row(
children: [
Icon(
Icons.link,
size: 20.0,
),
Container(
width: 40,
),
Icon(
Icons.favorite,
size: 20.0,
color: RASPBERRY,
),
Container(
width: 40,
),
Icon(
Icons.remove_circle_outline,
size: 20.0,
),
],
mainAxisAlignment: MainAxisAlignment.center,
),
Container(
height: 24,
),
TimeProgressIndicator(),
Container(
height: 20,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Row(
children: [
Icon(Icons.repeat, size: 20.0),
Icon(Icons.skip_previous, size: 40.0),
Icon(
Icons.play_circle_filled,
size: 64.0,
),
Icon(Icons.skip_next, size: 40.0),
Icon(Icons.shuffle, size: 20.0),
],
mainAxisAlignment: MainAxisAlignment.spaceBetween,
),
),
Container(
height: 72,
),
],
),
), ),
), QueueCard(
QueueCard( boxConstraints: constraints,
boxConstraints: constraints, ),
), ],
]), ),
), ),
), ),
); );

View file

@ -1,17 +0,0 @@
import 'package:flutter/material.dart';
class LibraryPage extends StatefulWidget {
LibraryPage({Key key}) : super(key: key);
@override
_LibraryPageState createState() => _LibraryPageState();
}
class _LibraryPageState extends State<LibraryPage> {
@override
Widget build(BuildContext context) {
return Container(
child: Center(child: Text("Library Page"),),
);
}
}

View file

@ -0,0 +1,69 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
import 'package:mosh/domain/entities/album.dart';
import '../state/music_store.dart';
class LibraryPage extends StatelessWidget {
const LibraryPage({Key key, @required this.store}) : super(key: key);
final MusicStore store;
Image getAlbumImage(Album album) {
if (album.albumArtPath == null || !File(album.albumArtPath).existsSync()) {
return Image.asset('assets/no_cover.jpg');
}
return Image.file(File(album.albumArtPath));
}
@override
Widget build(BuildContext context) => Observer(builder: (_) {
final ObservableFuture<List<Album>> future = store.albumsFuture;
switch (future.status) {
case FutureStatus.pending:
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
CircularProgressIndicator(),
Text('Loading items...'),
],
);
case FutureStatus.rejected:
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'Failed to load items.',
style: TextStyle(color: Colors.red),
),
],
);
case FutureStatus.fulfilled:
final List<Album> albums = future.result as List<Album>;
return ListView.builder(
physics: const AlwaysScrollableScrollPhysics(),
itemCount: albums.length,
itemBuilder: (_, index) {
final album = albums[index];
return ListTile(
leading: Card(
child: getAlbumImage(album),
),
title: Text(
'${album.title}, ${album.artist}, ${album.year}',
),
);
},
);
}
return Center(
child: Text('Library Page'),
);
});
}

View file

@ -1,24 +0,0 @@
import 'package:flutter/material.dart';
class SettingsPage extends StatefulWidget {
SettingsPage({Key key}) : super(key: key);
@override
_SettingsPageState createState() => _SettingsPageState();
}
class _SettingsPageState extends State<SettingsPage> {
@override
Widget build(BuildContext context) {
return ListView(
children: [
ListTile(
title: Text("Update database"),
onTap: () {
print("Hello World");
},
)
],
);
}
}

View file

@ -0,0 +1,23 @@
import 'package:flutter/material.dart';
import '../state/music_store.dart';
class SettingsPage extends StatelessWidget {
const SettingsPage({Key key, @required this.store}) : super(key: key);
final MusicStore store;
@override
Widget build(BuildContext context) {
return ListView(
children: [
ListTile(
title: const Text('Update database'),
onTap: () {
store.updateDatabase();
},
)
],
);
}
}

View file

@ -0,0 +1,20 @@
import 'package:flutter/material.dart';
const Color RASPBERRY = Color(0xFFea0367);
const Color TURQUOISE = Color(0xFF30d8f3);
const Color CRAYOLA = Color(0xfffde189);
const Color PINEAPPLE = Color(0xff56365e);
const Color MIDNIGHT = Color(0xff622371);
const Color MIDDLE_RED_PURPLE = Color(0xff0f0127);
ThemeData theme() => ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.amber,
accentColor: Colors.amberAccent,
// https://api.flutter.dev/flutter/material/TextTheme-class.html
textTheme: TextTheme(
headline: TextStyle(fontSize: 72.0, fontWeight: FontWeight.bold),
title: const TextStyle(fontSize: 20.0),
body1: const TextStyle(fontSize: 14.0, fontFamily: 'Hind'),
),
);

View file

@ -10,8 +10,8 @@ class QueueCard extends StatefulWidget {
} }
class _QueueCardState extends State<QueueCard> { class _QueueCardState extends State<QueueCard> {
final title = "Fire"; final title = 'Fire';
final artist = "Beartooth"; final artist = 'Beartooth';
final height = 64.0; final height = 64.0;
bool _first = true; bool _first = true;