Commit 44a71dd5 authored by MrMan's avatar MrMan

Write enough SystemJS integration to get inbox to show

parent 1d7af6ca
This diff is collapsed.
var EmailListItem = {
/* global System */
System.register([
"../services/email.js",
], function(exportModule, moduleCtx) {
return {
execute: function() {
Promise.all([
moduleCtx.import("../services/email.js",)
]).then(function(deps) {
var EmailSvc = deps.shift().service;
var ELLIPSIS_CHAR_LIMIT = 60;
var EmailListItem = {
view: function(vnode) {
var email = vnode.attrs.email;
var textContent = email.text || "";
var formattedSendDate = email.sendDate.toLocaleString();
var isSelected = EMAIL_SVC.getEmailSelectedStatusById(email.id);
var isChecked = EMAIL_SVC.getEmailCheckedStatusById(email.id);
var isSelected = EmailSvc.getEmailSelectedStatusById(email.id);
var isChecked = EmailSvc.getEmailCheckedStatusById(email.id);
var additionalClasses = [];
if (isSelected) { additionalClasses.push("selected"); }
......@@ -14,14 +27,14 @@ var EmailListItem = {
".component.email-list-item.clickable",
{
class: additionalClasses.join(" "),
onclick: function() { EMAIL_SVC.toggleSelectionStatusById(email.id); }
onclick: function() { EmailSvc.toggleSelectionStatusById(email.id); }
},
[
m(".header", [
m(".lhs", [
m("input[type=checkbox]", {
checked: isChecked,
onclick: function() { EMAIL_SVC.toggleCheckedStatusById(email.id); }
onclick: function() { EmailSvc.toggleCheckedStatusById(email.id); }
}),
m("span.sm-margin-left.sender", email.from.name),
m("span.sm-margin-left.tag", email.label),
......@@ -40,10 +53,9 @@ var EmailListItem = {
]);
}
};
};
var EmailList = {
var EmailList = {
oninit: function() {
this.selectedEmails = {};
},
......@@ -58,4 +70,12 @@ var EmailList = {
});
}));
}
};
};
exportModule({component: EmailList});
});
},
};
});
var InboxMail = {
/* global System */
System.register([
"./rhs-header.js",
"./mail-page-subnav.js",
"./email-list.js",
], function(exportModule, moduleCtx) {
return {
execute: function() {
Promise.all([
moduleCtx.import("./rhs-header.js"),
moduleCtx.import("./mail-page-subnav.js"),
moduleCtx.import("./email-list.js"),
])
.then(function(deps) {
var RHSHeader = deps.shift().component;
var MailPageSubNav = deps.shift().component;
var EmailList = deps.shift().component;
var InboxMail = {
view: function(vnode) {
var newCount = vnode.attrs.newCount;
var emails = vnode.attrs.emails;
......@@ -14,4 +33,10 @@ var InboxMail = {
m(EmailList, {emails: vnode.attrs.emails}),
]);
}
};
};
exportModule({component: InboxMail});
});
},
};
});
var HeaderButton = {
/* global m, System */
System.register([], function(exportModule, moduleCtx) {
return {
execute: function() {
var LHS_NAV_ITEMS = [
{
title: "Inbox",
iconImgSrc: "static/images/icons/inbox-white.svg",
badgeCSSBgColor: "#2285c6",
badgeContent: 2,
route: "/inbox",
},
{
title: "Starred",
iconImgSrc: "static/images/icons/star-full-white.svg",
route: "/starred",
},
{
title: "Draft",
iconImgSrc: "static/images/icons/file-line-white.svg",
route: "/draft",
},
{
title: "Important",
iconImgSrc: "static/images/icons/exclamation-triangle-white.svg",
route: "/important",
},
];
var LHS_LABEL_ITEMS = [
{
title: "Work",
badgeCSSBgColor: "#02bfc0",
badgeEmptySquare: true,
},
{
title: "Private",
badgeCSSBgColor: "#f9d47b",
badgeEmptySquare: true,
},
{
title: "Priority",
badgeCSSBgColor: "#9391e5",
badgeEmptySquare: true,
},
];
var HeaderButton = {
view: function(vnode) {
var text = vnode.attrs.title || "Compose Mail";
var iconName = vnode.attrs.iconName || "pencil-white.svg";
......@@ -9,17 +63,17 @@ var HeaderButton = {
m("img", {class: "sm-margin-left icon", src: iconPrefix + iconName }),
]);
}
};
};
var LHSNavHeader = {
var LHSNavHeader = {
view: function() {
return m("header", [
m(HeaderButton),
]);
}
};
};
var Badge = {
var Badge = {
view: function(vnode) {
var styles = [];
var content = vnode.attrs.content || "";
......@@ -36,9 +90,9 @@ var Badge = {
return m("div", {class: classes.join(" "), style: combinedStyles}, content);
}
};
};
var NavItem = {
var NavItem = {
view: function(vnode) {
var data = vnode.attrs.data || {};
var title = data.title || "Placeholder";
......@@ -78,10 +132,10 @@ var NavItem = {
},
}, children);
}
};
};
var NavItemListing = {
var NavItemListing = {
view: function(vnode) {
var navItems = vnode.attrs.items || [];
var children = navItems.map(function(i) {
......@@ -90,9 +144,9 @@ var NavItemListing = {
return m("ul", {class: "component nav-item-listing"}, children);
}
};
};
var LHSNavPageList = {
var LHSNavPageList = {
view: function() {
// Mark the nav items with the correct selected property
var currentPath = m.route.get();
......@@ -103,16 +157,16 @@ var LHSNavPageList = {
return m(NavItemListing, {items: navItems});
}
};
};
var LHSNavLabelList = {
var LHSNavLabelList = {
view: function() {
var labelItems = LHS_LABEL_ITEMS;
return m(NavItemListing, {items: labelItems});
}
};
};
var LHSNav = {
var LHSNav = {
view: function() {
return m("div", {class: "component lhs-nav"}, [
m(LHSNavHeader),
......@@ -123,4 +177,10 @@ var LHSNav = {
m("hr"),
]);
}
};
};
// SystemJS export
exportModule({component: LHSNav});
},
};
});
var MultiSelectCheckbox = {
System.register([
"../services/email.js",
], function(exportModule, moduleCtx) {
return {
execute: function() {
Promise.all([
moduleCtx.import("../services/email.js",)
]).then(function(deps) {
var EmailSvc = deps.shift().service;
var MultiSelectCheckbox = {
view: function(vnode) {
var allEmailsChecked = vnode.attrs.allEmailsChecked;
var oneOrMoreEmailsChecked = vnode.attrs.oneOrMoreEmailsChecked;
......@@ -15,8 +25,8 @@ var MultiSelectCheckbox = {
if (oneOrMoreEmailsChecked) { selectionText = "Clear Selection"; }
if (allEmailsChecked) { selectionText = "Unselect All"; }
var clickHandler = function() { EMAIL_SVC.checkAllEmails(); };
if (allEmailsChecked || oneOrMoreEmailsChecked) { clickHandler = function() { EMAIL_SVC.clearCheckedEmails(); }; }
var clickHandler = function() { EmailSvc.checkAllEmails(); };
if (allEmailsChecked || oneOrMoreEmailsChecked) { clickHandler = function() { EmailSvc.clearCheckedEmails(); }; }
return m(
"span.component.multi-select-checkbox.gray-boxed.clickable",
......@@ -28,15 +38,15 @@ var MultiSelectCheckbox = {
]),
]);
}
};
};
var ButtonGroup = {
var ButtonGroup = {
view: function(vnode) {
return m("span.component.button-group", {class: vnode.attrs.class}, vnode.children);
}
};
};
var DropDownButton = {
var DropDownButton = {
view: function(vnode) {
var title = vnode.attrs.title || "Button";
......@@ -45,9 +55,9 @@ var DropDownButton = {
m("img.xs-margin-left.icon", {src: "static/images/icons/chevron-down.svg"}),
]);
}
};
};
var PaginationControls = {
var PaginationControls = {
view: function(vnode) {
var title = vnode.attrs.title || "Button";
var lowerBound = 0;
......@@ -63,12 +73,12 @@ var PaginationControls = {
m("img.xs-margin-left.icon-lg.gray-boxed.valign-mid", {src: "static/images/icons/chevron-right.svg"}),
]);
}
};
};
var MailPageSubNav = {
var MailPageSubNav = {
view: function(vnode) {
var allEmailsChecked = EMAIL_SVC.allEmailsChecked();
var oneOrMoreEmailsChecked = EMAIL_SVC.oneOrMoreEmailsChecked();
var allEmailsChecked = EmailSvc.allEmailsChecked();
var oneOrMoreEmailsChecked = EmailSvc.oneOrMoreEmailsChecked();
// Container with buttons
return m(".component.mail-page-subnav", [
......@@ -95,4 +105,11 @@ var MailPageSubNav = {
]),
]);
},
};
};
exportModule({component: MailPageSubNav});
});
},
};
});
var MainLayout = {
/* global System */
System.register([
// Declare dependencies
"./lhs-nav.js"
], function(exportModule, moduleCtx) {
return {
execute: function() {
// Import the module from this module's context
moduleCtx
.import("./lhs-nav.js")
.then(function(LHSNavModule) {
var LHSNav = LHSNavModule.component;
// Use all the imports to actualy do work
var MainLayout = {
view: function(vnode) {
return m(".component.app-page.important-page", [
m(LHSNav),
vnode.children,
]);
},
};
};
// SystemJS export
exportModule({component: MainLayout});
return Promise.resolve();
});
},
};
});
var RHSHeader = {
/* global System */
System.register([], function(exportModule) {
return {
execute: function() {
var RHSHeader = {
view: function(vnode) {
var title = vnode.attrs.title || "Title";
var bgColor = vnode.attrs.bgColor || "#2285c6";
......@@ -17,4 +22,9 @@ var RHSHeader = {
])
]);
}
};
};
exportModule({component: RHSHeader});
},
};
});
var LoadingIndicator = {
/* global System */
System.register([], function(exportModule, moduleCtx) {
return {
execute: function() {
var LoadingIndicator = {
view: function(vnode) {
var title = vnode.attrs.title || "Loading...";
......@@ -7,10 +12,10 @@ var LoadingIndicator = {
m(".title", title),
]);
},
};
};
var WithRouteTriggeredLoader = {
var WithRouteTriggeredLoader = {
oninit: function(vnode) {
this.loadFn = vnode.attrs.loadFn;
this.requestInFlight = false;
......@@ -56,4 +61,10 @@ var WithRouteTriggeredLoader = {
this.loaded ? vnode.attrs.childFn(this.loadedData) : loader
]);
},
};
};
// SystemJS export
exportModule({component: WithRouteTriggeredLoader});
},
};
});
......@@ -9,26 +9,10 @@
</head>
<body>
<script src="static/vendor/mithril/1.1.6/mithril.min.js"></script>
<script src="static/vendor/s.min.js"></script>
<!-- LHS nav -->
<script src="components/lhs-nav.js"></script>
<!-- Shared by components on the right hand side of the page (i.e. email listing pages) -->
<script src="components/mail-page-subnav.js"></script>
<script src="components/loading-indicator.js"></script>
<script src="components/email-list.js"></script>
<script src="components/rhs-header.js"></script>
<script src="components/with-route-triggered-loader.js"></script>
<!-- email listing pages, they're used directly from app.js -->
<script src="components/inbox-mail.js"></script>
<script src="components/draft-mail.js"></script>
<script src="components/important-mail.js"></script>
<script src="components/starred-mail.js"></script>
<!-- layout used directly from app.js, I'd *like* for it to be separate -->
<script src="components/main-layout.js"></script>
<script src="app.js"></script>
<script type="text/javascript">
System.import("./app.js");
</script>
</body>
</html>
......@@ -10,9 +10,9 @@
"scripts": {
"build": "npm run build-static && npm run build-html && npm run build-js",
"build-html": "cp index.html dist/",
"build-js": "cp app.js dist/ && cp -r components dist/",
"build-js": "cp app.js dist/ && cp -r components dist/ && cp -r services dist/",
"build-static": "mkdir -p dist && cp -r static dist/",
"build-watch": "ls index.html app.js static/css/app.css | entr -rc npm run build",
"build-watch": "ls index.html app.js static/css/app.css components/* services/* | entr -rc npm run build",
"serve": "./node_modules/.bin/http-server dist/",
"serve-watch": "ls index.html app.js static/css/app.css | entr -rc bash -c 'npm run build && npm run serve'"
},
......
/* global m, System */
System.register([], function(exportModule) {
return {
execute: function() {
var ONE_MINUTE_MS = 1000 * 60;
var ONE_HOUR_MS = 60 * ONE_MINUTE_MS;
var ONE_DAY_MS = 24 * ONE_HOUR_MS;
var ONE_WEEK_MS = 27 * ONE_DAY_MS;
function randomPastDate() {
var mins = Math.floor(Math.random() * 60) * ONE_MINUTE_MS;
var hours = Math.floor(Math.random() * 24) * ONE_HOUR_MS;
var days = Math.floor(Math.random() * 7) * ONE_DAY_MS;
return new Date(new Date().getTime() - mins - hours - days);
}
var EMAILS = [
{
id: "QyLruCuUQ4SOy0JTkOuJ3VdOk8HbDuw3",
from: {name: "Victor Erixon", email: "victor.erixon@example.com"},
subject: "Theories of Design",
text: "Molestias deserunt veritatis modi ut fugiat sint. Dolorum vel autem sint. Dolores accusamus dolores occaecati tenetur adipisci asperiores",
sendDate: randomPastDate(),
},
{
id: "KpjgJQT8nIBdLj1NCjCPPvZJBtzhhixn",
from: {name: "Jacob Hubertus", email: "jacob.hubertus@example.com"},
subject: "Street Photography",
text: "Molestias deserunt veritatis modi ut fugiat sint. Dolorum vel autem sint. Dolores accusamus dolores occaecati tenetur adipisci asperiores",
sendDate: randomPastDate(),
},
{
id: "JiTTyuQ2XUakNd6xSeolyoWEpeNjOwJi",
from: {name: "August Berglund", email: "august.berglund@example.com"},
subject: "HTML+CSS Tutorials?",
text: "Molestias deserunt veritatis modi ut fugiat sint. Dolorum vel autem sint. Dolores accusamus dolores occaecati tenetur adipisci asperiores",
sendDate: randomPastDate(),
},
{
id: "XlwnoP5EUNiauVn8anBba1Ui2NeSwUCg",
from: {name: "Rick Brunstedt", email: "rick.brunstedt@example.com"},
subject: "Train Crossing",
text: "Molestias deserunt veritatis modi ut fugiat sint. Dolorum vel autem sint. Dolores accusamus dolores occaecati tenetur adipisci asperiores",
sendDate: randomPastDate(),
},
{
id: "w5smg1YFSo9ANXZQe56bQkNxcX1mJK16",
from: {name: "Webydo Team", email: "team@webydo.com"},
subject: "Does Webydo have what you're looking for? ",
text: "Molestias deserunt veritatis modi ut fugiat sint. Dolorum vel autem sint. Dolores accusamus dolores occaecati tenetur adipisci asperiores",
sendDate: randomPastDate(),
},
];
EMAILS = EMAILS.sort(function(a, b) {
var aTime = a.sendDate.getTime();
var bTime = b.sendDate.getTime();
if (aTime < aTime) { return -1; }
if (bTime > bTime) { return 1; }
return 0;
});
/**
* Email service that will manage checking
*
* Note: Mithril can't redraw subtrees yet (https://github.com/MithrilJS/mithril.js/issues/1907), so m.redraw() is everywhere
*/
function EmailService() {
this.selectedEmailId = null;
this.checkedEmailIds = {};
this._allEmailsChecked = false;
}
EmailService.prototype.selectEmailById = function(id, opts) {
if (!id) { throw new Error("Invalid email object, ID is missing"); }
console.log("[email-svc] selected email with id:", id);
this.selectedEmailId = id;
if (opts && opts.redraw) { m.redraw(); }
};
EmailService.prototype.resetSelectedEmailId = function(opts) {
this.selectedEmailId = null;
if (opts && opts.redraw) { m.redraw(); }
};
EmailService.prototype.toggleSelectionStatusById = function(id, opts) {
if (!id) { throw new Error("Invalid email object, ID is missing"); }
// Reset if currently selected and exit early
if (this.getEmailSelectedStatusById(id)) {
this.resetSelectedEmailId();
return;
}
this.selectEmailById(id);
if (opts && opts.redraw) { m.redraw(); }
};
EmailService.prototype.getEmailSelectedStatusById = function(id) {
if (!id) { throw new Error("Invalid email object, ID is missing"); }
return this.selectedEmailId === id;
};
EmailService.prototype.checkEmailById = function(id, opts) {
if (!id) { throw new Error("Invalid email object, ID is missing"); }
console.log("[email-svc] checked email with id:", id);
this.checkedEmailIds[id] = true;
if (opts && opts.redraw) { m.redraw(); }
};
EmailService.prototype.resetEmailCheckedStatusById = function(id, opts) {
if (!id) { throw new Error("Invalid email object, ID is missing"); }
delete this.checkedEmailIds[id]; // This is kinda bad to do a lot
if (opts && opts.redraw) { m.redraw(); }
};
EmailService.prototype.toggleCheckedStatusById = function(id, opts) {
if (!id) { throw new Error("Invalid email object, ID is missing"); }
// Reset if currently selected and exit early
if (this.getEmailCheckedStatusById(id)) {
this.resetEmailCheckedStatusById(id);
return;
}
this.checkEmailById(id);
if (opts && opts.redraw) { m.redraw(); }
};
EmailService.prototype.getEmailCheckedStatusById = function(id) {
if (!id) { throw new Error("Invalid email object, ID is missing"); }
return this._allEmailsChecked ? true : id in this.checkedEmailIds;
};
EmailService.prototype.clearCheckedEmails = function(opts) {
this._allEmailsChecked = false;
this.checkedEmailIds = {};
console.log("[email-svc] cleared checked emails");
if (opts && opts.redraw) { m.redraw(); }
};
EmailService.prototype.checkAllEmails = function(opts) {
this._allEmailsChecked = true;
console.log("[email-svc] checked all emails");
if (opts && opts.redraw) { m.redraw(); }
};
EmailService.prototype.allEmailsChecked = function(opts) {
return this._allEmailsChecked;
};
EmailService.prototype.oneOrMoreEmailsChecked = function(opts) {
// Object.keys isn't supported on some IE browsers, but Mithril doesn't support older than IE11 anyway IIRC
return this._allEmailsChecked || Object.keys(this.checkedEmailIds).length > 0;
};
EmailService.prototype.getEmails = function() {
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
setTimeout(function() {
resolve(EMAILS);
}, randomWaitMs);
});
};
var EMAIL_SVC = new EmailService();
// SystemJS export
exportModule({service: new EmailService()});
},
};
});
!function(){const e="undefined"!=typeof self?self:global;let n;if("undefined"!=typeof location){const e=(n=location.href.split("#")[0].split("?")[0]).lastIndexOf("/");-1!==e&&(n=n.slice(0,e+1))}const t=/\\/g,r="undefined"!=typeof Symbol,i=r&&Symbol.toStringTag,o=r?Symbol():"@";function c(){this[o]={}}const l=c.prototype;let u;l.import=function(e,n){const t=this;return Promise.resolve(t.resolve(e,n)).then(function(e){const n=function e(n,t,r){let c=n[o][t];if(c)return c;const l=[],u=Object.create(null);i&&Object.defineProperty(u,i,{value:"Module"});let s=Promise.resolve().then(function(){return n.instantiate(t,r)}).then(function(e){if(!e)throw new Error("Module "+t+" did not instantiate");const r=e[1](function(e,n){c.h=!0;let t=!1;if("object"!=typeof e)e in u&&u[e]===n||(u[e]=n,t=!0);else for(let n in e){let r=e[n];n in u&&u[n]===r||(u[n]=r,t=!0)}if(t)for(let e=0;e<l.length;e++)l[e](u);return n},2===e[1].length?{import:function(e){return n.import(e,t)},meta:n.createContext(t)}:void 0);return c.e=r.execute||function(){},[e[0],r.setters||[]]});const f=s.then(function(r){return Promise.all(r[0].map(function(i,o){const c=r[1][o];return Promise.resolve(n.resolve(i,t)).then(function(r){const i=e(n,r,t);return Promise.resolve(i.I).then(function(){return c&&(i.i.push(c),!i.h&&i.I||c(i.n)),i})})})).then(function(e){c.d=e})});return f.catch(function(){}),c=n[o][t]={id:t,i:l,n:u,I:s,L:f,h:!1,d:void 0,e:void 0,eE:void 0,E:void 0,C:void 0}}(t,e);return n.C||function(e,n){return n.C=function e(n,t,r){if(!r[t.id])return r[t.id]=!0,Promise.resolve(t.L).then(function(){return Promise.all(t.d.map(function(t){return e(n,t,r)}))})}(e,n,{}).then(function(){return function e(n,t,r){if(r[t.id])return;if(r[t.id]=!0,!t.e){if(t.eE)throw t.eE;return t.E?t.E:void 0}let i;return t.d.forEach(function(t){{const o=e(n,t,r);o&&(i=i||[]).push(o)}}),i?t.E=Promise.all(i).then(o):o();function o(){try{let e=t.e.call(s);if(e)return e.then(function(){t.C=t.n,t.E=null}),e.catch(function(){}),t.E=t.E||e;t.C=t.n}catch(e){throw t.eE=e,e}finally{t.L=t.I=void 0,t.e=null}}}(e,n,{})}).then(function(){return n.n})}(t,n)})},l.createContext=function(e){return{url:e}},l.register=function(e,n){u=[e,n]},l.getRegister=function(){const e=u;return u=void 0,e};const s=Object.freeze(Object.create(null));let f;e.System=new c,"undefined"!=typeof window&&window.addEventListener("error",function(e){f=e.error});const d=l.register;l.register=function(e,n){f=void 0,d.call(this,e,n)},l.instantiate=function(e,n){const t=this;return new Promise(function(r,i){const o=document.createElement("script");o.charset="utf-8",o.async=!0,o.crossOrigin="anonymous",o.addEventListener("error",function(){i(new Error("Error loading "+e+(n?" from "+n:"")))}),o.addEventListener("load",function(){if(document.head.removeChild(o),f)return i(f);r(t.getRegister())}),o.src=e,document.head.appendChild(o)})},l.resolve=function(e,r){const i=function(e,n){if(-1!==e.indexOf("\\")&&(e=e.replace(t,"/")),"/"===e[0]&&"/"===e[1])return n.slice(0,n.indexOf(":")+1)+e;if("."===e[0]&&("/"===e[1]||"."===e[1]&&("/"===e[2]||2===e.length&&(e+="/"))||1===e.length&&(e+="/"))||"/"===e[0]){const t=n.slice(0,n.indexOf(":")+1);let r;if(r="/"===n[t.length+1]?"file:"!==t?(r=n.slice(t.length+2)).slice(r.indexOf("/")+1):n.slice(8):n.slice(t.length+("/"===n[t.length])),"/"===e[0])return n.slice(0,n.length-r.length-1)+e;const i=r.slice(0,r.lastIndexOf("/")+1)+e,o=[];let c=-1;for(let e=0;e<i.length;e++)-1!==c?"/"===i[e]&&(o.push(i.slice(c,e+1)),c=-1):"."===i[e]?"."!==i[e+1]||"/"!==i[e+2]&&e+2!==i.length?"/"===i[e+1]||e+1===i.length?e+=1:c=e:(o.pop(),e+=2):c=e;return-1!==c&&o.push(i.slice(c)),n.slice(0,n.length-r.length)+o.join("")}}(e,r||n);if(!i){if(-1!==e.indexOf(":"))return e;throw new Error('Cannot resolve "'+e+(r?'" from '+r:'"'))}return i}}();
\ No newline at end of file
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