Commit 4e56173b authored by MrMan's avatar MrMan

Better but more complicated route-triggered loader animation

parent b081fa10
......@@ -213,7 +213,7 @@ EmailService.prototype.oneOrMoreEmailsChecked = function(opts) {
};
EmailService.prototype.getEmails = function() {
var randomWaitMs = Math.floor(Math.random() * 10) * 1000;
var randomWaitMs = 1000 + Math.floor(Math.random() * 3) * 1000;
return new Promise(function(resolve, reject) {
// After some random wait, return the global EMAILS we've always used
......@@ -551,26 +551,58 @@ var LoadingIndicator = {
},
};
var InboxMail = {
oninit: function() {
this.emailsLoaded = false;
EMAIL_SVC
.getEmails()
.then(emails => {
this.emails = emails;
this.emailsLoaded = true;
m.redraw(); // would love to only subtree render here...
var WithRouteTriggeredLoader = {
oninit: function(vnode) {
this.loadFn = vnode.attrs.loadFn;
this.requestInFlight = false;
this.refetchOnUpdate = true;
if ("refetchOnUpdate" in vnode.attrs) { this.refetchOnUpdate = vnode.attrs.refetchOnUpdate; }
// Trigger initial fetch
this.fetchAndRedraw();
},
fetchAndRedraw: function() {
this.loaded = false;
this.loadedData = null;
// Trigger redraw with emptied data
m.redraw();
this.requestInFlight = true;
(this.loadFn ? this.loadFn() : Promise.resolve())
.then(data => {
this.requestInFlight = false;
this.loadedData = data;
this.loaded = true;
this.currentRoute = m.route.get();
m.redraw();
});
},
view: function(vnode) {
var newCount = vnode.attrs.newCount;
onupdate: function(vnode) {
var newRoute = m.route.get();
var currentRoute = this.currentRoute;
var listing = m(LoadingIndicator, {title: "Loading your emails..."});
if (this.emailsLoaded) {
listing = m(EmailList, {emails: this.emails});
// If the route has been updated & refetching on update is turned on then re load
if (newRoute != currentRoute && this.refetchOnUpdate && !this.requestInFlight) {
this.fetchAndRedraw();
}
},
view: function(vnode) {
var loader = m(LoadingIndicator, {title: vnode.attrs.title});
return m(".component.with-loader", [
this.loaded ? vnode.attrs.childFn(this.loadedData) : loader
]);
},
};
var InboxMail = {
view: function(vnode) {
var newCount = vnode.attrs.newCount;
var emails = vnode.attrs.emails;
return m(".component.inbox-rhs", [
// Colored header
......@@ -580,7 +612,7 @@ var InboxMail = {
m(MailPageSubNav),
// EmailList
listing,
m(EmailList, {emails: vnode.attrs.emails}),
]);
}
};
......@@ -597,7 +629,7 @@ var StarredMail = {
m(MailPageSubNav),
// EmailList
m(EmailList, {emails: EMAILS}),
m(EmailList, {emails: vnode.attrs.emails}),
]);
}
};
......@@ -614,7 +646,7 @@ var DraftMail = {
m(MailPageSubNav),
// EmailList
m(EmailList, {emails: EMAILS}),
m(EmailList, {emails: vnode.attrs.emails}),
]);
}
};
......@@ -631,7 +663,7 @@ var ImportantMail = {
m(MailPageSubNav),
// EmailList
m(EmailList, {emails: EMAILS}),
m(EmailList, {emails: vnode.attrs.emails}),
]);
}
};
......@@ -646,8 +678,52 @@ var MainLayout = {
};
m.route(document.body, "/inbox", {
"/inbox": {render: function() { return m(MainLayout, m(InboxMail)); }},
"/starred": {render: function() { return m(MainLayout, m(StarredMail)); }},
"/draft": {render: function() { return m(MainLayout, m(DraftMail)); }},
"/important": {render: function() { return m(MainLayout, m(ImportantMail)); }},
"/inbox": {
render: function() {
return m(MainLayout, m(WithRouteTriggeredLoader, {
title: "Loading inbox...",
// This function provides the data
loadFn: function() { return EMAIL_SVC.getEmails(); },
// This function provides the component to WithRouteTriggeredLoader
childFn: function(data) { return m(InboxMail, {emails: data}); }
}));
}
},
"/starred": {
render: function() {
return m(MainLayout, m(WithRouteTriggeredLoader, {
title: "Loading starred emails...",
// This function provides the data
loadFn: function() { return EMAIL_SVC.getEmails(); },
// This function provides the component to WithRouteTriggeredLoader
childFn: function(data) { return m(StarredMail, {emails: data}); }
}));
}
},
"/draft": {
render: function() {
return m(MainLayout, m(WithRouteTriggeredLoader, {
title: "Loading draft emails...",
// This function provides the data
loadFn: function() { return EMAIL_SVC.getEmails(); },
// This function provides the component to WithRouteTriggeredLoader
childFn: function(data) { return m(DraftMail, {emails: data}); }
}));
}
},
"/important": {
render: function() {
return m(MainLayout, m(WithRouteTriggeredLoader, {
title: "Loading important emails...",
// This function provides the data
loadFn: function() { return EMAIL_SVC.getEmails(); },
// This function provides the component to WithRouteTriggeredLoader
childFn: function(data) { return m(ImportantMail, {emails: data}); }
}));
}
},
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment