var tid; var ractive; var model; var tiptid; var first; var log; function update() { ractive.set(model); } function reload_page(bypass) { if (!bypass) { debugger }; var param = "?t=" + new Date().getTime() % 1000; var hashach = document.location.hash; document.location = param + hashach; } function navigate(path) { path = path.substr(path.indexOf('#')); var split = path.split("/"); ractive.set("view.page.*", false); if (split.length >= 2) { ractive.set("view.page." + split[1], true); } else { ractive.set("view.page.welcome", true); } if (split.length >= 3) { var remote = split[2]; var remoteObj = UR.store.getRemoteById(remote); if (remoteObj) { selectRemote(remoteObj); showRemote(remoteObj); } else { ractive.set("view.page.welcome", true); ractive.set("remotes.*.active", false); tip("Missing remote " + remote); } } } function showRemote(remote) { var onRemoteLayout = function (layout) { var groups = UR.render.flattenLayout(layout); model.current_layout = layout; model.current_remote = remote; model.current_actions = groups; update(); UR.render.prettyRows(groups); update(); }; var onRemoteLoaded = function () { // Keep on working }; var old_remote = model.current_remote; if (old_remote) { UR.client.instance.stopRemote(old_remote); // Unload previous } UR.client.instance.startRemote(remote, onRemoteLayout, onRemoteLoaded); } function onRemoteEvent(events) { if (events.Error === "Not authorized") { ractive.set("view.connected", false); UR.client.instance.restart(); } if (events.length > 0) { _.forEach(events, function(event) { UR.events.publish(event, model.current_remote); }); } }; function selectRemote(remote) { _.forEach(model.remotes, function (r) { r.active = false; }); remote.active = true; update(); } function tip(s) { if (!ractive) return; ractive.set("view.tip", s); $(".tips").hide(); clearTimeout(tiptid); $(".tips").slideDown(100, function () { tiptid = setTimeout(function () { $(".tips").slideUp(100); }, 2000); }); } function onEvent(remote, event) { tip("Event from " + remote.id + ": " + event); return true; } var model = {}; $(document).ready(function () { first = true; log = ""; model = { year: new Date().getFullYear(), view: { disconnected: true, loading_remotes: true, tip: "", page: { welcome: false, login: false, remote: false, unauthorized: false, connecting: true } }, remotes: UR.store.getRemoteList(), current_remote: undefined, current_layout: undefined, current_actions: undefined, current_sync_queue: {}, element_child_style: function(arr) { return "width: " + (100 / arr.length) + "%"; }, init_onhold: function(obj) { setTimeout(function () { // This can be refactored by building a ractive event plugin UR.render.bindHold(obj, function () { UR.client.instance.sendAction(model.current_remote, obj.OnHold); }); }, 500); }, try_image: function(obj) { if (obj.Image) { return "data:image/jpeg;base64," + obj.Image; } else { return "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD//gATQ3JlYXRlZCB3aXRoIEdJTVD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wgARCAAKAAoDAREAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAj/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGqQAf/xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAEFAh//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAY/Ah//xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAE/IR//2gAMAwEAAgADAAAAEJJP/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAwEBPxAf/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAgEBPxAf/8QAFBABAAAAAAAAAAAAAAAAAAAAIP/aAAgBAQABPxAf/9k="; } } }; ractive = new Ractive({ el: "container", template: "#tmain", data: model }); $( window ).unload(function () { UR.client.instance.stop(model.current_remote); }); $(window).on('hashchange', function() { navigate(window.location.hash); ga('send', 'pageview', {'page': location.pathname + location.search + location.hash}); }); function addExtra(action, value) { action = _.cloneDeep(action); var values = {'Values': [{ 'Key': "0", 'Value': value }]}; var old_values = action['Extras']; action['Extras'] = _.merge(values, old_values, function(a, b) { return _.isArray(a) ? a.concat(b) : undefined; }); return action; } ractive.on({ simple_event: function(evt, action) { UR.client.instance.sendAction(model.current_remote, action); }, toggle_down: function(evt, on_down) { var down = UR.render.isChecked(evt.context); UR.render.setChecked(evt.context, !down); UR.client.instance.sendAction(model.current_remote, on_down); }, toggle_changed: function(evt, on_change, on_tap) { if (on_change !== undefined) { var down = $(evt.node).attr("data-down") === "yes"; var action_new = addExtra(on_change, down); UR.client.instance.sendAction(model.current_remote, action_new); } UR.client.instance.sendAction(model.current_remote, on_tap); }, slider_up: function (evt) { var obj = evt.context; var id = obj.ID; var value = Math.round(parseFloat(evt.node.value)); if (model.current_sync_queue[id] === "") { model.current_sync_queue[id] = undefined; } /* OnUp */ if (obj.OnUp) { var action_new = addExtra(obj.OnUp, value); UR.client.instance.sendAction(model.current_remote, action_new); } /* OnChange */ if (obj.OnChange) { var action_new = addExtra(obj.OnChange, value); UR.client.instance.sendAction(model.current_remote, action_new); } /* OnDone */ if (obj.OnDone) { var action_new = addExtra(obj.OnDone, value); UR.client.instance.sendAction(model.current_remote, action_new); } // Add value to sync queue, such that events in-between are ignored model.current_sync_queue[id] = value; // Invalidate event glitch lock after 2sec setTimeout(function () { model.current_sync_queue[id] = undefined; }, 2000); }, slider_down: function (evt) { var obj = evt.context; var id = obj.ID; var value = Math.round(parseFloat(evt.node.value)); model.current_sync_queue[id] = ""; /* OnDone */ if (obj.OnDone) { var action_new = addExtra(obj.OnDone, value); UR.client.instance.sendAction(model.current_remote, action_new); } }, login: function(evt, user, pass) { ractive.set("view.page.*", false); ractive.set("view.page.remote", true); UR.client.instance.onAuthentication(user, pass); }, input_keydown: function(evt) { if (evt.original.keyCode === 13) { // IF enter click data-target $("#" + $(evt.node).attr("data-target")).click(); } } }); UR.client.instance = UR.client.init(function () { //onConnected ractive.set("view.disconnected", false); ractive.set("view.loading_remotes", false); ractive.set("view.page.*", false); ractive.set("view.page.welcome", true); UR.client.instance.listenToEvents(onRemoteEvent); if (window.location.hash) { navigate(window.location.hash); } }, function () { //onLostConnection ractive.set("view.disconnected", true); ractive.set("view.loading_remotes", true); ractive.set("view.page.*", false); ractive.set("view.page.connecting", true); }, function (user) { //onAuthenticationNeed ractive.set("view.page.*", false); ractive.set("view.disconnected", true); ractive.set("view.loading_remotes", true); if (user) { ractive.set("view.page.login_user", true); } else { ractive.set("view.page.login_anonymous", true); } }, function () { //onUnauthorized ractive.set("view.disconnected", true); ractive.set("view.loading_remotes", true); ractive.set("view.page.*", false); ractive.set("view.page.unauthorized", true); }); });