Skip to content

Instantly share code, notes, and snippets.

@ejamesc
Last active November 29, 2015 09:25
Show Gist options
  • Select an option

  • Save ejamesc/61488d49919110049610 to your computer and use it in GitHub Desktop.

Select an option

Save ejamesc/61488d49919110049610 to your computer and use it in GitHub Desktop.
moi first mithril app
var ModalWidget = {
view: function(ctrl, opts) {
return m(".modal", [
m(".modal-dialog", [
m(".modal-header", [
m("h2", opts.title)]),
m(".modal-body", [m("input[type=text]", {placeholder: "http://", oninput: m.withAttr("value", opts.pastedUrl), value: opts.pastedUrl()}),
!opts.validUrl() ? m(".valid-message", [m("em", "Hey, that's not a valid URL!")]) : null,
].concat(opts.body)),
m("a.close[href=javascript:;]", {onclick: function(e) {
setTimeout(function() {
opts.nullify();
m.redraw();
}, 50);
}}, m.trust("×")),
m(".modal-footer", [
m("a.add[href=javascript:;]",
{onclick: opts.save}, m.trust("Save it! →"))
])
])
]);
},
};
var NotificationPane = {
view: function(ctrl, opts) {
return m(".notification", [
opts.error() ? m(".error", opts.msg()) : m(".success", opts.msg())
]);
},
};
var SourceAddButtonWidget = {
url: "/api/source",
validateURL: function(urltext) {
// Taken from @dperini, https://gist.github.com/dperini/729294
return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(urltext);
},
controller: function() {
var ctrl = {};
var _pastedUrl;
ctrl.modal = null;
ctrl.validUrl = m.prop(true);
ctrl.pastedUrl = function(value) {
if (arguments.length > 0) {
ctrl.validUrl(SourceAddButtonWidget.validateURL(value.trim()));
_pastedUrl = value;
m.redraw();
}
if (value === "") {
ctrl.validUrl(true);
}
return _pastedUrl;
};
ctrl.pastedUrl("");
ctrl.notify = m.prop(false);
ctrl.error = m.prop(false);
ctrl.message = m.prop("");
ctrl.notifyTimer = null;
ctrl.nullify = function() {
ctrl.modal = null;
};
ctrl.save = function() {
if (!ctrl.validUrl()) {
return;
}
ctrl.modal = null;
// We don't want to issue a request if the pastedUrl is empty.
if (!ctrl.pastedUrl()) return;
var data = {
url: ctrl.pastedUrl(),
};
var checkHttpStatus = function(xhr){
if(xhr.status >= 300){
ctrl.failure(xhr.status);
return JSON.stringify(xhr.responseText);
}
return xhr.responseText;
};
m.request({method: 'POST',
url: SourceAddButtonWidget.url,
data: data,
extract: checkHttpStatus}).then(ctrl.success);
};
ctrl.success = function(res) {
ctrl.notify(true);
ctrl.error(false);
ctrl.message("New link saved!");
ctrl.pastedUrl("");
ctrl.cleanupNotification();
};
ctrl.failure = function(res) {
ctrl.notify(true);
ctrl.error(true);
ctrl.message("We couldn't save that link, sorry. :(");
ctrl.cleanupNotification();
};
ctrl.cleanupNotification = function () {
if (ctrl.notifyTimer) {
clearTimeout(ctrl.notifyTimer);
}
ctrl.notifyTimer = setTimeout(function() {
ctrl.notify(false);
ctrl.notifyTimer = null;
m.redraw();
}, 5000);
};
return ctrl;
},
view: function(vm) {
return [
m("a[href=javascript:;].add-button", {onclick: function(e) {
vm.modal = {
title: 'Add link', body: []
};
}}, "+"),
vm.modal ? m.component(ModalWidget, {
title: vm.modal.title,
body: vm.modal.body,
nullify: vm.nullify,
save: vm.save,
pastedUrl: vm.pastedUrl,
validUrl: vm.validUrl,
}) : null,
vm.notify() ? m.component(NotificationPane, {
error: vm.error, msg: vm.message
}) : null,
];
},
};
m.module(document.getElementsByClassName('add-button-placeholder')[0], SourceAddButtonWidget);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment