// ==UserScript== // @name TagPro Talk // @namespace http://reddit.com/user/snaps_ // @description Talk in TagPro // @require https://gist.github.com/chrahunt/4843f0258c516882eea0/raw/loopback.user.js // @require https://craig.global.ssl.fastly.net/js/mousetrap/mousetrap.min.js // @downloadURL https://gist.github.com/chrahunt/todo // @include http://tagpro-*.koalabeast.com:* // @include http://maptest*.newcompte.fr:* // @include http://tangent.jukejuice.com:* // @license MIT // @author snaps // @version 0.1.0 // @grant GM_getResourceURL // @run-at document-start // ==/UserScript== var HTTPS_LINK = "https://rawgit.com/chrahunt/6ad88b678838fd1218f3/raw/9a2a66b109859bc601998ef4003cd39f6433b07c/listen.html"; var ORIGIN_REGEX = /^(.*?:\/\/.*?)\//; // 2-way frame communication, implements protocol. function Frame(url) { var iframe = document.createElement("iframe"); iframe.src = url; iframe.style.display = "none"; this.origin = url.match(ORIGIN_REGEX)[1]; this.listeners = {}; var self = this; // Introduce self. iframe.addEventListener("load", function () { self.target = iframe.contentWindow; self.send("init"); }, false); window.addEventListener("message", function (event) { var origin = event.origin || event.originalEvent.origin; if (origin !== self.origin || event.source !== self.target) return; var message = event.data; var name = message.name; console.log("Content: Message received: '" + name + "'"); if (self.listeners.hasOwnProperty(name)) { console.log("Content: Calling listeners."); self.listeners[name].forEach(function (fn) { fn(message.data); }); } else { console.log("Content: No listeners set"); } }); document.body.appendChild(iframe); } Frame.prototype.send = function(name, data) { var arg = { name: name }; if (typeof data !== "undefined") { arg.data = data; } this.target.postMessage(arg, this.origin); }; Frame.prototype.on = function(name, fn) { if (!this.listeners.hasOwnProperty(name)) { this.listeners[name] = []; } this.listeners[name].push(fn); }; Frame.prototype.removeListener = function(name, fn) { if (this.listeners.hasOwnProperty(name)) { var i = this.listeners[name].indexOf(fn); if (i !== -1) { this.listeners[name].splice(i, 1); } } }; function Messenger(socket) { this.socket = socket; } Messenger.prototype.send = function(msg) { this.socket.emit("chat", { message: msg.substring(0, 70), toAll: true }); }; // Listen for things to happen with these keys function KeyState(start, reset, send) { this.listening = false; } KeyState.prototype.onstart = function(fn) { // body... }; function showInfo(msg) { tagpro.socket.emit("local:chat", { to: "all", from: null, message: msg }); } // When key is pressed, start listening. As words come in, display in chat element look-alike. // When done, allow pressing enter to send. // or escape to stop // override tagpro hotkey functionality when active // stop listening only when disabled // if text at end of input, flash red. setTimeout(function setup() { // Wait for TagPro to get chat socket if (typeof tagpro == "undefined" || !tagpro.socket) { setTimeout(setup, 500); return; } var messenger = new Messenger(tagpro.socket); var frame = new Frame(HTTPS_LINK); var recognizing = false; var output = ""; Mousetrap.bind("ctrl+z", function (e) { if (recognizing) { console.log("Content: Stopping recognition."); frame.send("sr.stop"); if (output !== "") { console.log("Sending message: " + output); messenger.send(output); output = ""; } recognizing = false; } else { console.log("Content: Starting recognition."); frame.send("sr.start"); recognizing = true; } return false; }); var input = $("
"); var first = $(""); first.css({color: "white"}); var second = $(""); second.css({color: "gray"}); input.append(first); input.append(second); $("body").append(input); frame.on("sr.result", function (result) { first.text(result.final_transcript); output = result.final_transcript; second.text(result.interim_transcript); }); frame.on("sr.error", function (result) { console.log("SR error: %o", result); }); // initialize key listener // on keypress }, 50);