Improve focus traversal
This commit is contained in:
parent
0eefa84c2f
commit
bf8a056117
|
|
@ -23,22 +23,20 @@ class SettingsScreen extends StatelessWidget {
|
||||||
final store = StoreProvider.of<AppState>(context);
|
final store = StoreProvider.of<AppState>(context);
|
||||||
final state = store.state;
|
final state = store.state;
|
||||||
|
|
||||||
return FocusTraversalGroup(
|
return ListScaffold(
|
||||||
child: ListScaffold(
|
entityType: EntityType.settings,
|
||||||
|
appBarTitle: ListFilter(
|
||||||
|
key:
|
||||||
|
ValueKey('__cleared_at_${state.settingsUIState.filterClearedAt}__'),
|
||||||
entityType: EntityType.settings,
|
entityType: EntityType.settings,
|
||||||
appBarTitle: ListFilter(
|
entityIds: [],
|
||||||
key: ValueKey(
|
filter: state.settingsUIState.filter,
|
||||||
'__cleared_at_${state.settingsUIState.filterClearedAt}__'),
|
onFilterChanged: (value) {
|
||||||
entityType: EntityType.settings,
|
store.dispatch(FilterSettings(value));
|
||||||
entityIds: [],
|
},
|
||||||
filter: state.settingsUIState.filter,
|
|
||||||
onFilterChanged: (value) {
|
|
||||||
store.dispatch(FilterSettings(value));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
appBarActions: <Widget>[],
|
|
||||||
body: SettingsListBuilder(),
|
|
||||||
),
|
),
|
||||||
|
appBarActions: <Widget>[],
|
||||||
|
body: SettingsListBuilder(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -290,145 +290,142 @@ class _TaskEditDesktopState extends State<TaskEditDesktop> {
|
||||||
),
|
),
|
||||||
FormCard(
|
FormCard(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: kMobileDialogPadding),
|
padding: const EdgeInsets.symmetric(horizontal: kMobileDialogPadding),
|
||||||
child: FocusTraversalGroup(
|
child: Table(
|
||||||
policy: ReadingOrderTraversalPolicy(),
|
key: ValueKey('__table_${_updatedAt}__'),
|
||||||
child: Table(
|
columnWidths: {
|
||||||
key: ValueKey('__table_${_updatedAt}__'),
|
showEndDate ? 5 : 4: FixedColumnWidth(kMinInteractiveDimension),
|
||||||
columnWidths: {
|
},
|
||||||
showEndDate ? 5 : 4: FixedColumnWidth(kMinInteractiveDimension),
|
children: [
|
||||||
},
|
TableRow(
|
||||||
children: [
|
children: [
|
||||||
TableRow(
|
TableHeader(localization.startDate, isFirst: true),
|
||||||
children: [
|
TableHeader(localization.startTime),
|
||||||
TableHeader(localization.startDate, isFirst: true),
|
if (showEndDate) TableHeader(localization.endDate),
|
||||||
TableHeader(localization.startTime),
|
TableHeader(localization.endTime),
|
||||||
if (showEndDate) TableHeader(localization.endDate),
|
TableHeader(localization.duration),
|
||||||
TableHeader(localization.endTime),
|
TableHeader(''),
|
||||||
TableHeader(localization.duration),
|
],
|
||||||
TableHeader(''),
|
decoration: tableHeaderColor.isNotEmpty
|
||||||
],
|
? BoxDecoration(
|
||||||
decoration: tableHeaderColor.isNotEmpty
|
color: convertHexStringToColor(tableHeaderColor),
|
||||||
? BoxDecoration(
|
)
|
||||||
color: convertHexStringToColor(tableHeaderColor),
|
: null,
|
||||||
)
|
),
|
||||||
: null,
|
for (var index = 0; index < taskTimes.length; index++)
|
||||||
),
|
TableRow(children: [
|
||||||
for (var index = 0; index < taskTimes.length; index++)
|
Padding(
|
||||||
TableRow(children: [
|
padding: const EdgeInsets.only(right: kTableColumnGap),
|
||||||
|
child: DatePicker(
|
||||||
|
key: ValueKey(
|
||||||
|
'__${_startTimeUpdatedAt}_${_durationUpdateAt}_${index}__'),
|
||||||
|
selectedDate: taskTimes[index].startDate == null
|
||||||
|
? null
|
||||||
|
: convertDateTimeToSqlDate(
|
||||||
|
taskTimes[index].startDate.toLocal()),
|
||||||
|
onSelected: (date) {
|
||||||
|
final taskTime = taskTimes[index]
|
||||||
|
.copyWithStartDate(date, syncDates: !showEndDate);
|
||||||
|
viewModel.onUpdatedTaskTime(taskTime, index);
|
||||||
|
setState(() {
|
||||||
|
_startDateUpdatedAt =
|
||||||
|
DateTime.now().millisecondsSinceEpoch;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: kTableColumnGap),
|
||||||
|
child: TimePicker(
|
||||||
|
key: ValueKey('__${_durationUpdateAt}_${index}__'),
|
||||||
|
selectedDateTime: taskTimes[index].startDate,
|
||||||
|
onSelected: (timeOfDay) {
|
||||||
|
final taskTime =
|
||||||
|
taskTimes[index].copyWithStartTime(timeOfDay);
|
||||||
|
viewModel.onUpdatedTaskTime(taskTime, index);
|
||||||
|
setState(() {
|
||||||
|
_startTimeUpdatedAt =
|
||||||
|
DateTime.now().millisecondsSinceEpoch;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (showEndDate)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(right: kTableColumnGap),
|
padding: const EdgeInsets.only(right: kTableColumnGap),
|
||||||
child: DatePicker(
|
child: DatePicker(
|
||||||
key: ValueKey(
|
key: ValueKey(
|
||||||
'__${_startTimeUpdatedAt}_${_durationUpdateAt}_${index}__'),
|
'__${_startDateUpdatedAt}_${_durationUpdateAt}_${_endTimeUpdatedAt}_${index}__'),
|
||||||
selectedDate: taskTimes[index].startDate == null
|
selectedDate: taskTimes[index].endDate == null
|
||||||
? null
|
? null
|
||||||
: convertDateTimeToSqlDate(
|
: convertDateTimeToSqlDate(
|
||||||
taskTimes[index].startDate.toLocal()),
|
taskTimes[index].endDate.toLocal()),
|
||||||
onSelected: (date) {
|
onSelected: (date) {
|
||||||
final taskTime = taskTimes[index]
|
|
||||||
.copyWithStartDate(date, syncDates: !showEndDate);
|
|
||||||
viewModel.onUpdatedTaskTime(taskTime, index);
|
|
||||||
setState(() {
|
|
||||||
_startDateUpdatedAt =
|
|
||||||
DateTime.now().millisecondsSinceEpoch;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(right: kTableColumnGap),
|
|
||||||
child: TimePicker(
|
|
||||||
key: ValueKey('__${_durationUpdateAt}_${index}__'),
|
|
||||||
selectedDateTime: taskTimes[index].startDate,
|
|
||||||
onSelected: (timeOfDay) {
|
|
||||||
final taskTime =
|
final taskTime =
|
||||||
taskTimes[index].copyWithStartTime(timeOfDay);
|
taskTimes[index].copyWithEndDate(date);
|
||||||
viewModel.onUpdatedTaskTime(taskTime, index);
|
viewModel.onUpdatedTaskTime(taskTime, index);
|
||||||
setState(() {
|
setState(() {
|
||||||
_startTimeUpdatedAt =
|
_endDateUpdatedAt =
|
||||||
DateTime.now().millisecondsSinceEpoch;
|
DateTime.now().millisecondsSinceEpoch;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (showEndDate)
|
Padding(
|
||||||
Padding(
|
padding: const EdgeInsets.only(right: kTableColumnGap),
|
||||||
padding: const EdgeInsets.only(right: kTableColumnGap),
|
child: TimePicker(
|
||||||
child: DatePicker(
|
key: ValueKey(
|
||||||
key: ValueKey(
|
'__${_endDateUpdatedAt}_${_durationUpdateAt}_${index}__'),
|
||||||
'__${_startDateUpdatedAt}_${_durationUpdateAt}_${_endTimeUpdatedAt}_${index}__'),
|
selectedDateTime: taskTimes[index].endDate,
|
||||||
selectedDate: taskTimes[index].endDate == null
|
isEndTime: true,
|
||||||
? null
|
onSelected: (timeOfDay) {
|
||||||
: convertDateTimeToSqlDate(
|
final taskTime =
|
||||||
taskTimes[index].endDate.toLocal()),
|
taskTimes[index].copyWithEndTime(timeOfDay);
|
||||||
onSelected: (date) {
|
viewModel.onUpdatedTaskTime(taskTime, index);
|
||||||
final taskTime =
|
setState(() {
|
||||||
taskTimes[index].copyWithEndDate(date);
|
_endTimeUpdatedAt =
|
||||||
viewModel.onUpdatedTaskTime(taskTime, index);
|
DateTime.now().millisecondsSinceEpoch;
|
||||||
setState(() {
|
});
|
||||||
_endDateUpdatedAt =
|
},
|
||||||
DateTime.now().millisecondsSinceEpoch;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(right: kTableColumnGap),
|
|
||||||
child: TimePicker(
|
|
||||||
key: ValueKey(
|
|
||||||
'__${_endDateUpdatedAt}_${_durationUpdateAt}_${index}__'),
|
|
||||||
selectedDateTime: taskTimes[index].endDate,
|
|
||||||
isEndTime: true,
|
|
||||||
onSelected: (timeOfDay) {
|
|
||||||
final taskTime =
|
|
||||||
taskTimes[index].copyWithEndTime(timeOfDay);
|
|
||||||
viewModel.onUpdatedTaskTime(taskTime, index);
|
|
||||||
setState(() {
|
|
||||||
_endTimeUpdatedAt =
|
|
||||||
DateTime.now().millisecondsSinceEpoch;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Padding(
|
),
|
||||||
padding: const EdgeInsets.only(right: kTableColumnGap),
|
Padding(
|
||||||
child: DurationPicker(
|
padding: const EdgeInsets.only(right: kTableColumnGap),
|
||||||
key: ValueKey(
|
child: DurationPicker(
|
||||||
'__${_startTimeUpdatedAt}_${_endTimeUpdatedAt}_${_startDateUpdatedAt}_${_endDateUpdatedAt}_${index}__'),
|
key: ValueKey(
|
||||||
onSelected: (Duration duration) {
|
'__${_startTimeUpdatedAt}_${_endTimeUpdatedAt}_${_startDateUpdatedAt}_${_endDateUpdatedAt}_${index}__'),
|
||||||
final taskTime =
|
onSelected: (Duration duration) {
|
||||||
taskTimes[index].copyWithDuration(duration);
|
final taskTime =
|
||||||
viewModel.onUpdatedTaskTime(taskTime, index);
|
taskTimes[index].copyWithDuration(duration);
|
||||||
setState(() {
|
viewModel.onUpdatedTaskTime(taskTime, index);
|
||||||
_durationUpdateAt =
|
setState(() {
|
||||||
DateTime.now().millisecondsSinceEpoch;
|
_durationUpdateAt =
|
||||||
});
|
DateTime.now().millisecondsSinceEpoch;
|
||||||
},
|
});
|
||||||
selectedDuration: (taskTimes[index].startDate == null ||
|
},
|
||||||
taskTimes[index].endDate == null)
|
selectedDuration: (taskTimes[index].startDate == null ||
|
||||||
? null
|
taskTimes[index].endDate == null)
|
||||||
: taskTimes[index].duration,
|
? null
|
||||||
),
|
: taskTimes[index].duration,
|
||||||
),
|
),
|
||||||
Padding(
|
),
|
||||||
padding: const EdgeInsets.only(top: 4),
|
Padding(
|
||||||
child: IconButton(
|
padding: const EdgeInsets.only(top: 4),
|
||||||
icon: Icon(Icons.clear),
|
child: IconButton(
|
||||||
tooltip: localization.remove,
|
icon: Icon(Icons.clear),
|
||||||
onPressed: taskTimes[index].isEmpty
|
tooltip: localization.remove,
|
||||||
? null
|
onPressed: taskTimes[index].isEmpty
|
||||||
: () {
|
? null
|
||||||
viewModel.onRemoveTaskTime(index);
|
: () {
|
||||||
setState(() {
|
viewModel.onRemoveTaskTime(index);
|
||||||
_updatedAt =
|
setState(() {
|
||||||
DateTime.now().millisecondsSinceEpoch;
|
_updatedAt =
|
||||||
});
|
DateTime.now().millisecondsSinceEpoch;
|
||||||
},
|
});
|
||||||
),
|
},
|
||||||
),
|
),
|
||||||
]),
|
),
|
||||||
],
|
]),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue