| 
									
										
										
										
											2020-04-06 11:43:46 +02:00
										 |  |  | import 'package:flutter/material.dart'; | 
					
						
							| 
									
										
										
										
											2020-04-24 22:41:52 +02:00
										 |  |  | import 'package:musicus_database/musicus_database.dart'; | 
					
						
							| 
									
										
										
										
											2020-04-06 11:43:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import '../backend.dart'; | 
					
						
							| 
									
										
										
										
											2020-04-18 23:41:08 +02:00
										 |  |  | import '../music_library.dart'; | 
					
						
							| 
									
										
										
										
											2020-04-06 11:43:46 +02:00
										 |  |  | import '../selectors/files.dart'; | 
					
						
							|  |  |  | import '../selectors/recording.dart'; | 
					
						
							|  |  |  | import '../widgets/recording_tile.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TrackModel { | 
					
						
							| 
									
										
										
										
											2020-04-24 20:10:48 +02:00
										 |  |  |   int workPartIndex; | 
					
						
							|  |  |  |   String workPartTitle; | 
					
						
							| 
									
										
										
										
											2020-04-18 23:41:08 +02:00
										 |  |  |   String fileName; | 
					
						
							| 
									
										
										
										
											2020-04-06 11:43:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-18 23:41:08 +02:00
										 |  |  |   TrackModel(this.fileName); | 
					
						
							| 
									
										
										
										
											2020-04-06 11:43:46 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TracksEditor extends StatefulWidget { | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   _TracksEditorState createState() => _TracksEditorState(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class _TracksEditorState extends State<TracksEditor> { | 
					
						
							| 
									
										
										
										
											2020-04-24 20:10:48 +02:00
										 |  |  |   BackendState backend; | 
					
						
							| 
									
										
										
										
											2020-04-06 11:43:46 +02:00
										 |  |  |   int recordingId; | 
					
						
							| 
									
										
										
										
											2020-04-18 23:41:08 +02:00
										 |  |  |   String parentId; | 
					
						
							|  |  |  |   List<TrackModel> trackModels = []; | 
					
						
							| 
									
										
										
										
											2020-04-06 11:43:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							| 
									
										
										
										
											2020-04-24 20:10:48 +02:00
										 |  |  |     backend = Backend.of(context); | 
					
						
							| 
									
										
										
										
											2020-04-06 11:43:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return Scaffold( | 
					
						
							|  |  |  |       appBar: AppBar( | 
					
						
							|  |  |  |         title: Text('Tracks'), | 
					
						
							|  |  |  |         actions: <Widget>[ | 
					
						
							|  |  |  |           FlatButton( | 
					
						
							|  |  |  |             child: Text('DONE'), | 
					
						
							|  |  |  |             onPressed: () async { | 
					
						
							| 
									
										
										
										
											2020-04-18 23:41:08 +02:00
										 |  |  |               final List<Track> tracks = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               for (var i = 0; i < trackModels.length; i++) { | 
					
						
							|  |  |  |                 final trackModel = trackModels[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 tracks.add(Track( | 
					
						
							|  |  |  |                   fileName: trackModel.fileName, | 
					
						
							|  |  |  |                   recordingId: recordingId, | 
					
						
							|  |  |  |                   index: i, | 
					
						
							| 
									
										
										
										
											2020-04-24 20:10:48 +02:00
										 |  |  |                   partIds: [trackModel.workPartIndex], | 
					
						
							| 
									
										
										
										
											2020-04-18 23:41:08 +02:00
										 |  |  |                 )); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               backend.ml.addTracks(parentId, tracks); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               Navigator.pop(context); | 
					
						
							| 
									
										
										
										
											2020-04-06 11:43:46 +02:00
										 |  |  |             }, | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |       ), | 
					
						
							| 
									
										
										
										
											2020-04-06 11:55:19 +02:00
										 |  |  |       body: ReorderableListView( | 
					
						
							|  |  |  |         header: Column( | 
					
						
							|  |  |  |           children: <Widget>[ | 
					
						
							| 
									
										
										
										
											2020-04-22 10:10:25 +02:00
										 |  |  |             ListTile( | 
					
						
							|  |  |  |               title: recordingId != null | 
					
						
							|  |  |  |                   ? RecordingTile( | 
					
						
							|  |  |  |                       recordingId: recordingId, | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                   : Text('Select recording'), | 
					
						
							|  |  |  |               onTap: selectRecording, | 
					
						
							|  |  |  |             ), | 
					
						
							| 
									
										
										
										
											2020-04-06 11:43:46 +02:00
										 |  |  |             ListTile( | 
					
						
							| 
									
										
										
										
											2020-04-06 11:55:19 +02:00
										 |  |  |               title: Text('Files'), | 
					
						
							| 
									
										
										
										
											2020-04-06 11:43:46 +02:00
										 |  |  |               trailing: IconButton( | 
					
						
							| 
									
										
										
										
											2020-04-24 20:10:48 +02:00
										 |  |  |                 icon: const Icon(Icons.edit), | 
					
						
							| 
									
										
										
										
											2020-04-06 11:55:19 +02:00
										 |  |  |                 onPressed: () async { | 
					
						
							| 
									
										
										
										
											2020-04-18 21:23:24 +02:00
										 |  |  |                   final FilesSelectorResult result = await Navigator.push( | 
					
						
							| 
									
										
										
										
											2020-04-06 11:55:19 +02:00
										 |  |  |                     context, | 
					
						
							|  |  |  |                     MaterialPageRoute( | 
					
						
							| 
									
										
										
										
											2020-04-11 21:59:23 +02:00
										 |  |  |                       builder: (context) => FilesSelector(), | 
					
						
							| 
									
										
										
										
											2020-04-06 11:55:19 +02:00
										 |  |  |                     ), | 
					
						
							|  |  |  |                   ); | 
					
						
							| 
									
										
										
										
											2020-04-18 21:23:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                   if (result != null) { | 
					
						
							| 
									
										
										
										
											2020-04-24 20:10:48 +02:00
										 |  |  |                     final List<TrackModel> newTrackModels = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     for (final document in result.selection) { | 
					
						
							|  |  |  |                       newTrackModels.add(TrackModel(document.name)); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-18 23:41:08 +02:00
										 |  |  |                     setState(() { | 
					
						
							|  |  |  |                       parentId = result.parentId; | 
					
						
							| 
									
										
										
										
											2020-04-24 20:10:48 +02:00
										 |  |  |                       trackModels = newTrackModels; | 
					
						
							| 
									
										
										
										
											2020-04-18 23:41:08 +02:00
										 |  |  |                     }); | 
					
						
							| 
									
										
										
										
											2020-04-24 20:10:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                     if (recordingId != null) { | 
					
						
							|  |  |  |                       updateAutoParts(); | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2020-04-18 21:23:24 +02:00
										 |  |  |                   } | 
					
						
							| 
									
										
										
										
											2020-04-06 11:43:46 +02:00
										 |  |  |                 }, | 
					
						
							|  |  |  |               ), | 
					
						
							|  |  |  |             ), | 
					
						
							| 
									
										
										
										
											2020-04-06 11:55:19 +02:00
										 |  |  |           ], | 
					
						
							|  |  |  |         ), | 
					
						
							| 
									
										
										
										
											2020-04-18 23:41:08 +02:00
										 |  |  |         children: trackModels | 
					
						
							| 
									
										
										
										
											2020-04-06 11:55:19 +02:00
										 |  |  |             .map((t) => ListTile( | 
					
						
							|  |  |  |                   key: Key(t.hashCode.toString()), | 
					
						
							| 
									
										
										
										
											2020-04-24 20:10:48 +02:00
										 |  |  |                   leading: const Icon(Icons.drag_handle), | 
					
						
							|  |  |  |                   title: Text(t.workPartTitle ?? 'Set work part'), | 
					
						
							|  |  |  |                   subtitle: Text(t.fileName), | 
					
						
							| 
									
										
										
										
											2020-04-06 11:55:19 +02:00
										 |  |  |                 )) | 
					
						
							|  |  |  |             .toList(), | 
					
						
							|  |  |  |         onReorder: (i1, i2) { | 
					
						
							|  |  |  |           setState(() { | 
					
						
							| 
									
										
										
										
											2020-04-18 23:41:08 +02:00
										 |  |  |             final track = trackModels.removeAt(i1); | 
					
						
							| 
									
										
										
										
											2020-04-06 11:55:19 +02:00
										 |  |  |             final newIndex = i2 > i1 ? i2 - 1 : i2; | 
					
						
							| 
									
										
										
										
											2020-04-18 23:41:08 +02:00
										 |  |  |             trackModels.insert(newIndex, track); | 
					
						
							| 
									
										
										
										
											2020-04-06 11:55:19 +02:00
										 |  |  |           }); | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2020-04-06 11:43:46 +02:00
										 |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-24 20:10:48 +02:00
										 |  |  |   Future<void> selectRecording() async { | 
					
						
							| 
									
										
										
										
											2020-04-06 11:43:46 +02:00
										 |  |  |     final Recording recording = await Navigator.push( | 
					
						
							|  |  |  |       context, | 
					
						
							|  |  |  |       MaterialPageRoute( | 
					
						
							|  |  |  |         builder: (context) => RecordingsSelector(), | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (recording != null) { | 
					
						
							|  |  |  |       setState(() { | 
					
						
							|  |  |  |         recordingId = recording.id; | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2020-04-24 20:10:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       updateAutoParts(); | 
					
						
							| 
									
										
										
										
											2020-04-06 11:43:46 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-04-24 20:10:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /// Automatically associate the tracks with work parts.
 | 
					
						
							|  |  |  |   Future<void> updateAutoParts() async { | 
					
						
							|  |  |  |     final recording = await backend.db.recordingById(recordingId).getSingle(); | 
					
						
							|  |  |  |     final workId = recording.work; | 
					
						
							|  |  |  |     final workParts = await backend.db.workParts(workId).get(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     setState(() { | 
					
						
							|  |  |  |       for (var i = 0; i < trackModels.length; i++) { | 
					
						
							|  |  |  |         if (i >= workParts.length) { | 
					
						
							|  |  |  |           trackModels[i].workPartIndex = null; | 
					
						
							|  |  |  |           trackModels[i].workPartTitle = null; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           trackModels[i].workPartIndex = workParts[i].partIndex; | 
					
						
							|  |  |  |           trackModels[i].workPartTitle = workParts[i].title; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-04-06 11:43:46 +02:00
										 |  |  | } |