Twitter enabled web page slideshow
This flow is based almost entirely on https://flows.nodered.org/flow/8666510f94ad422e4765
It adds a Twitter user input (@archillect) extracts the https url of the posted media and feed said url to the websocket, so it can be displayed by the webpage available at 'http://{your-server-ip:1880/slideshow'
The image gets somewhat resized to the dimension of the browser window. It's not working 100% of the time i.e. with 16:10 aspect monitors the images get stretched too much, It's far from perfect, but it's a start. In the page template there's some javascript added so you can go fullscreen (but that gets resetted when the image changes) see: http://blogs.sitepointstatic.com/examples/tech/full-screen/index.html
It works quite well if you cast a tab of your browser to a chromecast, or if you have a spare tablet you can basically have a Twitter powered photo display.
[ { "id": "affb0fda.9189c", "type": "twitter in", "z": "fb5b6e33.9bc11", "twitter": "", "tags": "@archillect", "user": "user", "name": "", "topic": "tweets", "x": 170, "y": 60, "wires": [ [ "2ee36506.9e365a", "e27ad042.65f95" ] ] }, { "id": "e27ad042.65f95", "type": "change", "z": "fb5b6e33.9bc11", "name": "get tweet object", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "tweet", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 160, "y": 140, "wires": [ [ "62c28189.4ce19" ] ] }, { "id": "62c28189.4ce19", "type": "change", "z": "fb5b6e33.9bc11", "name": "get media https url", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "payload.entities.media[0].media_url_https", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 390, "y": 140, "wires": [ [ "b7450e85.a8207", "fc94d254.85dd1" ] ] }, { "id": "fc94d254.85dd1", "type": "websocket out", "z": "fb5b6e33.9bc11", "name": "", "server": "bc725200.1dc2d", "client": "", "x": 550, "y": 260, "wires": [] }, { "id": "8905b6ac.848648", "type": "http in", "z": "fb5b6e33.9bc11", "name": "", "url": "/slideshow", "method": "get", "swaggerDoc": "", "x": 140, "y": 200, "wires": [ [ "6864b831.fe7818" ] ] }, { "id": "6864b831.fe7818", "type": "template", "z": "fb5b6e33.9bc11", "name": "HTML Slideshow", "field": "payload", "fieldType": "msg", "format": "html", "syntax": "mustache", "template": "<!DOCTYPE HTML>\n<html>\n <head>\n <style>\n*\n{\n\tpadding: 0;\n\tmargin: 0;\n}\n\nhtml, body\n{\n\tfont-family: \"Segoe UI\", arial, helvetica, freesans, sans-serif;\n\tcolor: #333;\n\tbackground-color: #000;\n\toverflow-y: auto;\n\toverflow-x: auto;\n}\n\nbody\n{\n\tmargin: 0 auto;\n\tmax-height: 100%;\n max-width: 100%;\n}\n\np\n{\n\tmargin: 0 0 1em 0;\n}\n\nsection\n{\n\tdisplay: block;\n\tfloat: center;\n\tpadding: 0;\n\tmargin: 0 auto;\n\tborder: 0 none;\n\tcursor: pointer;\n\tmax-height: 100%;\n max-width: 100%;\n}\n\n\nsection img\n{\n\twidth: 100%;\n\theight: 100%;\n}\n\n\nsection p\n{\n\tfont-weight: bold;\n\ttext-align: center;\n\tmargin: 0;\n}\n\nsection:-webkit-full-screen\n{\n\tfloat: none;\n\twidth: 100%;\n\theight: 100%;\n\tpadding: 0;\n\tmargin: 0;\n\tborder: 0 none;\n\tbackground-color: #f00;\n}\n\nsection:-moz-full-screen\n{\n\tfloat: none;\n\twidth: 100%;\n\theight: 100%;\n\tpadding: 0;\n\tmargin: 0;\n\tborder: 0 none;\n}\n\nsection:-ms-full-screen\n{\n\tfloat: none;\n\twidth: 100%;\n\theight: 100%;\n\tpadding: 0;\n\tmargin: 0;\n\tborder: 0 none;\n}\n\nsection:-o-full-screen\n{\n\tfloat: none;\n\twidth: 100%;\n\theight: 100%;\n\tpadding: 0;\n\tmargin: 0;\n\tborder: 0 none;\n}\n\nsection:full-screen\n{\n\tfloat: none;\n\twidth: 100%;\n\theight: 100%;\n\tpadding: 0;\n\tmargin: 0;\n\tborder: 0 none;\n}\n</style>\n <title>Simple Live Display</title>\n <script src=\"https://code.jquery.com/jquery-latest.js\"></script>\n <script type=\"text/javascript\">\n var ws;\n var wsUri = \"ws:\";\n var loc = window.location;\n console.log(loc);\n if (loc.protocol === \"https:\") { wsUri = \"wss:\"; }\n // This needs to point to the web socket in the Node-RED flow\n // ... in this case it's ws/simple\n wsUri += \"//\" + loc.host + loc.pathname.replace(\"slideshow\",\"ws/slideshow\");\n\n function wsConnect() {\n console.log(\"connect\",wsUri);\n ws = new WebSocket(wsUri);\n //var line = \"\"; // either uncomment this for a building list of messages\n ws.onmessage = function(msg) {\n var line = \"\"; // or uncomment this to overwrite the existing message\n // parse the incoming message as a JSON object\n var data = msg.data;\n //console.log(data);\n // build the output from the topic and payload parts of the object\n // line += \"<p>\"+data+\"</p>\";\n line += '<section id=\"fullscreen\" onclick=\"gofull();\"><img onload=\"fit_to_screen();\" src=\"' + data + '\"/></section>'\n // replace the messages div with the new \"line\"\n document.getElementById('messages').innerHTML = line;\n //ws.send(JSON.stringify({data:data}));\n set_body_height();\n }\n ws.onopen = function() {\n // update the status div with the connection status\n document.getElementById('status').innerHTML = \"connected\";\n //ws.send(\"Open for data\");\n console.log(\"connected\");\n }\n ws.onclose = function() {\n // update the status div with the connection status\n document.getElementById('status').innerHTML = \"not connected\";\n // in case of lost connection tries to reconnect every 3 secs\n setTimeout(wsConnect,3000);\n }\n }\n \n function set_body_height() { // set body height = window height\n $('body').height($(window).height());\n $('body').width($(window).width());\n fit_to_screen();\n }\n $(document).ready(function() {\n $(window).bind('resize', set_body_height);\n set_body_height();\n });\n \n function fit_to_screen() {\n img.removeAttribute(\"style\");\n // var winX = window.innerWidth + \"px\";\n var winX = $(window).width();\n // var winY = window.innerHeight + \"px\";\n var winY = $(window).height();\n var vbar = false;\n if (document.body.scrollHeight > document.body.clientHeight) // vertical scrollbar\n {\n img.style.height = winY;\n vbar = true;\n }\n if (document.body.scrollWidth > document.body.clientWidth) // horizontal scrollbar\n {\n if (vbar) // both scrollbars\n {\n if ((document.body.scrollHeight - document.body.clientHeight) > (document.body.scrollWidth - document.body.clientWidth)) // let's see which one is bigger\n {\n img.removeAttribute(\"style\");\n img.style.height = winY;\n }\n else\n {\n img.removeAttribute(\"style\");\n img.style.width = winX;\n }\n }\n else\n {\n img.removeAttribute(\"style\");\n img.style.width = winX;\n }\n }\n }\n \n function gofull() {\n \n var e = document.getElementById(\"fullscreen\");\n\n\t if (RunPrefixMethod(document, \"FullScreen\") || RunPrefixMethod(document, \"IsFullScreen\")) {\n\t\t RunPrefixMethod(document, \"CancelFullScreen\");\n\t }\n\t else {\n\t\t RunPrefixMethod(e, \"RequestFullScreen\");\n\t }\n\n }\n\n var pfx = [\"webkit\", \"moz\", \"ms\", \"o\", \"\"];\n function RunPrefixMethod(obj, method) {\n\t\n\t var p = 0, m, t;\n\t while (p < pfx.length && !obj[m]) {\n\t \tm = method;\n\t \tif (pfx[p] == \"\") {\n\t \t\tm = m.substr(0,1).toLowerCase() + m.substr(1);\n\t \t}\n \t\tm = pfx[p] + m;\n \t\tt = typeof obj[m];\n \t\tif (t != \"undefined\") {\n\t\t\t pfx = [pfx[p]];\n\t\t\t return (t == \"function\" ? obj[m]() : obj[m]);\n\t\t }\n\t\t p++;\n\t }\n\n }\n \n function doit(m) {\n if (ws) { ws.send(m); }\n }\n </script>\n </head>\n <body onload=\"wsConnect();\" onunload=\"ws.disconnect();\">\n <font face=\"Arial\">\n <div id=\"messages\"></div>\n <!-- <button type=\"button\" onclick='gofull();'>Full Screen</button> -->\n <!-- <button type=\"button\" onclick='fit_to_screen();'>Fit</button> -->\n <div id=\"status\">unknown</div>\n </font>\n </body>\n</html>\n", "x": 338, "y": 200, "wires": [ [ "b7cabbb.ce8e248" ] ] }, { "id": "b7cabbb.ce8e248", "type": "http response", "z": "fb5b6e33.9bc11", "name": "", "x": 550, "y": 200, "wires": [] }, { "id": "bc725200.1dc2d", "type": "websocket-listener", "z": "", "path": "/ws/slideshow", "wholemsg": "false" } ]