mobile: Check server errors in editors

This commit is contained in:
Elias Projahn 2020-04-26 18:29:21 +02:00
parent 00c31296e5
commit 9d4554b67f
6 changed files with 247 additions and 91 deletions

View file

@ -25,6 +25,13 @@ class App extends StatelessWidget {
primary: Colors.amber, primary: Colors.amber,
secondary: Colors.amber, secondary: Colors.amber,
), ),
snackBarTheme: SnackBarThemeData(
backgroundColor: Colors.grey[800],
contentTextStyle: TextStyle(
color: Colors.white,
),
behavior: SnackBarBehavior.floating,
),
fontFamily: 'Libertinus Sans', fontFamily: 'Libertinus Sans',
), ),
home: Builder( home: Builder(

View file

@ -17,6 +17,8 @@ class EnsembleEditor extends StatefulWidget {
class _EnsembleEditorState extends State<EnsembleEditor> { class _EnsembleEditorState extends State<EnsembleEditor> {
final nameController = TextEditingController(); final nameController = TextEditingController();
bool uploading = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -34,18 +36,46 @@ class _EnsembleEditorState extends State<EnsembleEditor> {
appBar: AppBar( appBar: AppBar(
title: Text('Ensemble'), title: Text('Ensemble'),
actions: <Widget>[ actions: <Widget>[
FlatButton( uploading
child: Text('DONE'), ? Padding(
onPressed: () async { padding: const EdgeInsets.all(16.0),
final ensemble = Ensemble( child: Center(
id: widget.ensemble?.id ?? generateId(), child: SizedBox(
name: nameController.text, width: 24.0,
); height: 24.0,
child: CircularProgressIndicator(
strokeWidth: 2.0,
),
),
),
)
: FlatButton(
child: Text('DONE'),
onPressed: () async {
setState(() {
uploading = true;
});
await backend.client.putEnsemble(ensemble); final ensemble = Ensemble(
Navigator.pop(context, ensemble); id: widget.ensemble?.id ?? generateId(),
}, name: nameController.text,
) );
final success = await backend.client.putEnsemble(ensemble);
setState(() {
uploading = false;
});
if (success) {
Navigator.pop(context, ensemble);
} else {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('Failed to upload'),
));
}
},
),
], ],
), ),
body: ListView( body: ListView(

View file

@ -17,6 +17,8 @@ class InstrumentEditor extends StatefulWidget {
class _InstrumentEditorState extends State<InstrumentEditor> { class _InstrumentEditorState extends State<InstrumentEditor> {
final nameController = TextEditingController(); final nameController = TextEditingController();
bool uploading = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -34,18 +36,47 @@ class _InstrumentEditorState extends State<InstrumentEditor> {
appBar: AppBar( appBar: AppBar(
title: Text('Instrument/Role'), title: Text('Instrument/Role'),
actions: <Widget>[ actions: <Widget>[
FlatButton( uploading
child: Text('DONE'), ? Padding(
onPressed: () async { padding: const EdgeInsets.all(16.0),
final instrument = Instrument( child: Center(
id: widget.instrument?.id ?? generateId(), child: SizedBox(
name: nameController.text, width: 24.0,
); height: 24.0,
child: CircularProgressIndicator(
strokeWidth: 2.0,
),
),
),
)
: FlatButton(
child: Text('DONE'),
onPressed: () async {
setState(() {
uploading = true;
});
await backend.client.putInstrument(instrument); final instrument = Instrument(
Navigator.pop(context, instrument); id: widget.instrument?.id ?? generateId(),
}, name: nameController.text,
) );
final success =
await backend.client.putInstrument(instrument);
setState(() {
uploading = false;
});
if (success) {
Navigator.pop(context, instrument);
} else {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('Failed to upload'),
));
}
},
),
], ],
), ),
body: ListView( body: ListView(

View file

@ -18,6 +18,8 @@ class _PersonEditorState extends State<PersonEditor> {
final firstNameController = TextEditingController(); final firstNameController = TextEditingController();
final lastNameController = TextEditingController(); final lastNameController = TextEditingController();
bool uploading = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -36,19 +38,47 @@ class _PersonEditorState extends State<PersonEditor> {
appBar: AppBar( appBar: AppBar(
title: Text('Person'), title: Text('Person'),
actions: <Widget>[ actions: <Widget>[
FlatButton( uploading
child: Text('DONE'), ? Padding(
onPressed: () async { padding: const EdgeInsets.all(16.0),
final person = Person( child: Center(
id: widget.person?.id ?? generateId(), child: SizedBox(
firstName: firstNameController.text, width: 24.0,
lastName: lastNameController.text, height: 24.0,
); child: CircularProgressIndicator(
strokeWidth: 2.0,
),
),
),
)
: FlatButton(
child: Text('DONE'),
onPressed: () async {
setState(() {
uploading = true;
});
await backend.client.putPerson(person); final person = Person(
Navigator.pop(context, person); id: widget.person?.id ?? generateId(),
}, firstName: firstNameController.text,
), lastName: lastNameController.text,
);
final success = await backend.client.putPerson(person);
setState(() {
uploading = false;
});
if (success) {
Navigator.pop(context, person);
} else {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('Failed to upload'),
));
}
},
),
], ],
), ),
body: ListView( body: ListView(

View file

@ -27,6 +27,7 @@ class RecordingEditor extends StatefulWidget {
class _RecordingEditorState extends State<RecordingEditor> { class _RecordingEditorState extends State<RecordingEditor> {
final commentController = TextEditingController(); final commentController = TextEditingController();
bool uploading = false;
WorkInfo workInfo; WorkInfo workInfo;
List<PerformanceInfo> performanceInfos = []; List<PerformanceInfo> performanceInfos = [];
@ -103,29 +104,58 @@ class _RecordingEditorState extends State<RecordingEditor> {
appBar: AppBar( appBar: AppBar(
title: Text('Recording'), title: Text('Recording'),
actions: <Widget>[ actions: <Widget>[
FlatButton( uploading
child: Text('DONE'), ? Padding(
onPressed: () async { padding: const EdgeInsets.all(16.0),
final recordingInfo = RecordingInfo( child: Center(
recording: Recording( child: SizedBox(
id: widget?.recordingInfo?.recording?.id ?? generateId(), width: 24.0,
work: workInfo.work.id, height: 24.0,
comment: commentController.text, child: CircularProgressIndicator(
), strokeWidth: 2.0,
performances: performanceInfos, ),
); ),
),
)
: FlatButton(
child: Text('DONE'),
onPressed: () async {
setState(() {
uploading = true;
});
await backend.client.putRecording(recordingInfo); final recordingInfo = RecordingInfo(
recording: Recording(
id: widget?.recordingInfo?.recording?.id ??
generateId(),
work: workInfo.work.id,
comment: commentController.text,
),
performances: performanceInfos,
);
Navigator.pop( final success =
context, await backend.client.putRecording(recordingInfo);
RecordingSelectorResult(
workInfo: workInfo, setState(() {
recordingInfo: recordingInfo, uploading = false;
});
if (success) {
Navigator.pop(
context,
RecordingSelectorResult(
workInfo: workInfo,
recordingInfo: recordingInfo,
),
);
} else {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('Failed to upload'),
));
}
},
), ),
);
},
)
], ],
), ),
body: ListView( body: ListView(

View file

@ -173,6 +173,7 @@ class WorkEditor extends StatefulWidget {
class _WorkEditorState extends State<WorkEditor> { class _WorkEditorState extends State<WorkEditor> {
final titleController = TextEditingController(); final titleController = TextEditingController();
bool uploading = false;
Person composer; Person composer;
List<Instrument> instruments = []; List<Instrument> instruments = [];
List<PartData> parts = []; List<PartData> parts = [];
@ -249,45 +250,72 @@ class _WorkEditorState extends State<WorkEditor> {
appBar: AppBar( appBar: AppBar(
title: Text('Work'), title: Text('Work'),
actions: <Widget>[ actions: <Widget>[
FlatButton( uploading
child: Text('DONE'), ? Padding(
onPressed: () async { padding: const EdgeInsets.all(16.0),
final workId = widget?.workInfo?.work?.id ?? generateId(); child: Center(
child: SizedBox(
List<PartInfo> partInfos = []; width: 24.0,
for (var i = 0; i < parts.length; i++) { height: 24.0,
final part = parts[i]; child: CircularProgressIndicator(
partInfos.add(PartInfo( strokeWidth: 2.0,
work: Work( ),
id: generateId(), ),
title: part.titleController.text,
composer: part.composer?.id,
partOf: workId,
partIndex: i,
), ),
instruments: part.instruments, )
composer: part.composer, : FlatButton(
)); child: Text('DONE'),
} onPressed: () async {
setState(() {
uploading = true;
});
final workInfo = WorkInfo( final workId = widget?.workInfo?.work?.id ?? generateId();
work: Work(
id: workId, List<PartInfo> partInfos = [];
title: titleController.text, for (var i = 0; i < parts.length; i++) {
composer: composer?.id, final part = parts[i];
partInfos.add(PartInfo(
work: Work(
id: generateId(),
title: part.titleController.text,
composer: part.composer?.id,
partOf: workId,
partIndex: i,
),
instruments: part.instruments,
composer: part.composer,
));
}
final workInfo = WorkInfo(
work: Work(
id: workId,
title: titleController.text,
composer: composer?.id,
),
instruments: instruments,
// TODO: Theoretically, this should include all composers
// from the parts.
composers: [composer],
parts: partInfos,
);
final success = await backend.client.putWork(workInfo);
setState(() {
uploading = false;
});
if (success) {
Navigator.pop(context, workInfo);
} else {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('Failed to upload'),
));
}
},
), ),
instruments: instruments,
// TODO: Theoretically, this should include all composers from
// the parts.
composers: [composer],
parts: partInfos,
);
await backend.client.putWork(workInfo);
Navigator.pop(context, workInfo);
},
),
], ],
), ),
body: ReorderableListView( body: ReorderableListView(