BugiDev / react-native-calendar-strip

Easy to use and visually stunning calendar component for React Native.
MIT License
957 stars 329 forks source link

Swipe Calendar #1

Closed basequatro closed 4 years ago

basequatro commented 8 years ago

Hi. Great Work! Would be great if we could swipe instead of using arrows.

peacechen commented 7 years ago

Would this help provide swiping? https://github.com/leecade/react-native-swiper

FlaviooLima commented 7 years ago

I already created a calendar exactly like this one, but with swipe feature using: https://github.com/leecade/react-native-swiper

Unfortunately it's very slow, specially in android. I believe that the swipe library is not recommended for this type of component. But maybe it was my fault (it probably was xD).

Eager to see this feature implemented.

jan-06-2017 10-45-44

peacechen commented 7 years ago

After evaluating some performance bottlenecks with CalendarStrip, there is room for significant improvement using LayoutAnimation instead of Animated. I am working on refactoring CalendarStrip to use LayoutAnimation (https://github.com/BugiDev/react-native-calendar-strip/issues/25). Would like to hear your ideas on swiping after that is done.

daminux commented 7 years ago

Will be great @peacechen @flaviotobi

peacechen commented 7 years ago

@flaviotobi Would you mind sharing your prototype calendar swiping code? react-native-swiper uses a ScrollView to implement the swiping. I imagine if there are lots of dates in the ScrollView, performance would drop significantly. An optimization may be to dynamically populate the dates as the calendar strip is swiped.

FlaviooLima commented 7 years ago

@peacechen I'm gonna be honest my implementation it's very messy, but after a few updates of https://github.com/leecade/react-native-swiper and a few hacks that i did in the code my self, it's getting better.

I'm using two libraries. react-native-swiper react-native-agenda-view

With react-native-swiper i created the week view with the week days that you see in the gif in my early post. On click in the day it has below a list of events that is made by using react-native-agenda-view. this agenda is render every time you click a different day.

In the swipe i have an array with 3 positions [ weekBefore , actualWeek , weekAfter ]. I created 3 swappable views and locked the swipe component to be always in the middle. and when it detects that you swipe to change the week, it changes the array and render the new information that has to be in the middle position of swipe.

Yes i can share my code, but it's very messy, i had to do this in a morning, and i wasn't cable of more elaborate work, but if you are willing to do this the right way that would be awesome :)

Could you tell me the best way to share with you the code ? [noob asking xD]

if you would this weekend i cant create it on github as a React-native component and evolve from there.

peacechen commented 7 years ago

I recommend creating a public Github repo and post your code there. Thanks for sharing your code :)

song50119 commented 7 years ago

+1

YoucefMami commented 7 years ago

Is this still in the works?

arrkaye commented 7 years ago

This is a great library, and swipe support would make even better.

Is it on the cards any time soon?

lomo009 commented 7 years ago

+1

joejlam commented 6 years ago

+1 would be incredibly helpful @BugiDev thanks so much for all your work.

skmehra commented 6 years ago

@FlaviooLima Would it be possible to share the code for swipe?

tyricec commented 6 years ago

I think it would be cool if we could use a library like this to do swiping, but not sure how much it would change this library.

https://github.com/archriss/react-native-snap-carousel

peacechen commented 6 years ago

TBH that's too heavy for this use case and would require substantial redesign. Swiping here could be accomplished with a ScrollView that substitutes the previous/next weeks as the user scrolls through. While it would look like an infinite scroll, the ScrollView holds only 3 weeks at any given moment: previous, current and next.

tyricec commented 6 years ago

I understand that.

Do you think the swiping would be a prop that the user must pass to enable?

peacechen commented 6 years ago

It would be best to offer it as an option. A scroll wrapper could be instantiated if the prop is set, otherwise return the regular CalendarStrip. It could look something like:

render() {
  return (
    props.swipeable ?
      <CalendarWeek ... />
      :
      <SwipeableCalendarWeek ... />
  )
}

There would need to be some wiring between the swipeable week and the header, etc.

FaiChou commented 6 years ago

@peacechen Will swipeable in the next commit?

peacechen commented 6 years ago

If someone submits a PR, it will most likely be included in the next release.

FaiChou commented 6 years ago

I just see this contribute PR. @peacechen

peacechen commented 6 years ago

@FaiChou Thanks for reminding me about the PR. The author hasn't followed up on the changes requested in the comment thread of that PR. Would you mind trying it out?

FaiChou commented 6 years ago

I tried myself, it's a bad user experience and sure we need a big refactor to accomplish the swipe feature.

FaiChou commented 6 years ago

@peacechen @basequatro

Hi, I just release my custom calendar strip. It using horizontal FlatList to support swipe feature. Watch this video to check it.

Just a beta version, anyone can help me to support custom style for my component?

peacechen commented 6 years ago

That looks quite nice @FaiChou

It's always a tough decision how to integrate features. A lot of work has been put into this library, and I hesitate to have to reinvent that wheel. It's not only the features, but all the bug fixes that go along with it. My preference would be to merge your FlatList implementation into this library. The left/right arrows are useful as an alternative to swiping because some use cases may not allow for horizontal swiping (e.g. the app uses horizontal gestures for other actions).

FaiChou commented 6 years ago

@peacechen OK, one more thing, leave moment pick datefns up.

peacechen commented 6 years ago

date-fns looks nice. Is there a good way to support both Moment JS and date-fns? A lot of people are using Moment JS and this library supported that from the beginning.

FaiChou commented 6 years ago

@peacechen Change all component moment API to Date will work.

peacechen commented 6 years ago

It's not that simple. People are using Moment JS localization with this library. https://github.com/BugiDev/react-native-calendar-strip#localization

psolom commented 6 years ago

@peacechen I agree, the arrows may be useful, so the best option seems to make both features optional: arrows AND/OR swipe gesture. As you suggested above, can be split into 2 components.

Any chances this feature will be implemented?

peacechen commented 6 years ago

I haven't had time to port the FaiChou's swiping calendar. If anyone's started work on it, please post here and when you plan to submit a PR. If some time opens up, I'll give it a go.

psolom commented 6 years ago

FaiChou's swiping calendar have issues while prepending new dates dynamically. Mostly due to a lack of required features of FlatList, which is also quite buggy at this point. Since I have a high demand in this feature I'm going to put some efforts to make swiping possible along with switching (optional). I will create a PR if I will manage to handle it.

FaiChou commented 6 years ago

@servocoder Can you tell more about dynamic prepending dates issue? Also receive discuss and pr on my little project. 😊

psolom commented 6 years ago

@FaiChou when you swipe right (to load prev dates) FloatList sometimes doesn't perform scrollTo(Index) correct. The cause of this is that FlatList is not able to keep page number (index) while scrolling on Android. There is no robust solution for this. I have been played with FlatList a lot and made it much better and smoother, but you can still run into the issue if swipe too intense.

@peacechen (and others, who are interested in the swipe feature) The feature is ready. I had to rewrite a lot and despite I did my best to keep compatibility with existing features, properties and methods, and spent a lot of time for testing, I could miss something. You should keep this in mind. Also new properties are provided, for example swiperEnabled, shouldAllowDateSelection, responsiveContainerDayRatio.

The question is: @peacechen are you ready to spend some time to play with new features, test the consistence and merge such an amount of modifications into the master branch? Or you can create a separate branch and, even if you will never merge it, it will be available for others.

peacechen commented 6 years ago

That's great to hear @servocoder

It would be best to have two separate Week sub-components. One is the original as-is, the second is the newer swipe week component. Which one gets instantiated is controlled by a prop such as swipeable={true}. That way the original behavior will continue to work for those need it for production, while others can opt to use the "beta" swipeable component and wring out the bugs.

There are use cases for both so it's worth keeping them both. Some apps may already use horizontal swiping action for something else, so the swipeable calendar would interfere with that. Those use cases would opt for the original non-swiping calendar.

psolom commented 6 years ago

This is not not possible unfortunately. While I was working at swipe feature I found that many methods and properties are common and, in the same time, they require some refactoring to be able to handle both "switch" and "swipe" features. I ended up in refactoring of many methods and splitting is not the way to go. But if you create a separate branch I can create PR to this branch. This new branch will be "experimental". You may call it "swipable" or even "v2", it's up to you.

peacechen commented 6 years ago

"Anything is possible in software" -- Unknown attribution ;)

I created the branch swipeable for you. Thanks @servocoder for working on this

ifaketraveler commented 5 years ago

Any update on this? As far as I see, the branch swipeable doesn't seem to include this feature yet..

FaiChou commented 5 years ago

@ifaketraveler hi, check my project https://github.com/FaiChou/react-native-slideable-calendar-strip.

Hope it helps.

ifaketraveler commented 5 years ago

@FaiChou I'm concerned with the issue opened here. https://github.com/FaiChou/react-native-slideable-calendar-strip/issues/1#issue-332696138. I haven't tried it out myself but is this solved?

vandiepbui commented 5 years ago

@FaiChou have you fixed above problem yet?

FaiChou commented 5 years ago

@vandiepbui

do you mean this project? 👉 https://github.com/FaiChou/react-native-slideable-calendar-strip

vandiepbui commented 5 years ago

@FaiChou Yes. I build an app using swipeable calendar, so I find your project.

vandiepbui commented 5 years ago

@FaiChou thanks so much. I think it's great. But I have just tested it on Android. And I think you should use flex for each date container. It will be responsive when rotate device screen instead of using width/7.

peacechen commented 4 years ago

I was able to implement the swipeable feature at long last. It took a lot of effort and time to get it working well. I paired RecyclerListView with custom data shifting code to create a bi-directional infinite scroller. In between, the CalendarDay logic needed to be refactored to make it self-contained and less intermingled with the root component. The example folder contains a sample app that you can quickly try out.

This has been published in the 2.0.0 release.

psolom commented 4 years ago

Great, it was must have!

Although I can see some problems and have few proposals for the swipe feature:

1) startingDate works incorrect when scrollable is enabled. Case: startingDate set to Mon is fine in regular mode, but in scrollable mode week starts from Wed.

2) it would we good to add option that controls arrows visibility, so one'd be able to hide arrows in scrollable mode

3) feature that I most expect: capability to swipe with momentum (as FlatList does), so that swiping would be performed week by week, opposite to the infinite smooth scrolling, as it's implemented. I guess such a FlatList implementation may simplify scrolling, because now, once scrollable is enabled, the calendar component feels clumsy: long loading with with some unwelcome re-renders. As a positive side effect it will be a possibility to use onWeekChanged() callback properly.

Thanks for your work!

peacechen commented 4 years ago

Thanks for the feedback @psolom

  1. Are you setting the useIsoWeekday prop?
  2. The left/right selectors may be hidden by passing [] to leftSelector & rightSelector. https://github.com/BugiDev/react-native-calendar-strip#icon-sizing
  3. My first attempt at implementing the scrollable feature was with FlatList. Unfortunately it was a disaster due to its primitive scroll position reporting and repositioning. As the data grew larger during scrolling, it caused severe performance problems.

The current implementation is far from perfect. I'd like to see RecyclerListView support linked lists instead of arrays in order to enable true seamless infinite scrolling. That's a major change and dependent on their resource commitment. It may not be feasible since RLV uses ScrollView under the covers.

I encourage you to open PRs and issues for the scrollable feature. There's an issue open currently that could use an extra set of eyes on.

ChristopherDcosta commented 2 years ago

Is there any way I can put the left and the right arrows corresponding to the months name and not to the days name?