From 7fcc6323bb02c002ae3d1fc490cc169450bbe15d Mon Sep 17 00:00:00 2001 From: jrtechs Date: Sat, 26 Jan 2019 13:55:39 -0500 Subject: [PATCH] Got the home page looking normal. --- googletrendsgame/JQueryReWork/README.md | 2 + googletrendsgame/JQueryReWork/css/app.css | 335 +++++++++++++++++- googletrendsgame/JQueryReWork/html/home.html | 95 ++--- googletrendsgame/JQueryReWork/html/lobby.html | 14 + googletrendsgame/JQueryReWork/player.js | 73 ++++ googletrendsgame/JQueryReWork/room.js | 281 +++++++++++++++ googletrendsgame/JQueryReWork/server.js | 25 +- googletrendsgame/JQueryReWork/trendsAPI.js | 89 +++++ googletrendsgame/JQueryReWork/utils.js | 37 ++ 9 files changed, 865 insertions(+), 86 deletions(-) create mode 100644 googletrendsgame/JQueryReWork/player.js create mode 100644 googletrendsgame/JQueryReWork/room.js create mode 100644 googletrendsgame/JQueryReWork/trendsAPI.js create mode 100644 googletrendsgame/JQueryReWork/utils.js diff --git a/googletrendsgame/JQueryReWork/README.md b/googletrendsgame/JQueryReWork/README.md index 8215528..6a53ad9 100644 --- a/googletrendsgame/JQueryReWork/README.md +++ b/googletrendsgame/JQueryReWork/README.md @@ -4,4 +4,6 @@ npm install express-session --save npm install url --save npm install whiskers --save npm install fs --save +npm install sanitizer --save +npm install google-trends-api --save ``` \ No newline at end of file diff --git a/googletrendsgame/JQueryReWork/css/app.css b/googletrendsgame/JQueryReWork/css/app.css index 5636ce4..88cc831 100644 --- a/googletrendsgame/JQueryReWork/css/app.css +++ b/googletrendsgame/JQueryReWork/css/app.css @@ -1,3 +1,311 @@ +article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden]{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:0.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C" "\201D" "\2018" "\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;} +*, +*::after, +*::before { + box-sizing: border-box; +} + +html { + background: #000; +} + +body { + font-family: 'Barlow', Helvetica, Arial, sans-serif; + font-weight: 500; + min-height: 100vh; + color: #57585c; + color: var(--color-text); + background-color: #000; + background-color: var(--color-bg); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* Fade effect */ +.js body { + opacity: 0; + transition: opacity 0.6s; +} + +.js body.render { + opacity: 1; +} + +a { + text-decoration: none; + color: var(--color-link); + outline: none; +} + +a:hover, +a:focus { + color: var(--color-link-hover); + outline: none; +} + +.hidden { + position: absolute; + overflow: hidden; + width: 0; + height: 0; + pointer-events: none; +} + +.message { + position: relative; + z-index: 100; + display: none; + padding: 1em; + text-align: center; + color: var(--color-bg); + background: var(--color-text); +} + +/* Icons */ +.icon { + display: block; + width: 1.5em; + height: 1.5em; + margin: 0 auto; + fill: currentColor; +} + +.icon--keyboard { + display: none; +} + +main { + position: relative; + width: 100%; +} + +.content { + position: relative; + display: grid; + justify-content: center; + align-items: center; + align-content: center; + margin: 0 auto; + min-height: 100vh; +} + +.content--fixed { + position: fixed; + z-index: 10000; + top: 0; + left: 0; + display: grid; + align-content: space-between; + width: 100%; + max-width: none; + min-height: 0; + height: 100vh; + padding: 1.5em; + pointer-events: none; + grid-template-columns: 50% 50%; + grid-template-rows: auto auto 4em; + grid-template-areas: 'header ...' + '... ...' + 'github demos'; +} + +.content--fixed a { + pointer-events: auto; +} + +/* Header */ +.codrops-header { + position: relative; + z-index: 100; + display: flex; + flex-direction: row; + align-items: flex-start; + align-items: center; + align-self: start; + grid-area: header; + justify-self: start; +} + +.codrops-header__title { + font-size: 1em; + font-weight: 500; + margin: 0; + padding: 0.75em 0; +} + +.info { + margin: 0 0 0 1.25em; + color: var(--color-info); +} + +.github { + display: block; + align-self: end; + grid-area: github; + justify-self: start; +} + +.demos { + position: relative; + display: block; + align-self: end; + text-align: center; + grid-area: demos; +} + +.demo { + margin: 0 0.15em; +} + +.demo:hover, +.demo:focus { + opacity: 0.5; +} + +.demo span { + white-space: nowrap; + text-transform: lowercase; + pointer-events: none; +} + +.demo span::before { + content: '#'; +} + +a.demo--current { + pointer-events: none; + color: var(--color-link-hover); +} + +/* Top Navigation Style */ +.codrops-links { + position: relative; + display: flex; + justify-content: center; + margin: 0 1em 0 0; + text-align: center; + white-space: nowrap; +} + +.codrops-icon { + display: inline-block; + margin: 0.15em; + padding: 0.25em; +} + +/* Canvas positions */ +.content__inner { + grid-area: 1 / 1 / 1 / 1; + position: relative; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + align-content: center; +} + +.scene { + position: absolute; +} + +.scene--left { + width: 100vmin; + height: 100vmin; + transform: translate3d(-50vmin,0,0); +} + +.scene--full { + width: 100%; + height: 100vh; +} + +.scene--up { + height: 150vmin; + width: 150vmin; + top: -50vh; + left: 50%; + margin-left: -75vmin; +} + +@media screen and (min-width: 55em) { + .icon--keyboard { + position: absolute; + right: 0.55em; + bottom: -30%; + display: block; + width: 54px; + height: 46px; + fill: var(--color-link); + } + .demos { + display: flex; + padding-right: 80px; + justify-self: end; + } + .demo { + display: block; + width: 17px; + height: 17px; + margin: 0 4px; + border-radius: 50%; + background: var(--color-link); + } + a.demo--current { + background: var(--color-link-hover); + } + .demo span { + line-height: 1; + position: absolute; + right: 100%; + display: none; + margin: 0 1em 0 0; + } + .demo--current span { + display: block; + } +} + +@media screen and (max-width: 55em) { + .message { + /* display: block; */ + } + .content { + flex-direction: column; + height: auto; + } + .content--fixed { + position: relative; + z-index: 1000; + display: block; + padding: 0.85em; + } + .content:not(.content--fixed) { + margin-bottom: 6em; + } + .codrops-header { + flex-direction: column; + align-items: center; + } + .codrops-header__title { + font-weight: bold; + padding-bottom: 0.25em; + text-align: center; + } + .info { + margin: 0; + } + .github { + display: block; + margin: 1em auto; + } + .codrops-links { + margin: 0; + } +} + + + + body { -moz-osx-font-smoothing: grayscale; background: #B9B9B9; @@ -17,15 +325,26 @@ body { color: #FFF; } .logo { - float: left; - margin: 0 0 60px 40px; - font-size: 30px; - border-bottom-left-radius: 8px; - border-bottom-right-radius: 8px; } - .logo:hover { - color: #FFF; + width: auto; + flex: 0; + padding: 20px; + font-size: 50px; + text-transform: uppercase; + font-family: 'Poppins', sans-serif; + font-weight: 900; + background: #0459ed; + color: #FFF !important; } + +.logo { + float: left; + margin: 0 0 60px 40px; + font-size: 30px; + border-bottom-left-radius: 8px; + border-bottom-right-radius: 8px; } +.logo:hover { + color: #FFF !important; text-decoration: none; } - .logo div { +.logo div { line-height: 30px; } a { diff --git a/googletrendsgame/JQueryReWork/html/home.html b/googletrendsgame/JQueryReWork/html/home.html index 7905c44..454d904 100644 --- a/googletrendsgame/JQueryReWork/html/home.html +++ b/googletrendsgame/JQueryReWork/html/home.html @@ -1,84 +1,29 @@ - - - - - - - Trend Spotter | Game - - - - - - - - - - - - -
- -
-
- -
-
+
- -
-
Round 4/7
-
-
- -
-
-
car
-
- +
+ + + +
+
+ + + + +
- - - -
You're in dave61's room | 12/20 players
- Leave Game -
- +
+ + -
-
60 seconds
-
    -
  1. - John Daniels - 10,000 points - X -
  2. -
  3. - John Daniels - 10,000 points - X -
  4. -
  5. - John Daniels - 10,000 points - X -
  6. -
-
- - - - - - - - - - - \ No newline at end of file +
\ No newline at end of file diff --git a/googletrendsgame/JQueryReWork/html/lobby.html b/googletrendsgame/JQueryReWork/html/lobby.html index e69de29..25f90db 100644 --- a/googletrendsgame/JQueryReWork/html/lobby.html +++ b/googletrendsgame/JQueryReWork/html/lobby.html @@ -0,0 +1,14 @@ +
+
+
    + {for room in rooms} +
  • + {room.name} + {room.occupancy} + {room.status} +
  • + {/for} +
+
+
\ No newline at end of file diff --git a/googletrendsgame/JQueryReWork/player.js b/googletrendsgame/JQueryReWork/player.js new file mode 100644 index 0000000..d2ab26f --- /dev/null +++ b/googletrendsgame/JQueryReWork/player.js @@ -0,0 +1,73 @@ +//gets the trending data +const trendingAPI = require("./trendsAPI.js"); + +class Player +{ + + constructor(s) + { + //name of the user + this.name = null; + + //players socket + this.socket = s; + + //score of the player + this.score = 0; + + //reference to the room -- might not need this + this.room = null; + + //the word the user selected for current round + this.submission = ''; + + this.roundScore = 0; + + //logs the user data so we can record it to data base at end of round + this.log = []; + } + + /** + * generate the json object used in 'roomUpdate' socket io event + * + * return {name: score: word:} + */ + genJASON() + { + var result = new Object(); + result.name = this.name; + result.score = this.score; + result.word = this.submission; + + return result; + } + + /** + * data -- literally a string + * @param data + */ + selectWord(data) + { + var w = data + " " + this.room.currentWord; + this.submission = data; + + //console.log(w); + + this.room.update(); + + return new Promise(function(resolve, reject) + { + trendingAPI.getPopularity(w).then(function(result) + { + console.log("api result for " + result + w); + resolve(result); + }).catch(function(err){ + console.log(err); + }) + }); + + + } +} + +module.exports = Player; \ No newline at end of file diff --git a/googletrendsgame/JQueryReWork/room.js b/googletrendsgame/JQueryReWork/room.js new file mode 100644 index 0000000..712a723 --- /dev/null +++ b/googletrendsgame/JQueryReWork/room.js @@ -0,0 +1,281 @@ +//used for the getting the word array +const utils = require("./utils.js"); + +/** + * Object used for storing rooms + * @param capacityP -- the number of people that can be in room + * @param pass -- the room password -- null if none + * @param owner -- the person who is creating the room + */ +class Room +{ + + constructor(capacityP, pass, owner) + { + //max capacity of room -- default is 4 for now + this.capacity = capacityP; + + //name of the room + this.roomName = owner.name; + + //list of words used in the game + //7 for now will change later to be room specific + this.words = utils.getRandomWords(7); + + this.currentWord = this.words.pop(); + + //list players -- so we can push requests to them + this.users = []; + + //increments when rounds pass + this.currentRound = 0; + + // the password of the room -- null if no password + this.password = pass; + + /** + 1 = Waiting for users + 2 = Word shown, Waiting for response from users + 3 = Showing Result + 4 = Game Over, Display Final Results + */ + this.state = 1; + + this.addUser(owner); + } + + + /** + * generate the json object used in 'roomUpdate' socket io event + * + * return {name: score: word:} + */ + genJASON() + { + var result = new Object(); + result.name = this.roomName; + result.users = this.users; + + return result; + } + + /** + * creates json to send in the 'roomUpdate' socket event + * + * {users: gameState: roundWinner: currentWord: } + */ + generateRoomUpdate() + { + var result = new Object(); + + result.users = []; + + this.users.forEach(function(u) + { + result.users.push(u.genJASON()); + }); + + //sort the users based on score + var countOuter = 0; + var countInner = 0; + var countSwap = 0; + + // var swapped; + // do + // { + // countOuter++; + // swapped = false; + // for(var i = 0; i < result.users.length; i++) + // { + // countInner++; + // if(result.users[i].score && result.users[i + 1].score && + // result.users[i].score > result.users[i + 1].score) + // { + // countSwap++; + // var temp = result.users[i]; + // result.users[i] = result.users[j]; + // result.users[j] = temp; + // swapped = true; + // } + // } + // } while(swapped); + + + result.gameState = this.state; + + + //sets round winner + var rWinner = -1; + + for(var i = 0; i < this.users.length; i++) + { + if(rWinner < this.users[i].roundScore) + { + result.roundWinner = this.users[i].name; + rWinner = this.users[i].roundScore; + } + } + + result.currentWord = this.currentWord; + + return result; + } + + /** + * adds a user to a room + * @param p + * return 0 if they could join + */ + addUser(player) + { + //console.log("user added"); + //check if room is not full + this.users.push(player); + player.room = this; + + if(this.users.length == this.capacity) + { + this.state = 2; + } + + console.log("user added to room " + player.name); + //console.log(this.users); + + this.update(); + } + + + + + /** + * Removes a specific user from the room and adjusts the size of the array + * if the array is empty, the room closes + * @param p + */ + removeUser(p) + { + console.log("remove users fnc called"); + var temp = new Array(); + + for(var i = 0; i < temp.length; i++) + { + if(p.name === this.users[i].name) + { + + } + else + { + temp.push(this.users[i]); + } + } + + this.users = temp; + + //if room is empty remove the room from rooms list + if(this.users.length == 0) + { + console.log("room scrubbed"); + delete rooms[this.roomName]; + } + + this.update(); + } + + /** + * Whether or not a user can join this room -- checks for number of people are + * already in the room and the password + * @param p + * @returns {boolean} + */ + canJoin(p) + { + if(this.password == null) + { + return (this.users.length < this.capacity); + } + else + { + return (this.users.length < this.capacity) && (p === this.password); + } + } + + /** + * starts new round for the room -- called once all the players have submitted + */ + newRound() + { + console.log("new round started"); + if(this.words.length == 0) + { + this.state == 4; + } + else + { + this.currentRound++; + this.users.forEach(function(u) + { + u.submission = ''; + }); + this.currentWord = this.words.pop(); + this.state = 2; + } + this.sendRoomUpdate(); + } + + //updates room variables + update() + { + switch(this.state) + { + case 1: //waiting for users to join + { + if(this.users.length == this.capacity) + { + this.newRound(); + } + break; + } + case 2: // waiting for responses + { + var flag = true; + var test = ""; + this.users.forEach(function(u) + { + test+=u.submission; + if(u.submission === '') + { + flag = false; + } + }); + console.log("big stuff " + test); + if(flag) + { + this.state = 3; + this.newRound(); + // setTimeout(function() { + // + // }, 4000); + } + break; + } + case 3: // showing results -- time out fnc + { + console.log("error &&&&&&&&&&&&&&&&&&"); + break; + } + case 4: //game over display final result + { + //sqlStuff.dumpRoom(this); + break; + } + default: + { + console.log("You don goof up") + } + } + console.log(this.state + " state"); + this.sendRoomUpdate(); + } +} + +module.exports = Room; \ No newline at end of file diff --git a/googletrendsgame/JQueryReWork/server.js b/googletrendsgame/JQueryReWork/server.js index a7cc500..42dfa87 100644 --- a/googletrendsgame/JQueryReWork/server.js +++ b/googletrendsgame/JQueryReWork/server.js @@ -19,6 +19,18 @@ app.use(express.json()); // if needed app.use(session({ secret: "changeWithConfigLater", cookie: { maxAge: 6000000 }})); +var Room = require("./room"); + +var Player = require("./player"); + + +//list of all players --accessed using names like a dic +var players = {}; + +//list of all the rooms +var rooms = {}; + + const PORT = 5000; @@ -38,7 +50,7 @@ function fetchFile(filename) function fetchLobby(templateContext) { - + templateContext.rooms = [{name: "test1"},{name: "test2"}]; } function fetchGame(templateContext) @@ -70,14 +82,21 @@ function processPage(result, pageHTMLFile, templateFillerFunction) app.get('/', (requst, result) => { - processPage(result, "lobby.html", fetchLobby); + processPage(result, "home.html", fetchLobby); }); app.get('/game', (request, result)=> { - processPage(result, "game.html", fetchLobby); + processPage(result, "game.html", fetchGame); }); + +app.get('/lobby', (request, result)=> +{ + processPage(result, "lobby.html", fetchLobby); +}); + + app.use(express.static('css')); app.use(express.static('js')); app.listen(PORT, () => console.log(`App listening on port ${PORT}!`)); diff --git a/googletrendsgame/JQueryReWork/trendsAPI.js b/googletrendsgame/JQueryReWork/trendsAPI.js new file mode 100644 index 0000000..b063c65 --- /dev/null +++ b/googletrendsgame/JQueryReWork/trendsAPI.js @@ -0,0 +1,89 @@ +const googt = require('google-trends-api'); +const DAY = 1000 * 60 * 60 * 24; // 1 day in milliseconds +const YEAR = DAY * 365; // 1 year in milliseconds +const GEO = 'US'; //the scope of the trends + + +/** +desc: helper function for getYearStats, gets list of popularity for days in +the month. +*/ +function getMonthStats(word, month){ + + return new Promise(function(resolve, reject){ + //set up query for 1 month length + googt.interestOverTime({ + keyword:word, + startTime:new Date(Date.now() - (YEAR * month/12)), + endTime:new Date(Date.now() - (YEAR * (month-1)/12)) + }).then(function(results){ + //parse the json, fill return array w tuples of date + value + var times = JSON.parse(results).default.timelineData; + var ret = []; + for(var i = 0; i < times.length; ++i){ + var tup = new Object(); + tup.time = times[i].formattedTime; + tup.value = times[i].value[0]; + ret[i] = tup; + + } + resolve(ret); + }); + }); +} + +module.exports= + { + /* + desc: returns an integer score for the word over the day + */ + getPopularity: function(word) + { + //must be a promise since call to trends API is async + return new Promise(function(resolve, reject){ + + //specifies the keyword, time interval, granularity, and region + googt.interestOverTime({keyword:word, + startTime:new Date(Date.now() - DAY),granularTimeResolution:true, + geo:GEO + }) + .then(function(results){ + //turn into json object + data = JSON.parse(results).default.timelineData; + + //add up values + var total = 0; + data.forEach(function(element){ + total += element.value[0]; + }) + + //tell function to return + console.log("********************" + total); + //pl.selectWord2(total); + resolve(total); + }).catch(function(err){ + reject("Google Trends Query Failed"); + }); + }); + }, + + /** + desc: returns a list of tuples (date, value) representing word's + popularity for the past year + */ + /* + getYearStats: async function(word){ + var ret = []; + + for (var i = 9; i > 0; --i) { + await getMonthStats(word,i).then(function(data){ + ret = ret.concat(data); + }); + console.log(i); + } + + return ret; + } + */ + + }; diff --git a/googletrendsgame/JQueryReWork/utils.js b/googletrendsgame/JQueryReWork/utils.js new file mode 100644 index 0000000..b9cdc63 --- /dev/null +++ b/googletrendsgame/JQueryReWork/utils.js @@ -0,0 +1,37 @@ + +var fs = require('fs'); +const WORD_FILE_PATH = '../../words/words.txt'; + +//loads words from word file +var words = []; +var data = fs.readFileSync(WORD_FILE_PATH, 'utf8'); +var lines = data.split('\n'); +lines.forEach(function(element){ + words.push(element); +}); + +module.exports= + { + /** + * returns a specific amount of words -- unique + * @param num the number of words + * @returns {Array} the random, unique words + */ + getRandomWords : function(num) + { + var rwords = []; + for(var i = 0; i < num; ++i){ + var randindex = Math.round((Math.random() * (words.length - 1))); + var newword = words[randindex]; + var uniq = true; + rwords.forEach(function(element){ + if(newword === element){ + --i; + uniq = false; + } + }); + if(uniq)rwords.push(newword); + } + return rwords; + } + };