Skip to content

Conversation

@xster
Copy link
Member

@xster xster commented Feb 1, 2017

  • Show out of bound dates as disabled
  • Prevent navigation into out of bound months by swipe or chevrons
  • Some small renames for readability

flutter_01

@xster xster requested a review from abarth February 1, 2017 02:16
@xster
Copy link
Member Author

xster commented Feb 1, 2017

Soliciting some feedback before I write the tests

@xster
Copy link
Member Author

xster commented Feb 1, 2017

Addresses #6501. Will generalize into a generic predicate mechanism #637 and fix the year selector on a different PR.

assert(currentDate != null);
assert(onChanged != null);
assert(displayedMonth != null);
assert(lastDate.isAfter(firstDate));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can they not be the same?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I kept the previous behaviour but makes sense. Changed.

if (day < 1) {
labels.add(new Container());
} else {
DateTime dayToBuild = new DateTime(year, month, day);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

behavior: HitTestBehavior.opaque,
onTap: () {
DateTime result = new DateTime(year, month, day);
onChanged(result);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You already have dayToBuild, might as well just return it instead of making a new copy.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

}

/// True if the earliest allowable month is displayed.
bool get _onFirstMonth {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually use the "on" prefix for callback closures. Maybe _isDisplayingFirstMonth ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, makes sense

void initState() {
super.initState();
// Initially display the pre-selected date.
_currentDisplayedMonthDate = new DateTime(config.selectedDate.year, config.selectedDate.month);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to update this member in didUpdateConfig as well. When your parent builds a new widget for this location in the tree and this State object is re-used, the framework calls didUpdateConfig to let you know that your config property now points to the new widget.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. Thanks.

new DateTime(config.lastDate.year, config.lastDate.month));
}

void _monthPageChanged(int monthPage) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually name implementations of onFoo callbacks something like _handleFoo, so in this case _handleMonthPageChanged.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SG

ScrollableState state = _dayPickerListKey.currentState;
double newPage = state.scrollOffset.round() + 1.0;
state?.scrollTo(newPage, duration: _kMonthScrollDuration);
_monthPageChanged(newPage.toInt());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no need to call _monthPageChanged here. The scrollTo call will eventually cause the callback to be called for you.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, what's what I was thinking when I opened #7764 since it wasn't working. If it's meant to, I'll dig a bit into why it wasn't working.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I read correctly, seems like onPageChanged is a PageableState concept and scrollTo is a ScrollableState concept. And the various stuff on the call back chains of scrollTo doesn't re-enter PageableState.

I can either use APIs on PageableState directly in date_picker, override scrollTo on the way in and await then snap to page and notify, add some handle to super's end scroll, the offset setter or something in PageableState, or just always callback on didUpdateConfig.

I suspect calling pageable state APIs directly is probably best. Overriding would imply page users would lose low level scrollable programmatic APIs to scroll and not snap.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, used the PageableState's fling API. PTAL

ScrollableState state = _dayPickerListKey.currentState;
double newPage = state.scrollOffset.round() - 1.0;
state?.scrollTo(newPage, duration: _kMonthScrollDuration);
_monthPageChanged(newPage.toInt());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

@abarth
Copy link
Contributor

abarth commented Feb 1, 2017

Definitely looks in the right track.

@Hixie
Copy link
Contributor

Hixie commented Feb 1, 2017

Regarding onFoo/didFoo/handleFoo, there's a discussion in the style guide.

@xster
Copy link
Member Author

xster commented Feb 1, 2017

Ok, adding tests

Future<Null> _flingToAdjacentItem(double scrollVelocity) {
final double newScrollOffset = snapScrollOffset(scrollOffset + scrollVelocity.sign)
.clamp(snapScrollOffset(scrollOffset - 0.5), snapScrollOffset(scrollOffset + 0.5));
.clamp(snapScrollOffset(scrollOffset - 0.50001), snapScrollOffset(scrollOffset + 0.5));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a bug. The fix is a bit cheesy but I hear you're going to delete all this so I didn't make it too fancy.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure you have a test for this specific case (with the date picker), and we'll make sure we don't regress it. :-)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's somewhere in date_picker_test.dart :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent.

});
});

testWidgets('Cannot selecte a month past last date', (WidgetTester tester) async {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: here and below - typo "selecte"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, thanks

state?.scrollTo(state.scrollOffset.round() + 1.0, duration: _kMonthScrollDuration);
if (!_isDisplayingLastMonth) {
PageableState<PageableLazyList> state = _dayPickerListKey.currentState;
state?.fling(1.0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've got the type parameter in the key, so you can write this as _dayPickerListKey.currentState?.fling(1.0) if you like.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

ScrollableState state = _dayPickerListKey.currentState;
state?.scrollTo(state.scrollOffset.round() - 1.0, duration: _kMonthScrollDuration);
if (!_isDisplayingFirstMonth) {
PageableState<PageableLazyList> state = _dayPickerListKey.currentState;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

@abarth
Copy link
Contributor

abarth commented Feb 2, 2017

LGTM

@abarth
Copy link
Contributor

abarth commented Feb 2, 2017

Thanks!

@xster
Copy link
Member Author

xster commented Feb 2, 2017

Thanks for the reviews!

@xster xster merged commit 959db13 into flutter:master Feb 2, 2017
@xster xster deleted the date-picker branch February 2, 2017 19:30
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants