var API_MAGIC = "#(@)PROTOCOLS"
var URLregexp = /^(https?:\/\/)(www.)?([-A-Z0-9.]+)(\/)?([-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])*/ig;
var months = { Jan: 0, Feb: 1, Mar: 2, Apr: 3, May: 4, Jun: 5, Jul: 6, Aug: 7, Sep: 8, Oct: 9, Nov: 10, Dec: 11 }
function isScrolledIntoView (elem)
{
return true;
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom));
}
function scrollToTop (div)
{ $(div).scrollTop( 0 ) }
function scrollToBottom (div)
{ $(div).scrollTop( $(div)[0].scrollHeight ) }
function warn(s)
{
// return
var h = document.getElementById('msg').innerHTML
h = s + ' ' + h
document.getElementById('msg').innerHTML = h
}
var image_extensions = ["jpg","gif","png","jpeg","JPEG","JPG","GIF","PNG"]
function is_image(s)
{
for (i in image_extensions)
{
if (s.indexOf(image_extensions[i]) !== -1)
return true
}
return false
}
var domain_extensions = [".com",".net",".org",".uk",".fr",".de",".ch",".info",".nu",".mu",".io","facebook.com","twitter.com"]
function has_domain(s)
{
for (var i in domain_extensions)
{
if (s.indexOf(domain_extensions[i]) !== -1)
return true
}
return false
}
function parse_blurb(s)
{
// s = linkify(s+"\n")
var parsed_lines = []
var lines = s.split("\n")
for (i in lines)
{
var parsed_words = []
var words = lines[i].split(" ")
for (j in words)
{
if (words[j].indexOf("http") !== -1)
{
if (is_image(words[j]))
parsed_words.push('')
else
parsed_words.push(linkify(words[j]))
}
else if (words[j].indexOf("www") === 0 || has_domain(words[j]))
{
parsed_words.push(linkify("http://"+words[j]))
}
else
parsed_words.push(words[j])
}
parsed_lines.push( parsed_words.join(" ") )
}
// return s.replace(/\n/g, ' ')
return parsed_lines.join(" ")
}
function linkify(s)
{
var link = '';
var punctuation = '';
var end = s.length-1;
// strip the terminal punctuation mark if it's a period or comma
if (s.indexOf(".", end) === end || s.indexOf(",", end) === end)
{
punctuation = s.substr(end, 1);
s = s.substr(0, end);
}
if (s.indexOf("twitter.com") !== -1)
{
var partz = s.split("/");
var uname = '';
if (partz[partz.length-1].length)
uname = partz[partz.length-1];
else if (parts[-2].length)
uname = partz[partz.length-2];
link = '@' + uname + '';
}
else
{
// link = s.replace(URLregexp,"[$3]");
var match = URLregexp.exec(s);
if (match && match.length == 6)
{
var url = match[0] || "";
var http = match[1] || "";
var www = match[2] || "";
var domain = match[3] || "";
var slash = match[4] || "";
var uri = match[5] ? match[5].replace(/\/?index.html$/, "") : "";
link = '[' + domain + ']';
}
else
{
link = s.replace(URLregexp,"[$3]");
}
}
return link + punctuation;
}
var URL =
{
auth:
{
login: "/login",
logout: "/logout",
},
party:
{
list: "/api/party/list",
view: "/api/party/view",
edit: "/api/party/edit",
},
user:
{
all: "/api/user/all",
view: "/api/user/view",
edit: "/api/user/edit",
destroy: "/api/user/destroy",
},
};
var Party =
{
parties: {},
currentID: -1,
partyData: '',
liclick: function ()
{
Nav.selectClass(Party.parties, this.id)
var id = this.id.split("-")[1]
warn("viewing party "+id)
Party.view(id)
},
list: function()
{
$('#partyListContainer').fadeOut(200)
$('#partyEditContainer').hide()
$('#userListContainer').hide()
$('#userEditContainer').hide()
$('#userViewContainer').hide()
$.get(URL.party.list,{},Party.listCallback)
},
listCallback: function (raw)
{
warn("got party list")
var lines = raw.split("\n")
if (lines.shift() !== API_MAGIC)
{
warn(raw)
warn("bad api: party list")
return
}
var partyList = ""
if (Party.currentID != -1)
var firstPartyID = Party.currentID
for (i in lines)
{
if (! lines[i])
continue
var fields = lines[i].split('\t')
if (! firstPartyID)
firstPartyID = fields[0]
// 0 id 1 date
partyList += "
"+fields[1]+"
"
Party.parties["party-"+fields[0]] = fields
}
$('#partyList').html(partyList)
$('#partyListContainer').fadeIn(200)
for (id in Party.parties)
$('#'+id).click(Party.liclick)
Nav.selectClass(Party.parties, "party-"+firstPartyID)
if (firstPartyID)
Party.view(firstPartyID)
},
view: function(id)
{
$('#userViewContainer').hide()
$('#userEditContainer').hide()
$('#partyEditContainer').hide()
$('#userListContainer').fadeOut(200)
$.get(URL.party.view, {'id':id}, Party.viewCallback)
},
viewCallback: function (raw)
{
warn ("got party view")
var lines = raw.split("\n")
if (lines.shift() !== API_MAGIC)
{
warn("bad api: party view")
return
}
var partyData = '';
var partyUserList = ""
var partyLocationTag = ""
var editable = []
var currentHost = -1
for (i in lines)
{
if (! lines[i])
continue
var fields = lines[i].split('\t')
if (! partyData)
{ partyData = fields; continue }
// 0 id 1 group 2 name 3 email 4 blurb
if (fields[1] !== currentHost)
{
currentHost = fields[1]
if (currentHost === '0')
partyUserList += "
"
Users.userlist['user-'+fields[0]] = fields
}
partyLocationTag = partyData[2]
Party.currentID = partyData[0]
Party.partyData = partyData
$('#partyLocation').html(partyLocationTag)
$('#userList').html(partyUserList)
if (Auth.isHost)
{
$('#user-add').show()
$('#party-edit').show()
}
$('#userListContainer').fadeIn(200)
$('#userViewContainer').show()
for (id in Users.userlist)
{
$('#'+id).hover(Users.limousein, Users.limouseout)
$('#'+id).click(Users.liclick)
}
for (i in editable)
{
$('#edit-'+editable[i]).bind("click",Users.editClick)
}
Users.hovering = true
},
addClick: function ()
{
warn("NEW PARTY FORM")
var id = "NEW"
var today = new Date()
$('#party-id').val(id)
$('#party-day').val(today.getDate())
$('#party-year').val(today.getFullYear())
$('#party-month option').attr("selected", false);
$('#party-month option[value="'+today.getMonth()+'"]').attr("selected", true);
$('#party-location').val("")
$('#partyEditContainer h2').html("New party")
$('#userListContainer').hide()
$('#userViewContainer').hide()
$('#userEditContainer').hide()
$('#partyEditContainer').show()
$('#party-location').focus()
Main.saveFunction = Party.editSave
Nav.selectClass(Party.parties, "")
},
editClick: function ()
{
var id = Party.currentID
// 0 id 1 date 2 location
var party = Party.partyData
var date = party[1].split("-")
$('#party-id').val(id)
$('#party-day').val(date[0])
$('#party-year').val(date[2])
$('#party-month option').attr("selected", false);
$('#party-month option[value="'+months[date[1]]+'"]').attr("selected", true);
$('#party-location').val(party[2])
$('#partyEditContainer h2').html("Edit party")
$('#userListContainer').hide()
$('#userViewContainer').hide()
$('#userEditContainer').hide()
$('#partyEditContainer').show()
Main.saveFunction = Party.editSave
},
editSave: function ()
{
if (Main.saving)
return
Main.saving = true
warn("attempting save")
var data =
{
id: $('#party-id').val(),
userid: Auth.userID,
hostid: Auth.userID,
location: $('#party-location').val(),
month: $('#party-month').val(),
day: $('#party-day').val(),
year: $('#party-year').val(),
}
$('#partyEditContainer').fadeOut(200)
$.post(URL.party.edit, data, Party.editSaveCallback)
},
editSaveCallback: function (raw)
{
var lines = raw.split("\n")
if (lines.shift() !== API_MAGIC)
{
warn("bad api: party save")
return
}
var result = lines.shift().split("\t")
if (result[0] === "ERROR")
{
warn("save error: "+result[1])
return
}
var fields = lines.shift().split("\t")
var rowID = "party-"+fields[0]
if (result[0] === "OK")
{ warn("party saved") }
else if (result[0] === "NEW")
{
warn("party created")
$("#partyList").append("
"+fields[1]+"
")
}
// Party.parties[rowID] = fields
// Party.view(fields[0])
// Nav.selectClass(Party.parties, rowID)
Main.saving = false
Party.currentID = fields[0]
Party.list()
},
};
var Users =
{
userlist: {},
hovering: true,
current: false,
allCount: 0,
userListIndex: [],
currentIdx: -1,
all: function ()
{
$('#userViewContainer').hide()
$('#userEditContainer').hide()
$('#partyEditContainer').hide()
$('#userListContainer').fadeOut(200)
$.get(URL.user.all,{},Users.allCallback)
},
allCallback: function (raw)
{
warn ("got all users")
var lines = raw.split("\n")
if (lines.shift() !== API_MAGIC)
{
warn("bad api: user all")
return
}
var partyUserList = [];
var guestHosts = [];
var editable = [];
var firstletter = "A";
Users.allCount = 0;
Users.userListIndex = [];
for (i in lines)
{
if (! lines[i])
continue
var fields = lines[i].split('\t')
// 0 id 1 group 2 name 3 email 4 blurb
// if (fields[1] !== currentHost)
// {
// currentHost = fields[1]
// partyUserList += "
invited by "+Auth.hosts[fields[1]]+"
"
// }
var a = fields[2].substr(0,1)
var li = "li id='r-"+Users.allCount+"'"
var userRow = "";
var editSpan = "";
if (firstletter !== a)
{
firstletter = a
li += " class='br'"
}
if (Auth.isHost || fields[0] === Auth.userID)
{
editSpan += "edit";
editable.push(fields[0]);
}
switch (fields[1]) {
case '2': // host
userRow = "<"+li+">"+fields[2]+" *" + editSpan + "";
break;
case '1': // guest host
userRow = "<"+li+">"+fields[2]+" *" + editSpan + "";
guestHosts.push(userRow);
Users.userListIndex.unshift('user-'+fields[0]);
Users.allCount += 1;
break;
default: // guest
userRow = "<"+li+">"+fields[2]+"" + editSpan + "";
}
partyUserList.push(userRow);
Users.userlist['user-'+fields[0]] = fields;
Users.userListIndex.push('user-'+fields[0]);
Users.allCount += 1;
}
$('#partyLocation').html("");
var guestHostHeader = "
Guest Hosts
";
var guestListHeader = "
Guest List
";
for (var i in guestHosts)
guestHosts[i] = guestHosts[i].replace("class='br'","").replace("*","");
// console.log(guestHosts);
// guestHosts[guestHosts.length-1] = guestHosts[guestHosts.length-1].replace("
Here\'s a tip! Use the up and down arrow keys to browse this list.').fadeIn(500)
$('#userViewContainer').html('');
for (id in Users.userlist)
{
$('#'+id).hover(Users.limousein, Users.limouseout)
$('#'+id).click(Users.liclick)
}
for (i in editable)
{
$('#edit-'+editable[i]).bind("click",Users.editClick)
}
Users.hovering = true
},
limouseout: function ()
{
if (Users.hovering)
$("#"+this.id).removeClass("selected")
},
limousein: function ()
{
if (Users.hovering)
{
$("#"+this.id).addClass("selected")
Users.view(this.id)
}
},
liclick: function ()
{
if (! Users.hovering && Users.current === this.id)
{
Nav.selectClass(Users.userlist, false)
Users.current = false
Users.hovering = true
}
else
{
Nav.selectClass(Users.userlist, this.id)
Users.view(this.id)
Users.hovering = false
}
},
viewIdx: function (idx)
{
var id = Users.userListIndex[idx]
if (isScrolledIntoView("#r-"+idx))
{
var offset = $("#r-"+idx)[0].offsetTop+5
if (offset > 300)
$("body").scrollTop( offset )
}
else
{
// get element at x,y
var element = document.elementFromPoint(30,180);
if (element.tagName === "UL")
element = document.elementFromPoint(30,190);
if (element.tagName === "UL")
element = document.elementFromPoint(30,200);
if (element.tagName === "SPAN")
id = element.id
}
Users.hovering = false
Users.view(id)
Nav.selectClass(Users.userlist, id)
},
view: function (id)
{
var user = Users.userlist[id]
var userRec = '';
// 0 id 1 group 2 name 3 email 4 blurb
var blurb = parse_blurb( atob ( user[4] ) )
userRec += "