mobile: Update to new client API

The settings screen was refactored too.
This commit is contained in:
Elias Projahn 2020-05-01 17:48:23 +02:00
parent 4f7a99d2a1
commit 820ff7eadb
11 changed files with 286 additions and 163 deletions

View file

@ -49,8 +49,8 @@ class HomeScreen extends StatelessWidget {
),
],
),
body: StreamBuilder<List<Person>>(
stream: backend.db.allPersons().watch(),
body: FutureBuilder<List<Person>>(
future: backend.db.getPersons(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(

View file

@ -37,14 +37,15 @@ class PersonScreen extends StatelessWidget {
),
],
),
body: StreamBuilder<List<Work>>(
stream: backend.db.worksByComposer(person.id).watch(),
body: FutureBuilder<List<WorkInfo>>(
future: backend.db.getWorks(person.id),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
final work = snapshot.data[index];
final work = snapshot.data[index].work;
return ListTile(
title: Text(work.title),
onTap: () async {

View file

@ -0,0 +1,110 @@
import 'dart:async';
import 'package:flutter/material.dart';
import '../backend.dart';
import '../settings.dart';
class ServerSettingsScreen extends StatefulWidget {
@override
_ServerSettingsScreenState createState() => _ServerSettingsScreenState();
}
class _ServerSettingsScreenState extends State<ServerSettingsScreen> {
final hostController = TextEditingController();
final portController = TextEditingController();
final basePathController = TextEditingController();
BackendState backend;
StreamSubscription<ServerSettings> serverSubscription;
@override
void didChangeDependencies() {
super.didChangeDependencies();
backend = Backend.of(context);
if (serverSubscription != null) {
serverSubscription.cancel();
}
_settingsChanged(backend.settings.server.value);
serverSubscription = backend.settings.server.listen((settings) {
_settingsChanged(settings);
});
}
void _settingsChanged(ServerSettings settings) {
hostController.text = settings.host;
portController.text = settings.port.toString();
basePathController.text = settings.basePath;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Server settings'),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.restore),
tooltip: 'Reset to default',
onPressed: () {
backend.settings.resetServerSettings();
},
),
FlatButton(
onPressed: () async {
await backend.settings.setServerSettings(ServerSettings(
host: hostController.text,
port: int.parse(portController.text),
basePath: basePathController.text,
));
Navigator.pop(context);
},
child: Text('DONE'),
),
],
),
body: ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
controller: hostController,
decoration: InputDecoration(
labelText: 'Host',
),
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
controller: portController,
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Port',
),
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
controller: basePathController,
decoration: InputDecoration(
labelText: 'API path',
),
),
),
],
),
);
}
@override
void dispose() {
super.dispose();
serverSubscription.cancel();
}
}

View file

@ -1,11 +1,15 @@
import 'package:flutter/material.dart';
import '../backend.dart';
import '../settings.dart';
import 'server_settings.dart';
class SettingsScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final backend = Backend.of(context);
final settings = backend.settings;
return Scaffold(
appBar: AppBar(
@ -13,60 +17,42 @@ class SettingsScreen extends StatelessWidget {
),
body: ListView(
children: <Widget>[
ListTile(
leading: Icon(Icons.library_music),
title: Text('Music library path'),
subtitle: Text(backend.musicLibraryUri),
onTap: () {
backend.chooseMusicLibraryUri();
},
),
StreamBuilder<String>(
stream: backend.musicusServerUrl,
builder: (context, snapshot) {
return ListTile(
leading: Icon(Icons.router),
title: Text('Musicus server'),
subtitle: Text(snapshot.data ?? 'Set server URL'),
onTap: () {
showDialog(
context: context,
builder: (context) {
final controller = TextEditingController();
stream: settings.musicLibraryUri,
builder: (context, snapshot) {
return ListTile(
title: Text('Music library path'),
subtitle: Text(snapshot.data ?? 'Choose folder'),
isThreeLine: snapshot.hasData,
onTap: () {
settings.chooseMusicLibraryUri();
},
);
}),
StreamBuilder<ServerSettings>(
stream: settings.server,
builder: (context, snapshot) {
final s = snapshot.data;
if (snapshot.data != null) {
controller.text = snapshot.data;
}
return ListTile(
title: Text('Musicus server'),
subtitle: Text(
s != null ? '${s.host}:${s.port}${s.basePath}' : '...'),
trailing: const Icon(Icons.chevron_right),
onTap: () async {
final ServerSettings result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ServerSettingsScreen(),
),
);
return AlertDialog(
title: Text('Musicus server'),
content: TextField(
controller: controller,
decoration: InputDecoration(
labelText: 'Server URL',
),
),
actions: <Widget>[
FlatButton(
onPressed: () {
backend.setMusicusServer(controller.text);
Navigator.pop(context);
},
child: Text('SET'),
),
FlatButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('CANCEL'),
),
],
);
});
},
);
}
),
if (result != null) {
settings.setServerSettings(result);
}
},
);
}),
],
),
);

View file

@ -36,33 +36,25 @@ class WorkScreen extends StatelessWidget {
),
],
),
body: StreamBuilder<List<Recording>>(
stream: backend.db.recordingsByWork(workInfo.work.id).watch(),
body: FutureBuilder<List<RecordingInfo>>(
future: backend.db.getRecordings(workInfo.work.id),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
final recording = snapshot.data[index];
final recordingInfo = snapshot.data[index];
final recording = recordingInfo.recording;
return ListTile(
title: FutureBuilder<RecordingInfo>(
future: backend.db.getRecordingInfo(recording),
builder: (context, snapshot) {
if (snapshot.hasData) {
return PerformancesText(
performanceInfos: snapshot.data.performances,
);
} else {
return Text('...');
}
}
title: PerformancesText(
performanceInfos: recordingInfo.performances,
),
onTap: () async {
final tracks = backend.ml.tracks[recording.id];
tracks.sort(
(t1, t2) => t1.track.index.compareTo(t2.track.index));
backend.player.addTracks(backend.ml.tracks[recording.id]);
},
);