diff --git a/lib/pages/list/list.dart b/lib/pages/list/list.dart index fe277fb..dfcf45d 100644 --- a/lib/pages/list/list.dart +++ b/lib/pages/list/list.dart @@ -80,13 +80,13 @@ class _ListPageState extends State { task: task, loading: false, onEdit: () => Navigator.push( - context, - MaterialPageRoute( - builder: (context) => TaskEditPage( - task: task, - ), - ), + context, + MaterialPageRoute( + builder: (context) => TaskEditPage( + task: task, ), + ), + ), onMarkedAsDone: (done) { VikunjaGlobal.of(context) .taskService @@ -112,13 +112,13 @@ class _ListPageState extends State { task: task, loading: true, onEdit: () => Navigator.push( - context, - MaterialPageRoute( - builder: (context) => TaskEditPage( - task: task, - ), - ), + context, + MaterialPageRoute( + builder: (context) => TaskEditPage( + task: task, ), + ), + ), ); } diff --git a/lib/pages/list/task_edit.dart b/lib/pages/list/task_edit.dart index aa78f7f..1deecac 100644 --- a/lib/pages/list/task_edit.dart +++ b/lib/pages/list/task_edit.dart @@ -57,248 +57,240 @@ class _TaskEditPageState extends State { ), body: Builder( builder: (BuildContext context) => SafeArea( - child: Form( - key: _formKey, - child: ListView(padding: const EdgeInsets.all(16.0), children: < - Widget>[ - Padding( - padding: EdgeInsets.symmetric(vertical: 10.0), + child: Form( + key: _formKey, + child: ListView(padding: const EdgeInsets.all(16.0), children: < + Widget>[ + Padding( + padding: EdgeInsets.symmetric(vertical: 10.0), + child: TextFormField( + maxLines: null, + keyboardType: TextInputType.multiline, + initialValue: widget.task.text, + onSaved: (text) => _text = text, + validator: (text) { + if (text.length < 3 || text.length > 250) { + return 'The text needs to have between 3 and 250 characters.'; + } + return null; + }, + decoration: new InputDecoration( + labelText: 'Text', + border: OutlineInputBorder(), + ), + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10.0), + child: TextFormField( + maxLines: null, + keyboardType: TextInputType.multiline, + initialValue: widget.task.description, + onSaved: (description) => _description = description, + validator: (description) { + if (description.length > 1000) { + return 'The description can have a maximum of 1000 characters.'; + } + return null; + }, + decoration: new InputDecoration( + labelText: 'Description', + border: OutlineInputBorder(), + ), + ), + ), + VikunjaDateTimePicker( + icon: Icon(Icons.access_time), + label: 'Due Date', + initialValue: widget.task.dueDate, + onSaved: (duedate) => _dueDate = duedate, + ), + VikunjaDateTimePicker( + label: 'Start Date', + initialValue: widget.task.startDate, + onSaved: (startDate) => _startDate = startDate, + ), + VikunjaDateTimePicker( + label: 'End Date', + initialValue: widget.task.endDate, + onSaved: (endDate) => _endDate = endDate, + ), + Row( + children: [ + Expanded( + flex: 2, child: TextFormField( - maxLines: null, - keyboardType: TextInputType.multiline, - initialValue: widget.task.text, - onSaved: (text) => _text = text, - validator: (text) { - if (text.length < 3 || text.length > 250) { - return 'The text needs to have between 3 and 250 characters.'; - } - return null; - }, + keyboardType: TextInputType.number, + initialValue: getRepeatAfterValueFromDuration( + widget.task.repeatAfter) + ?.toString(), + onSaved: (repeatAfter) => _repeatAfter = + getDurationFromType(repeatAfter, _repeatAfterType), decoration: new InputDecoration( - labelText: 'Text', - border: OutlineInputBorder(), + labelText: 'Repeat after', + border: InputBorder.none, + icon: Icon(Icons.repeat), ), ), ), - Padding( - padding: EdgeInsets.symmetric(vertical: 10.0), - child: TextFormField( - maxLines: null, - keyboardType: TextInputType.multiline, - initialValue: widget.task.description, - onSaved: (description) => _description = description, - validator: (description) { - if (description.length > 1000) { - return 'The description can have a maximum of 1000 characters.'; - } - return null; - }, - decoration: new InputDecoration( - labelText: 'Description', - border: OutlineInputBorder(), - ), - ), - ), - VikunjaDateTimePicker( - icon: Icon(Icons.access_time), - label: 'Due Date', - initialValue: widget.task.dueDate, - onSaved: (duedate) => _dueDate = duedate, - ), - VikunjaDateTimePicker( - label: 'Start Date', - initialValue: widget.task.startDate, - onSaved: (startDate) => _startDate = startDate, - ), - VikunjaDateTimePicker( - label: 'End Date', - initialValue: widget.task.endDate, - onSaved: (endDate) => _endDate = endDate, - ), - Row( - children: [ - Expanded( - flex: 2, - child: TextFormField( - keyboardType: TextInputType.number, - initialValue: getRepeatAfterValueFromDuration( - widget.task.repeatAfter) - ?.toString(), - onSaved: (repeatAfter) => _repeatAfter = - getDurationFromType( - repeatAfter, _repeatAfterType), - decoration: new InputDecoration( - labelText: 'Repeat after', - border: InputBorder.none, - icon: Icon(Icons.repeat), - ), - ), - ), - Expanded( - child: DropdownButton( - isExpanded: true, - isDense: true, - value: _repeatAfterType ?? - getRepeatAfterTypeFromDuration( - widget.task.repeatAfter), - onChanged: (String newValue) { - setState(() { - _repeatAfterType = newValue; - }); - }, - items: [ - 'Hours', - 'Days', - 'Weeks', - 'Months', - 'Years' - ].map>((String value) { - return DropdownMenuItem( - value: value, - child: Text(value), - ); - }).toList(), - ), - ), - ], - ), - Column( - children: _reminderInputs, - ), - GestureDetector( - child: Padding( - padding: EdgeInsets.symmetric(vertical: 10), - child: Row( - children: [ - Padding( - padding: EdgeInsets.only(right: 15, left: 2), - child: Icon( - Icons.alarm_add, - color: Colors.grey, - )), - Text( - 'Add a reminder', - style: TextStyle( - color: Colors.grey, - fontSize: 16, - ), - ), - ], - ), - ), - onTap: () { - // We add a new entry every time we add a new input, to make sure all inputs have a place where they can put their value. - _reminderDates.add(null); - var currentIndex = _reminderDates.length - 1; - - // FIXME: Why does putting this into a row fails? - setState(() => _reminderInputs.add(Row( - children: [ - VikunjaDateTimePicker( - label: 'Reminder', - onSaved: (reminder) => - _reminderDates[currentIndex] = reminder, - ), - GestureDetector( - onTap: () => print('tapped'), - child: Icon(Icons.close), - ) - ], - ))); - }), - InputDecorator( - isEmpty: _priority == null, - decoration: InputDecoration( - icon: const Icon(Icons.flag), - labelText: 'Priority', - border: InputBorder.none, - ), - child: new DropdownButton( - value: _priorityToString(_priority), + Expanded( + child: DropdownButton( isExpanded: true, isDense: true, + value: _repeatAfterType ?? + getRepeatAfterTypeFromDuration( + widget.task.repeatAfter), onChanged: (String newValue) { setState(() { - _priority = _priorityFromString(newValue); + _repeatAfterType = newValue; }); }, - items: [ - 'Unset', - 'Low', - 'Medium', - 'High', - 'Urgent', - 'DO NOW' - ].map((String value) { - return new DropdownMenuItem( + items: [ + 'Hours', + 'Days', + 'Weeks', + 'Months', + 'Years' + ].map>((String value) { + return DropdownMenuItem( value: value, - child: new Text(value), + child: Text(value), ); }).toList(), ), ), - Wrap( - spacing: 10, - children: _labels.map((Label label) { - return LabelComponent( - label: label, - onDelete: () { - _removeLabel(label); - }, - ); - }).toList()), - Row( - children: [ - Container( - width: MediaQuery.of(context).size.width - 80, - child: TypeAheadFormField( - textFieldConfiguration: TextFieldConfiguration( - controller: _labelTypeAheadController, - decoration: InputDecoration( - labelText: 'Add a new label')), - suggestionsCallback: (pattern) { - return _searchLabel(pattern); - }, - itemBuilder: (context, suggestion) { - return ListTile( - title: Text(suggestion), - ); - }, - transitionBuilder: - (context, suggestionsBox, controller) { - return suggestionsBox; - }, - onSuggestionSelected: (suggestion) { - _addLabel(suggestion); - }, - ), - ), - IconButton( - onPressed: () => - _createAndAddLabel(_labelTypeAheadController.text), - icon: Icon(Icons.add), - ) - ], - ), - Builder( - builder: (context) => Padding( - padding: EdgeInsets.symmetric(vertical: 10.0), - child: FancyButton( - onPressed: !_loading - ? () { - if (_formKey.currentState.validate()) { - Form.of(context).save(); - _saveTask(context); - } - } - : null, - child: _loading - ? CircularProgressIndicator() - : VikunjaButtonText('Save'), - ))), - ]), + ], ), - ), + Column( + children: _reminderInputs, + ), + GestureDetector( + child: Padding( + padding: EdgeInsets.symmetric(vertical: 10), + child: Row( + children: [ + Padding( + padding: EdgeInsets.only(right: 15, left: 2), + child: Icon( + Icons.alarm_add, + color: Colors.grey, + )), + Text( + 'Add a reminder', + style: TextStyle( + color: Colors.grey, + fontSize: 16, + ), + ), + ], + ), + ), + onTap: () { + // We add a new entry every time we add a new input, to make sure all inputs have a place where they can put their value. + _reminderDates.add(null); + var currentIndex = _reminderDates.length - 1; + + // FIXME: Why does putting this into a row fails? + setState(() => _reminderInputs.add(Row( + children: [ + VikunjaDateTimePicker( + label: 'Reminder', + onSaved: (reminder) => + _reminderDates[currentIndex] = reminder, + ), + GestureDetector( + onTap: () => print('tapped'), + child: Icon(Icons.close), + ) + ], + ))); + }), + InputDecorator( + isEmpty: _priority == null, + decoration: InputDecoration( + icon: const Icon(Icons.flag), + labelText: 'Priority', + border: InputBorder.none, + ), + child: new DropdownButton( + value: _priorityToString(_priority), + isExpanded: true, + isDense: true, + onChanged: (String newValue) { + setState(() { + _priority = _priorityFromString(newValue); + }); + }, + items: ['Unset', 'Low', 'Medium', 'High', 'Urgent', 'DO NOW'] + .map((String value) { + return new DropdownMenuItem( + value: value, + child: new Text(value), + ); + }).toList(), + ), + ), + Wrap( + spacing: 10, + children: _labels.map((Label label) { + return LabelComponent( + label: label, + onDelete: () { + _removeLabel(label); + }, + ); + }).toList()), + Row( + children: [ + Container( + width: MediaQuery.of(context).size.width - 80, + child: TypeAheadFormField( + textFieldConfiguration: TextFieldConfiguration( + controller: _labelTypeAheadController, + decoration: + InputDecoration(labelText: 'Add a new label')), + suggestionsCallback: (pattern) { + return _searchLabel(pattern); + }, + itemBuilder: (context, suggestion) { + return ListTile( + title: Text(suggestion), + ); + }, + transitionBuilder: (context, suggestionsBox, controller) { + return suggestionsBox; + }, + onSuggestionSelected: (suggestion) { + _addLabel(suggestion); + }, + ), + ), + IconButton( + onPressed: () => + _createAndAddLabel(_labelTypeAheadController.text), + icon: Icon(Icons.add), + ) + ], + ), + Builder( + builder: (context) => Padding( + padding: EdgeInsets.symmetric(vertical: 10.0), + child: FancyButton( + onPressed: !_loading + ? () { + if (_formKey.currentState.validate()) { + Form.of(context).save(); + _saveTask(context); + } + } + : null, + child: _loading + ? CircularProgressIndicator() + : VikunjaButtonText('Save'), + ))), + ]), + ), + ), ), ); }