barba icon indicating copy to clipboard operation
barba copied to clipboard

Check if link has been prefetched successfully

Open TheFunkyMonk opened this issue 4 years ago • 2 comments

When using the @barba/prefetch plugin, new pages are usually ready to go before they're clicked on and I can transition them in. In the event they aren't ready, I would like to animate in a loading spinner so the user isn't left without feedback (though this should be bypassed if not needed).

Something like:

before: (data) => {
	// Only if page isn't ready yet
	if (!data.trigger.fetched) {
		// Animation sequence to load spinner
		// Once animation has completed, continue lifecycle
	}
},
enter: (data) => {
	// Entrance animation for new page
}

It seems the only way to currently do something similar to this would be to always trigger the entrance of the loading spinner in the before hook, and let the entrance of the new page fade in over the top of it, effectively obscuring it from view if it's not needed.

Though this sometimes leads to odd occurrences where the enter hook is ready to fire when the loader entrance has partially completed, so the user just sees a brief flash of the loader. It would be nice if the lifecycle progress could he halted for an animation in the before hook only if the prefetch hasn't completed yet.

TheFunkyMonk avatar Sep 26 '20 04:09 TheFunkyMonk

Hi @TheFunkyMonk,

Thanks for opening the issue. As discussed together on Slack, I am adding @thierrymichel and he will give you his opinion on this feature request.

Have a nice day :wink:

xavierfoucrier avatar Sep 28 '20 23:09 xavierfoucrier

Thanks @xavierfoucrier!

For clarity around what I'm asking, here is a workaround I've come up with that seems to work ok:

const initBarba = () => {
	let cachedPages = [];

	barba.use(barbaPrefetch);
	barba.init({
		transitions: [
			{
				before: (data) => {
					barba.cache.getRequest(data.trigger.href).then(() => {
						cachedPages.push(data.trigger.href);
					});
				},
				leave: (data) => {
					const showLoader = !cachedPages.includes(data.trigger.href);
					
					if (showLoader) {
						// Pause lifecycle to animate in loader
					}
				},
				enter: (data) => {
					// Pause lifecycle to animate in new page
				}
			}
		]
	});
}

Basically, in the before hook I'm hooking into the promise returned from barba.cache.getRequest(data.trigger.href) when an eligible link is clicked and manually adding it to an array of cached pages. Then I can check that array in the leave hook, similar to how you could just check barba.cache directly if you weren't using @barba/prefetch.

It would be nice if barba.cache.get(data.trigger.href) could also return a status according to whether the request promise had been fulfilled to avoid this workaround. Hopefully, that makes sense!

TheFunkyMonk avatar Sep 28 '20 23:09 TheFunkyMonk

@TheFunkyMonk Hi 👋

Sorry for the long long reply...

I will work on this soon, and I wanted to let you know that there are currently two possibilities for your use case:

  • use getRequest option
  • use sync option
  1. with the barba.cache.getRequest method you can obtain the current pending request from the Cache class, and act when the request is fulfilled:
let request;

barba.init({
  transitions: [{
    name: 'opacity-transition',
    before(data) {
      request = barba.cache.getRequest(data.next.url.href);
    },
    leave(data) {
      return request.then(() => {
        gsap.to(data.current.container, {
          opacity: 0
        });
      });
    },
    enter(data) {
      return gsap.from(data.next.container, {
        opacity: 0
      });
    },
  }],
});
  1. use the sync: true option in a transition, see sync mode:
barba.init({
  transitions: [{
    name: 'opacity-transition',
    sync: true,
    leave(data) {
      return gsap.to(data.current.container, {
        opacity: 0
      });
    },
    enter(data) {
      return gsap.from(data.next.container, {
        opacity: 0
      });
    },
  }],
});

Hope this is clear 😉

xavierfoucrier avatar Apr 26 '23 13:04 xavierfoucrier

Closed by #704.

xavierfoucrier avatar May 01 '23 21:05 xavierfoucrier