mess with the best, die like the rest

As a reminder, I had just watched the movie Hackers and was in search of more nostalgia. So I scrubbed through the movie and found a fun scene where two hackers battle for control over a T.V. station. So I thought I would try to recreate it in the form of an interactive website. I wanted the interaction to be kind of like using the command line in a terminal. That was a little tricky but I eventually got it working. There are still some features I would like to work out, like video synchronization when a user scrubs the video, as well as pausing and resuming play, streaming your own video, and usernames. I also tried to format the page using CSS, something I haven’t really put much time into in the past.

The clip at the right is the scene from the movie that inspired this project. The code for the project is below. 

HTML

<html>
    <head>
        <link rel="stylesheet" href="style.css">
        <script type="text/javascript" src="/socket.io/socket.io.js"></script>
        <script type="text/javascript">
            
            let videoArr = ["YourName.mp4",
            "TheWall.mp4",
            "2001ASpace Odyssey.mp4",
            "SevenSamurai.mp4",
            "HeavyMetal.mp4",
            "Hackers.m4v",
            "GhostInTheShell.mp4",
            "FantasticPlanet.m4v",
            "Alien.m4v",
            "Akira.mp4",
            "AdriftInTheOcean.mp4",	
        ]



            var socket = io.connect();
            
            socket.on('connect', function() {
                console.log("Connected");

                // Once we are connected, request the history
                socket.emit('history', null);
            });

            // Receive from any event
            socket.on('chatmessage', function (data) {
                document.getElementById('messages').innerHTML = "" + data + "\n<br />"
 + "" + document.getElementById('messages').innerHTML;
                if(videoArr.includes(data)){
                    let myVideo = document.querySelector("video")
                    myVideo.src = data;
                    myVideo.load();
                    myVideo.play();
                    console.log(data)
                }
            });
            
            var sendmessage = function(message) {
                if(message === "ls"){
                    videoArr.forEach((item) => {
                        
                        document.getElementById('messages').innerHTML = "" + '<span style="background: white;">' + item +  "</span>" + "\n<br />"
 + "" + document.getElementById('messages').innerHTML;
                    })
                }
                console.log("chatmessage: " + message);
                socket.emit('chatmessage', message);
                debugger;
            };
        </script>
        <style>
            #messages{
                color: rgb(16, 139, 37);
            }

            #instructions{
                color:rgb(16, 139, 37)
            }
        </style>	
        <head>
            <meta charset="UTF-8" />
            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <title>ITP TV</title>
        
    </head>
 <body>
     <div id="main">
    <div id="video-container">
     <video id="video" width="720" height="480" autoplay muted controls>
        <source id="video-player" src="AdriftInTheOcean.mp4" type="video/mp4">
        Your browser does not support the video tag.
      </video>
    </div>

<div id="instructions">
Type: LS, for available files<br>
Type: filename, to play video 
</div>

<div id="input-box">
 <input type="text" id="message" name="message" value=" ">
 <input id="submit-button" type="submit" value="submit" onclick="sendmessage(document.getElementById('message').value)">
 <script>
     let input = document.getElementById("message");
     input.addEventListener('keypress', (event) => {
        if(event.key === "Enter"){
            event.preventDefault();
            document.getElementById('submit-button').click()
            document.getElementById("message").value = "";
        }
     })
 </script>
</div>

 <div id="messages">
 mess with the best, die like the rest
 </div>
</div>
 </body>
</html>

 

JAVASCRIPT

// Database to store data
var Datastore = require('nedb');
var db = new Datastore({filename: "data.db", autoload: true});

const express = require("express");
const app = express();
const path = require('path');

var http = require('http');
var fs = require('fs');


// HTTP Portion

var httpServer = http.createServer(app);
const { Server } = require('socket.io');
const io = new Server(httpServer, {});
httpServer.listen(8070);

function requestHandler(req, res) {
    // Read index.html
    fs.readFile(__dirname + '/index.html', 
        // Callback function for reading
        function (err, data) {
            // if there is an error
            if (err) {
                res.writeHead(500);
                return res.end('Error loading index.html');
            }
            // Otherwise, send the data, the contents of the file
            res.writeHead(200);
            res.end(data);
  		}
  	);
}

app.use('/', express.static(path.join(__dirname, 'public')));

// Register a callback function to run when we have an individual connection
// This is run for each individual user that connects
io.sockets.on('connection', 
    // We are given a websocket object in our function

        function (socket) {
    
            console.log("We have a new client: " + socket.id)
            
        // When this user emits, client side: socket.emit('otherevent',some data);
        socket.on('chatmessage', function(data) {

            // Data comes in as whatever was sent, including objects
            console.log("Received: 'chatmessage' " + data);

            // Create the JavaScript Object
            var datatosave = {
                socketid: socket.id,
                message: data
            }
        
            // Insert the data into the database
            db.insert(datatosave, function (err, newDocs) {
                console.log("err: " + err);
                console.log("newDocs: " + newDocs);
            });
            
            // Send it to all of the clients
            io.sockets.emit('chatmessage',data);
        });

        // When the history is requested, find all of the docs in the database
        socket.on('history', function() {
            db.find({}, function(err, docs) {
                // Loop through the results, send each one as if it were a new chat message
                for (var i = 0; i < docs.length; i++) {
                    socket.emit('chatmessage', docs[i].message);
                }
            })
        });

        socket.on('disconnect', function() {
            console.log("Client has disconnected " + socket.id);
        });
    }
    
);


 

CSS

body {
    background-color: black;
    font-family: "Helvetica", "sans-serif";
    /*font-family: "Droid Sans Mono", "Courier New", monospace;*/
   /* font-family: "Lucida Console", "Courier New", monospace;*/
}

#video-container {
    float: right;
    width: 640px;
    padding-top: 2%;
    padding-left: 10px;
    padding-right: 150px;
    border: dashed;
    margin: 2px;
    
}

#instructions{
    position: relative;
    width: 20%;
    margin-left: 10%;
    padding-top: 2%;
    padding-bottom: 2%;
    padding-left: 2%;
    border-style: dashed;
}

#input-box{
    position: relative;
    top: 10px;
    padding-left: 10%;
    padding-top: 1%;
    padding-bottom: 1%;
}

#messages{
    position: relative;
    top: 30px;
    width: 20%;
    margin-left: 10%;
    padding-left: 2%;
    padding-top: 1%;
    padding-bottom: 1%;
    height: 300px;
    overflow: auto;
    border: dashed;
}

input[type=submit] {
    background-color: black;
    border: 2px dashed;
    color: green;
    padding: 10px 20px;
    text-decoration: none;
    margin: 4px 2px;
    cursor: pointer;
    font-family: inherit;
  }

  input[type=text] {
    border: 2px dashed green;
    background-color: black;
    color: green;
    outline: none;
    padding: 10px 20px;
    font-family: inherit
  }
  input[type=text]:focus {
    border: 3px solid green;
    padding: 10px 20px;
    font-family: inherit
  }