blank-white-cards/apps/bwc_web/assets/static/bwc.old/js/bwc.js
2020-12-28 14:35:10 -08:00

596 lines
16 KiB
JavaScript
Executable File

var $ = jQuery;
const getElement = (id) => document.getElementById(id);
const ws = new WebSocket('ws://bwc.ryanpandya.com/socket');
var username = "unnamed";
var pId = 0;
var cards = [];
var lastCard = false;
var players = [];
var gameMode = "draw";
const timeFormat = 'h:mm a [PDT]';
const notification_pos = "top-right";
function range(size, startAt = 0) {
return [...Array(size).keys()].map(i => i + startAt);
}
function heartbeat() {
clearTimeout(this.pingTimeout);
console.log("Ping");
this.pingTimeout = setTimeout(() => {
this.terminate();
}, 30000 + 1000);
}
ws.onopen = (moot) => {
heartbeat;
var urlParams = new URLSearchParams(window.location.search);
console.log('Connected to websocket.');
username = urlParams.get('username');
UIkit.notification({
message: 'Connected!',
status: 'success',
pos: notification_pos,
timeout: 1000
});
if(username == null || username == ""){
window.location = "/";
}
else{
}
};
const addMessage = (e) => {
var self_marker = "";
if(e.pId == pId){
self_marker = "self";
}
$("ul#chatbox").append(
'<li class="message uk-margin-top">\
<p class="uk-text-muted uk-text-small uk-margin-small">\
<span class="uk-float-right uk-margin-right">'+e.timestamp+'</span>\
<span class="uk-text-primary uk-text-bold username '+self_marker+'" pId='+e.pId+'>'+e.username+'</span>\
<p style="font-size:12px;">'+e.message+'</p>\
</p>\
</li>'
);
}
const addUser = (newPlayer) => {
var picker = "";
var existing = false;
players.forEach(function(p){ // Check if we already know about this player (is this a reconnection attempt)
if(p.pId == newPlayer.pId){ // Looks like it is
existing = true; console.log("Hit on " + newPlayer.username); // Make note
}
});
if(existing){
// What to do if this is a duplicate
}else{
// Otherwise
notice(newPlayer.username + " has joined the game.");
players.push(newPlayer);
if(newPlayer.username == username){ // This user is actually us, so make the username editable
picker = '<div class="uk-overlay uk-position-center"><span class="change-profile uk-icon uk-overlay-icon" uk-overlay-icon="icon: camera" uk-toggle="target: #profileModal"></span></div>';
u = '<input class="uk-form-blank uk-text-primary play-mode-username input-username" onKeyUp="javascript:playModeChangeUsername();" id="username" value="'+username+'">';
}
else{ // Otherwise just display the username
u = newPlayer.username;
}
var el = '\
<li class="player" data-pId="'+newPlayer.pId+'"><div class="uk-inline"><img data-pId="'+newPlayer.pId+'" class="uk-border-circle player" src="'+newPlayer.profilepic+'" alt="" width="100" height="100">'+picker+'</div><div class="player-username">'+u+'</div></li>';
$("ul.players-list").append(el);
$("span#number-of-players").text(parseInt($("span#number-of-players").text())+1); // This is probably wrong and will cause duplicates
}
}
const delUser = (username) => {
}
const changeMode = (data) => {
$("#pick-first-turn").css({'display':'flex'});
$("#card-view").hide();
$(".active-card-controls").hide();
if(data.playerTurn.pId == pId){
notice("The game has started. Your move!");
}
else{
notice("The game has started. Move: " + data.playerTurn.username);
}
gameMode = data.mode;
changeActivePlayer(data.playerTurn, data.incompleteCard);
}
const decrementCardsCount = () => {
var el = $("#toggle_play > .uk-badge");
var newNumber = parseInt(el.text()) - 1;
console.log(newNumber);
if(newNumber < 2){
el.text("last card").css({'background':'maroon',color:'white'});
}
if(newNumber == 0 || newNumber == NaN){
el.text("out of cards").css({'background':'black',color:'white'});
}
else{
el.html(newNumber + "&nbsp;cards").css({'background':'#eee',color:'#666'});;
}
};
const changeActivePlayer = (player, card) => {
clearActiveCard();
if(player.pId == pId){
// Our turn!
$(".active-card-controls").css({'display':'flex'});
if(card){
console.log("There's a card in memory already.");
pullCard(card);
}
else{
console.log("Requesting a card from the server...");
request = {
'type': 'pullCard',
'player': player
}
decrementCardsCount();
ws.send(JSON.stringify(request));
}
$("#game-status").text("your turn").css({'background':'palegoldenrod','color':'#666'}).fadeIn();
}
else{
$("#game-status").text(player.username+"'s turn").fadeIn();
$(".turn-indicator").css({"display":"inherit"});
if(!card){
decrementCardsCount();
}
else{
if(card.revealed){
$(".revealed-card-notice").show();
pullCard(card);
}
}
}
$("b.currentPlayer").text(player.username);
$("li.current-player").removeClass("current-player");
$("li[data-pId="+player.pId+"]").addClass("current-player");
}
const revealCard = () => {
card.revealed = true;
packet = {
'type': 'revealCard',
'card': card
}
markRevealedCard();
ws.send(JSON.stringify(packet));
}
const clearActiveCard = () => {
var empty = "";
$(".active-card").hide().attr('data-author',empty);
$("#pick-first-turn").css({'display':'flex'});
$(".revealed-card-notice").hide();
$(".active-card-controls").hide();
$(".active-card h1.card-title").text(empty);
$(".active-card img.card-picture").attr('src',empty);
$(".active-card div.card-content").text(empty);
$("li.reveal-card > a").text("Reveal Card").removeClass('uk-disabled').removeClass('revealed');
}
const doneWithCard = () => {
clearActiveCard();
$("#game-status").css({"background":"#1e87f0","color":"#fff"});
packet = {
'type': 'endTurn'
}
ws.send(JSON.stringify(packet));
}
const addVote = (i) => {
var el = $(".play-list-vote[data-pId="+i+"]");
el.text(parseInt(el.text()) + 1).css({"display":"grid", "float":"right"});
}
const pullCard = (pulledCard) => {
card = pulledCard;
const cardAuthor = pulledCard.author;
const cardTitle = pulledCard.title;
const cardImage = pulledCard.image;
const cardContent = pulledCard.content;
$(".active-card").attr('data-author',cardAuthor);
$(".active-card h1.card-title").text(cardTitle); if(cardTitle == ""){$(".active-card h1.card-title").hide()}
$(".active-card img.card-picture").attr('src',cardImage);
$(".active-card div.card-content").text(cardContent);
if(cardAuthor == username){
$(".your-card").show();
}
$("#pick-first-turn").hide();
$("#card-view").css({'display':'flex'});
if(card.revealed){
markRevealedCard();
}
}
const markRevealedCard = () => {
$("li.reveal-card > a").text("revealed").addClass('uk-disabled revealed');
}
const viewRevealedCard = (card) => {
pullCard(card);
if($("b.currentPlayer").first().text() != username){$(".revealed-card-notice").show()};
}
const updateUsername = (i, uname) => {
$(".input-username").val(uname);
const url = window.location.origin + window.location.pathname;
$("span.username[pId='"+i+"']").text(uname);
$(".input-username").val(uname);
history.pushState({},
"rename",
url + "?username=" + uname
);
}
ws.onmessage = (event) => {
event = JSON.parse(event.data);
switch(event.type){
case 'init':
if(event.mode == "error"){
window.location = window.origin + "?error=username";
}
console.log(">> Initializing game...");
pId = event.id;
console.log("You are in the game as '" + username + "' (Player " + pId + ").");
$(".input-username").val(username);
event.players.forEach(function(p){
addUser(p);
});
$("#toggle_play > .uk-badge").text(event.cards+1 +" cards");
decrementCardsCount();
if(event.mode == "play"){
changeMode(event);
$("#toggle_play").click();
}
$(".input-username").value = username;
$("span#number-of-players").text(event.players.length);
event.messages.forEach(function(e){
addMessage(e);
});
break;
case 'changeMode':
changeMode(event);
addMessage(event.message);
break;
case 'changeUsername':
console.log('Got an updated username: Player %s is now "%s".', event.pId, event.username);
updateUsername(event.pId, event.username);
break;
case 'updateCardsList':
if(username == event.author){
notice("Your card was submitted.");
}else{
notice(event.author + " submitted a card.");
}
var el = $("#toggle_play > .uk-badge");
el.html(parseInt(el.text()) + 1 +"&nbsp;cards");
break;
case 'error':
console.log(">> Error: " + event.content);
if(event.err_username){
}
UIkit.notification({
message: event.content,
status: 'warning',
pos: notification_pos,
timeout: 1000
});
break;
case 'notification':
console.log(">> Notification: " + event.content);
UIkit.notification({
message: event.content,
status: 'success',
pos: notification_pos,
timeout: 1000
});
break;
case 'gameOver':
console.log(">> GAME OVER: " + event.content);
UIkit.notification({
message: event.content,
status: 'success',
pos: notification_pos,
timeout: 1000
});
$("#game-status").html("game over");
$("#play_mode").html(
"<h1>Game over, thanks for playing!</h1>"
);
break;
case 'message':
console.log(">> Got a message.");
addMessage(event);
break;
case 'changeProfilePic':
updateProfPic(event.player, event.href);
break;
case 'vote':
addVote(event.pId);
if(firstPlayerPicked){
notice("First turn starting!");
$("#draw_mode").html("");
}
break;
case 'revealCard':
viewRevealedCard(event.card);
break;
case 'pulledCard':
if(event.last){
notice("Last card!");
lastCard = true;
}
pullCard(event.card);
break;
case 'nextTurn':
changeActivePlayer(event.playerTurn, null);
break;
case 'newPlayer':
var player = event.player;
if(player.pId != pId){
addUser(player);
}
break;
default:
console.log('Unknown event. Pasting:');
console.log(event);
}
};
const changeUsername = (name) => {
packet = {
"type": "changeUsername",
"pId": pId,
"username": name
}
console.log("Changing username to: '"+name+"'");
username = name;
ws.send(JSON.stringify(packet));
};
const notice = (message) => {
UIkit.notification({
message: message,
status: 'primary',
pos: notification_pos,
timeout: 2000
});
}
const error = (message) => {
UIkit.notification({
message: message,
status: 'danger',
pos: notification_pos,
timeout: 2000
});
}
const urlify = (text) => {
var urlRegex = /(((https?:\/\/)|(www\.))[^\s]+)/g;
//var urlRegex = /(https?:\/\/[^\s]+)/g;
return text.replace(urlRegex, function(url,b,c) {
var url2 = (c == 'www.') ? 'http://' +url : url;
return '<a href="' +url2+ '" target="_blank">' + url + '</a>';
})
};
const submitMessage = () => {
message = $("#message").val();
if(message.trim()){
const timestamp = new Date();
packet = {
"type": "message",
"pId": pId,
"username": username,
"message": urlify(message.trim()),
"timestamp": new Date()
}
console.log("Sending message.");
ws.send(JSON.stringify(packet));
$("#message").val("");
}};
const chooseGiphy = (url) => {
$("img.card-picture").attr("src", url);
$(".uk-close").click();
}
const chooseProfile = (url) => {
packet = {
'type': 'changeProfilePic',
'player': {
'pId': pId,
'username': username
},
'href': url
}
$(".change-profile > svg").hide();
$(".uk-close").click();
ws.send(JSON.stringify(packet));
}
const updateProfPic = (player, url) => {
$("img[data-pId="+player.pId+"]").attr('src',url);
}
const giphySearch = () => {
var query = $("#giphySearch").val().trim().replace(/ /g, "+");
const api_url = "https://api.giphy.com/v1/gifs/search?api_key=GUHvLYHRcNgPAIKt4PNZcjYw5FBeBX0F&q="+query+"&limit=25&offset=0&rating=R&lang=en";
$.ajax({url: api_url, method: 'GET'}).done(function(response){
// This is the API response data. It's a JSON object of 25 gifs
console.log(response.data);
$("#giphySearchResults").html("");
response.data.forEach(function(i){
var giphyURL = i.images.fixed_height.url;
$("#giphySearchResults").append(
"<a href='javascript:chooseGiphy("
+ '"'
+ giphyURL
+ '"'
+");'><img class='search-result' src='"+giphyURL+"'/></a>"
);
});
});
};
const voteForPlayer = (i) => {
console.log("Sending in a vote.");
packet = {
'type': "vote",
'pId': i
}
ws.send(JSON.stringify(packet));
}
const playModeChangeUsername = (e) => {
if(e.keyCode === 13){
changeUsername($(".player-username > input").val());
};
}
$().ready(function() {
$("#toggle_chat").on('click', function(e){
$(this).closest("li").toggleClass("uk-active");
});
$(".input-username").keydown(function(e){
if(e.keyCode === 13){
changeUsername(this.value);
};
});
$(".input-username").focusout(function(e){
changeUsername(this.value);
});
$("#message").keyup(function(e){
if(e.keyCode === 13){
submitMessage();
};
});
$("a#toggle_draw").on('click', function(e){
if(gameMode == "play"){
// Switch tabs
$("#play_mode").hide();$("a#toggle_play").closest("li").removeClass("uk-active");
$("#draw_mode").show();$("a#toggle_draw").closest("li").addClass("uk-active")
}
});
$("a#toggle_play").on('click', function(e){
if(gameMode == "play"){
// Switch tabs
$("#draw_mode").hide();$("a#toggle_draw").closest("li").removeClass("uk-active");
$("#play_mode").css({"display":"flex"});$("a#toggle_play").closest("li").addClass("uk-active")
}
else{
// Request server to start game
console.log("Asking server to start game...");
packet = {
"type": "startPlayMode",
"player": username
}
ws.send(JSON.stringify(packet));
setTimeout(function(e){
if(gameMode == "play"){
// Switch tabs
console.log("Switching tabs");
$("#draw_mode").hide();$("a#toggle_draw").closest("li").removeClass("uk-active");
$("#play_mode").css({"display":"flex"});$("a#toggle_play").closest("li").addClass("uk-active")
}
}, 500);
}
});
$("#submitCard").on('click', function(e){
submitCard();
clearCard();
});
$("#newCard").on('click', function(e) {
clearCard();
});
$("#giphySearch").keyup(function(e){
if(e.keyCode == "13"){
giphySearch();
}
});
$("#giphySearchButton").click(function(e){
giphySearch();
});
$("#imageInsta").click(function(e){
notice("TODO: Add insta feature");
});
$("#imageUpload").click(function(e){
notice("TODO: Add upload feature");
});
$("#imageDraw").click(function(e){
notice("TODO: Add draw feature");
});
range(22).forEach(function(e){
var profURL = "/img/profiles/"+e+".jpg";
$("#profile-options").append(
"<a href='javascript:chooseProfile("
+ '"'
+ profURL
+ '"'
+");'><img class='search-result' src='"+profURL+"'/></a>"
);
});
$('#imageModalContent').on('keyup keypress', function(e) {
var keyCode = e.keyCode || e.which;
if (keyCode === 13) {
e.preventDefault();
return false;
}
});
$("#manualProfile").on('keyup', function(e){
if(e.keyCode == 13){
const url = $(this).val();
$("#manual-img").attr("src", url).show();
$("#manual-img-href").attr('href',
"javascript:chooseProfile("
+ '"'
+ url
+ '"'
+");"
);
}
else{
$("#manual-img").attr("src", "").hide();
}
});
});