Rename top level directories

This commit is contained in:
Elias Projahn 2020-04-24 21:55:17 +02:00
parent 256bda1b72
commit 674ce19414
90 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,59 @@
import 'dart:async';
import 'package:flutter/material.dart';
import '../backend.dart';
class PlayPauseButton extends StatefulWidget {
@override
_PlayPauseButtonState createState() => _PlayPauseButtonState();
}
class _PlayPauseButtonState extends State<PlayPauseButton>
with SingleTickerProviderStateMixin {
AnimationController playPauseAnimation;
BackendState backend;
StreamSubscription<bool> playingSubscription;
@override
void initState() {
super.initState();
playPauseAnimation = AnimationController(
vsync: this,
duration: Duration(milliseconds: 300),
);
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
backend = Backend.of(context);
playPauseAnimation.value = backend.player.playing.value ? 1.0 : 0.0;
if (playingSubscription != null) {
playingSubscription.cancel();
}
playingSubscription = backend.player.playing.listen((playing) =>
playing ? playPauseAnimation.forward() : playPauseAnimation.reverse());
}
@override
Widget build(BuildContext context) {
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.play_pause,
progress: playPauseAnimation,
),
onPressed: backend.player.playPause,
);
}
@override
void dispose() {
super.dispose();
playingSubscription.cancel();
}
}

View file

@ -0,0 +1,83 @@
import 'package:flutter/material.dart';
import 'package:musicus/database.dart';
import '../backend.dart';
import '../music_library.dart';
import '../screens/program.dart';
import 'play_pause_button.dart';
import 'texts.dart';
class PlayerBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
final backend = Backend.of(context);
return BottomAppBar(
child: InkWell(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
StreamBuilder(
stream: backend.player.normalizedPosition,
builder: (context, snapshot) => LinearProgressIndicator(
value: snapshot.data,
),
),
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(Icons.keyboard_arrow_up),
),
Expanded(
child: StreamBuilder<InternalTrack>(
stream: backend.player.currentTrack,
builder: (context, snapshot) {
if (snapshot.data != null) {
final recordingId = snapshot.data.track.recordingId;
return FutureBuilder<Recording>(
future:
backend.db.recordingById(recordingId).getSingle(),
builder: (context, snapshot) {
if (snapshot.hasData) {
final workId = snapshot.data.work;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
DefaultTextStyle.merge(
style:
TextStyle(fontWeight: FontWeight.bold),
child: ComposersText(workId),
),
WorkText(workId),
],
);
} else {
return Container();
}
},
);
} else {
return Container();
}
},
),
),
PlayPauseButton(),
],
),
],
),
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProgramScreen(),
),
),
),
);
}
}

View file

@ -0,0 +1,51 @@
import 'package:flutter/material.dart';
import '../backend.dart';
import '../database.dart';
import 'texts.dart';
class RecordingTile extends StatelessWidget {
final int recordingId;
RecordingTile({
this.recordingId,
});
@override
Widget build(BuildContext context) {
final backend = Backend.of(context);
final textTheme = Theme.of(context).textTheme;
return StreamBuilder<Recording>(
stream: backend.db.recordingById(recordingId).watchSingle(),
builder: (context, snapshot) => Padding(
padding: const EdgeInsets.symmetric(
vertical: 8.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
if (snapshot.hasData) ...[
DefaultTextStyle(
style: textTheme.subtitle1,
child: ComposersText(snapshot.data.work),
),
DefaultTextStyle(
style: textTheme.headline6,
child: WorkText(snapshot.data.work),
),
],
const SizedBox(
height: 4.0,
),
DefaultTextStyle(
style: textTheme.bodyText1,
child: PerformancesText(recordingId),
),
],
),
),
);
}
}

View file

@ -0,0 +1,153 @@
import 'dart:async';
import 'package:flutter/material.dart';
import '../backend.dart';
import '../database.dart';
class EnsembleText extends StatelessWidget {
final int ensembleId;
EnsembleText(this.ensembleId);
@override
Widget build(BuildContext context) {
final backend = Backend.of(context);
return StreamBuilder<Ensemble>(
stream: backend.db.ensembleById(ensembleId).watchSingle(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.name);
} else {
return Container();
}
},
);
}
}
class PersonText extends StatelessWidget {
final int personId;
PersonText(this.personId);
@override
Widget build(BuildContext context) {
final backend = Backend.of(context);
return StreamBuilder<Person>(
stream: backend.db.personById(personId).watchSingle(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text('${snapshot.data.firstName} ${snapshot.data.lastName}');
} else {
return Container();
}
},
);
}
}
class PerformancesText extends StatefulWidget {
final int recordingId;
PerformancesText(this.recordingId);
@override
_PerformancesTextState createState() => _PerformancesTextState();
}
class _PerformancesTextState extends State<PerformancesText> {
BackendState backend;
StreamSubscription<List<Performance>> performancesSubscription;
String text = '...';
@override
void didChangeDependencies() {
super.didChangeDependencies();
performancesSubscription?.cancel();
backend = Backend.of(context);
performancesSubscription = backend.db
.performancesByRecording(widget.recordingId)
.watch()
.listen((performances) async {
final List<String> texts = [];
for (final performance in performances) {
final buffer = StringBuffer();
if (performance.person != null) {
final person =
await backend.db.personById(performance.person).getSingle();
buffer.write('${person.firstName} ${person.lastName}');
} else if (performance.ensemble != null) {
final ensemble =
await backend.db.ensembleById(performance.ensemble).getSingle();
buffer.write(ensemble.name);
} else {
buffer.write('Unknown');
}
if (performance.role != null) {
final role =
await backend.db.instrumentById(performance.role).getSingle();
buffer.write(' (${role.name})');
}
texts.add(buffer.toString());
}
setState(() {
text = texts.join(', ');
});
});
}
@override
Widget build(BuildContext context) {
return Text(text);
}
@override
void dispose() {
super.dispose();
performancesSubscription?.cancel();
}
}
class WorkText extends StatelessWidget {
final int workId;
WorkText(this.workId);
@override
Widget build(BuildContext context) {
final backend = Backend.of(context);
return StreamBuilder<Work>(
stream: backend.db.workById(workId).watchSingle(),
builder: (context, snapshot) => Text(snapshot.data?.title ?? '...'),
);
}
}
class ComposersText extends StatelessWidget {
final int workId;
ComposersText(this.workId);
@override
Widget build(BuildContext context) {
final backend = Backend.of(context);
return StreamBuilder<List<Person>>(
stream: backend.db.composersByWork(workId).watch(),
builder: (context, snapshot) => Text(snapshot.hasData
? snapshot.data.map((p) => '${p.firstName} ${p.lastName}').join(', ')
: '...'),
);
}
}

View file

@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
import '../backend.dart';
import '../database.dart';
class WorksByComposer extends StatelessWidget {
final int personId;
final void Function(Work work) onTap;
WorksByComposer({
this.personId,
this.onTap,
});
@override
Widget build(BuildContext context) {
final backend = Backend.of(context);
return StreamBuilder<List<Work>>(
stream: backend.db.worksByComposer(personId).watch(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
final work = snapshot.data[index];
return ListTile(
title: Text(work.title),
onTap: () => onTap(work),
);
},
);
} else {
return Container();
}
},
);
}
}