Skip to content

Commit d26bbf9

Browse files
committed
#7: Audio plays. TODO: Mantain state of which
1 parent aa19ee5 commit d26bbf9

15 files changed

+141
-48
lines changed

lib/main.dart

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import 'package:audioplayers/audioplayers.dart';
22
import 'package:flutter/material.dart';
33
import 'package:inside_chassidus/data/insideData.dart';
4-
import 'package:inside_chassidus/screens/lesson-screen/index.dart';
5-
import 'package:inside_chassidus/screens/top-lessons.dart';
4+
import 'package:inside_chassidus/routes/lesson-route/index.dart';
5+
import 'package:inside_chassidus/routes/top-lessons.dart';
66
import 'package:provider/provider.dart';
7-
import 'screens/site-section/index.dart';
7+
import 'routes/section-route/index.dart';
88

99
void main() => runApp(Provider<AudioPlayer>.value(
1010
value: AudioPlayer(),
@@ -22,13 +22,13 @@ class MyApp extends StatelessWidget {
2222
WidgetBuilder builder;
2323

2424
switch (settings.name) {
25-
case SiteSectionScreen.routeName:
25+
case SectionRoute.routeName:
2626
final SiteSection routeSection = settings.arguments;
27-
builder = (context) => SiteSectionScreen(section: routeSection);
27+
builder = (context) => SectionRoute(section: routeSection);
2828
break;
29-
case LessonScreen.routeName:
29+
case LessonRoute.routeName:
3030
final Lesson lesson = settings.arguments;
31-
builder = (context) => LessonScreen(lesson: lesson);
31+
builder = (context) => LessonRoute(lesson: lesson);
3232
break;
3333
default:
3434
throw ArgumentError("Unknown route: ${settings.name}");

lib/routes/lesson-route/index.dart

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export 'lesson-route.dart';

lib/screens/lesson-screen/lesson-screen.dart renamed to lib/routes/lesson-route/lesson-route.dart

+9-6
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,21 @@ import 'package:inside_chassidus/widgets/inside-scaffold.dart';
44
import 'package:inside_chassidus/widgets/media-list/index.dart';
55

66
/// Route to display all of the lessons for a given section.
7-
class LessonScreen extends StatelessWidget {
7+
class LessonRoute extends StatelessWidget {
88
static const String routeName = "/lessons";
99

1010
final Lesson lesson;
1111

12-
LessonScreen({this.lesson});
12+
LessonRoute({this.lesson});
1313

1414
@override
1515
Widget build(BuildContext context) => InsideScaffold(
1616
insideData: lesson,
17-
body: Row(children: <Widget>[
18-
if (lesson.description?.isNotEmpty) Text(lesson.description),
19-
MediaList(media: lesson.audio)
20-
]));
17+
body: Padding(
18+
padding: EdgeInsets.symmetric(horizontal: 8).copyWith(top: 8),
19+
child: Column(children: <Widget>[
20+
if (lesson.description?.isNotEmpty) Text(lesson.description),
21+
MediaList(media: lesson.audio)
22+
]),
23+
));
2124
}

lib/routes/section-route/index.dart

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export 'section-route.dart';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:inside_chassidus/data/insideData.dart';
3+
import 'package:inside_chassidus/routes/lesson-route/index.dart';
4+
import 'package:inside_chassidus/routes/section-route/widgets/index.dart';
5+
import 'package:inside_chassidus/widgets/inside-data-retriever.dart';
6+
import 'package:inside_chassidus/widgets/inside-navigator.dart';
7+
import 'package:inside_chassidus/widgets/inside-scaffold.dart';
8+
import 'package:inside_chassidus/widgets/navigate-to-section.dart';
9+
10+
/// Displays contents of a site section. All subsections and lessons.
11+
class SectionRoute extends StatelessWidget {
12+
static const String routeName = "/sections";
13+
14+
final SiteSection section;
15+
16+
SectionRoute({this.section});
17+
18+
@override
19+
Widget build(BuildContext context) => InsideScaffold(
20+
insideData: section,
21+
body: InsideDataRetriever(builder: (context, data) {
22+
final sections = List<SiteSection>.from(data.getSections(section));
23+
final lessons = List<Lesson>.from(data.getLessons(section));
24+
25+
return ListView.builder(
26+
itemCount: sections.length + lessons.length,
27+
itemBuilder: (context, i) {
28+
if (i < sections.length) {
29+
return NavigateToSection(
30+
section: sections[i],
31+
child: InsideDataCard(insideData: sections[i]));
32+
} else {
33+
int adjustedIndex = i - sections.length;
34+
final lesson = lessons[adjustedIndex];
35+
36+
return InsideNavigator(
37+
child: InsideDataCard(insideData: lesson),
38+
routeName: LessonRoute.routeName,
39+
data: lesson,
40+
);
41+
}
42+
},
43+
);
44+
}));
45+
}

lib/screens/site-section/widgets/inside-data-card.dart renamed to lib/routes/section-route/widgets/inside-data-card.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import 'package:expandable/expandable.dart';
22
import 'package:flutter/material.dart';
33
import 'package:inside_chassidus/data/insideData.dart';
4-
import 'package:inside_chassidus/screens/site-section/widgets/informative-text-painter.dart';
4+
import 'package:inside_chassidus/routes/section-route/widgets/informative-text-painter.dart';
55

66
class InsideDataCard extends StatefulWidget {
77
final CountableInsideData insideData;
File renamed without changes.

lib/screens/lesson-screen/index.dart

-1
This file was deleted.

lib/screens/site-section/index.dart

-1
This file was deleted.

lib/screens/site-section/site-section-screen.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import 'package:flutter/material.dart';
22
import 'package:inside_chassidus/data/insideData.dart';
3-
import 'package:inside_chassidus/screens/lesson-screen/index.dart';
4-
import 'package:inside_chassidus/screens/site-section/widgets/index.dart';
3+
import 'package:inside_chassidus/routes/lesson-route/index.dart';
4+
import 'package:inside_chassidus/routes/section-route/widgets/index.dart';
55
import 'package:inside_chassidus/widgets/inside-data-retriever.dart';
66
import 'package:inside_chassidus/widgets/inside-navigator.dart';
77
import 'package:inside_chassidus/widgets/inside-scaffold.dart';
@@ -35,7 +35,7 @@ class SiteSectionScreen extends StatelessWidget {
3535

3636
return InsideNavigator(
3737
child: InsideDataCard(insideData: lesson),
38-
routeName: LessonScreen.routeName,
38+
routeName: LessonRoute.routeName,
3939
data: lesson,
4040
);
4141
}
+28-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import 'package:flutter/material.dart';
2+
import 'package:audioplayers/audioplayers.dart';
23
import 'package:inside_chassidus/data/insideData.dart';
4+
import 'package:provider/provider.dart';
35
import './play-button.dart';
46

57
class MediaList extends StatelessWidget {
@@ -8,16 +10,31 @@ class MediaList extends StatelessWidget {
810
MediaList({this.media});
911

1012
@override
11-
Widget build(BuildContext context) => ListView.builder(
12-
itemCount: this.media.length,
13-
itemBuilder: (context, i) {
14-
var media = this.media[i];
13+
Widget build(BuildContext context) => Expanded(
14+
child: ListView.builder(
15+
itemCount: this.media.length,
16+
itemBuilder: (context, i) {
17+
var media = this.media[i];
18+
String title = media.title;
19+
Text subtitle;
1520

16-
return ListTile(
17-
contentPadding: EdgeInsets.all(4),
18-
title: Text(media.title),
19-
subtitle: Text(media.description, maxLines: 1),
20-
trailing: PlayButton(media: media),
21-
);
22-
});
21+
if (media.description?.isNotEmpty ?? false) {
22+
subtitle = Text(media.description, maxLines: 1);
23+
}
24+
25+
if (title?.isEmpty ?? true) {
26+
title = "Lesson ${i + 1}";
27+
}
28+
29+
return ListTile(
30+
contentPadding: EdgeInsets.all(4),
31+
title: Text(title),
32+
subtitle: subtitle,
33+
trailing: PlayButton(
34+
media: media,
35+
audioPlayer: Provider.of<AudioPlayer>(context),
36+
),
37+
);
38+
}),
39+
);
2340
}
+44-16
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,60 @@
1+
import 'dart:async';
2+
13
import 'package:audioplayers/audioplayers.dart';
24
import 'package:flutter/material.dart';
35
import 'package:inside_chassidus/data/insideData.dart';
46
import 'package:provider/provider.dart';
57

68
class PlayButton extends StatefulWidget {
79
final Media media;
10+
final AudioPlayer audioPlayer;
811

9-
PlayButton({@required this.media});
12+
PlayButton({@required this.media, @required this.audioPlayer});
1013

1114
@override
1215
State<StatefulWidget> createState() => _PlayButtonState();
1316
}
1417

1518
class _PlayButtonState extends State<PlayButton> {
16-
bool isPlaying = false;
19+
bool isPlaying;
20+
StreamSubscription<AudioPlayerState> subscription;
21+
22+
@override void initState() {
23+
super.initState();
24+
25+
subscription = widget.audioPlayer.onPlayerStateChanged.listen(_listenToStateChange);
26+
}
27+
28+
@override void dispose() {
29+
subscription?.cancel();
30+
31+
super.dispose();
32+
}
1733

1834
@override
19-
Widget build(BuildContext context) => GestureDetector(
20-
onTap: () {
21-
this.setState(() => this.isPlaying = !this.isPlaying);
22-
23-
var player = Provider.of<AudioPlayer>(context);
24-
25-
if (this.isPlaying) {
26-
player.play(this.widget.media.source);
27-
} else {
28-
player.pause();
29-
}
30-
},
31-
child: Icon(this.isPlaying ? Icons.pause : Icons.play_arrow));
32-
}
35+
Widget build(BuildContext context) {
36+
isPlaying = widget.audioPlayer.state == AudioPlayerState.PLAYING;
37+
38+
return GestureDetector(
39+
onTap: () {
40+
this.setState(() => this.isPlaying = !this.isPlaying);
41+
42+
var player = Provider.of<AudioPlayer>(context);
43+
44+
if (this.isPlaying) {
45+
player.play(this.widget.media.source);
46+
} else {
47+
player.pause();
48+
}
49+
},
50+
child: Icon(this.isPlaying ? Icons.pause : Icons.play_arrow));
51+
}
52+
53+
_listenToStateChange(AudioPlayerState state) {
54+
bool isPlaying = state == AudioPlayerState.PLAYING;
55+
56+
if (isPlaying != this.isPlaying) {
57+
this.setState(() => this.isPlaying = isPlaying);
58+
}
59+
}
60+
}

lib/widgets/navigate-to-section.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import 'package:flutter/material.dart';
22
import 'package:inside_chassidus/data/insideData.dart';
3-
import 'package:inside_chassidus/screens/site-section/index.dart';
3+
import 'package:inside_chassidus/routes/section-route/index.dart';
44
import 'package:inside_chassidus/widgets/inside-navigator.dart';
55

66
/// Navigates to given section when child is tapped.
77
class NavigateToSection extends InsideNavigator {
88
NavigateToSection({@required Widget child, @required SiteSection section})
9-
: super(child: child, data: section, routeName: SiteSectionScreen.routeName);
9+
: super(child: child, data: section, routeName: SectionRoute.routeName);
1010
}

0 commit comments

Comments
 (0)