UNPKG

solid-panes

Version:

Solid-compatible Panes: applets and views for the mashlib and databrowser

1,133 lines (945 loc) • 45 kB
"use strict"; /* Microblog pane Charles McKenzie <charles2@mit.edu> */ /* global alert */ var UI = require('solid-ui'); module.exports = { icon: UI.icons.originalIconBase + 'microblog/microblog.png', name: 'microblogPane', label: function label(subject) { if (UI.store.whether(subject, UI.ns.rdf('type'), UI.ns.foaf('Person'))) { return 'Microblog'; } else { return null; } }, render: function render(s, doc) { //* ********************************************** // NAMESPACES SECTION //* ********************************************** var SIOC = UI.rdf.Namespace('http://rdfs.org/sioc/ns#'); var SIOCt = UI.rdf.Namespace('http://rdfs.org/sioc/types#'); var FOAF = UI.rdf.Namespace('http://xmlns.com/foaf/0.1/'); var terms = UI.rdf.Namespace('http://purl.org/dc/terms/'); var RDF = UI.ns.rdf; var kb = UI.store; var charCount = 140; var sf = UI.store.fetcher; //* ********************************************** // BACK END //* ********************************************** var sparqlUpdater = kb.updater; // ---------------------------------------------- // FOLLOW LIST // store the URIs of followed users for // dereferencing the @replies // ---------------------------------------------- var FollowList = function FollowList(user) { this.userlist = {}; this.uris = {}; var myFollows = kb.each(kb.sym(user), SIOC('follows')); for (var mf in myFollows) { this.add(kb.any(myFollows[mf], SIOC('id')), myFollows[mf].uri); } }; FollowList.prototype.add = function (user, uri) { // add a user to the follows store if (this.userlist[user]) { if (!(uri in this.uris)) { this.userlist[user].push(uri); this.uris[uri] = ''; } } else { this.userlist[user] = [uri]; } }; FollowList.prototype.selectUser = function (user) { // check if a user is in the follows list. if (this.userlist[user]) { return [this.userlist[user].length === 1, this.userlist[user]]; } else { // user does not follow any users with this nick return [false, []]; } }; // ---------------------------------------------- // FAVORITES // controls the list of favorites. // constructor expects a user as uri. // ---------------------------------------------- var Favorites = function Favorites(user) { this.favorites = {}; this.favoritesURI = ''; if (!user) { // TODO is this even useful? return; } this.user = user.split('#')[0]; var created = kb.each(kb.sym(user), SIOC('creator_of')); for (var c in created) { if (kb.whether(created[c], RDF('type'), SIOCt('FavouriteThings'))) { this.favoritesURI = created[c]; var favs = kb.each(created[c], SIOC('container_of')); for (var f in favs) { this.favorites[favs[f]] = ''; } break; } } }; Favorites.prototype.favorited = function (post) { /* Favorited- returns true if the post is a favorite false otherwise */ return kb.sym(post) in this.favorites; }; Favorites.prototype.add = function (post, callback) { var batch = new UI.rdf.Statement(this.favoritesURI, SIOC('container_of'), kb.sym(post), kb.sym(this.user)); sparqlUpdater.insert_statement(batch, function (a, success, c) { if (success) { kb.add(batch.subject, batch.predicate, batch.object, batch.why); } callback(a, success, c); }); }; Favorites.prototype.remove = function (post, callback) { var batch = new UI.rdf.Statement(this.favoritesURI, SIOC('container_of'), kb.sym(post), kb.sym(this.user)); sparqlUpdater.delete_statement(batch, function (a, success, c) { if (success) { kb.add(batch.subject, batch.predicate, batch.object, batch.why); } callback(a, success, c); }); }; // ---------------------------------------------- // MICROBLOG // store the uri's of followed users for // dereferencing the @replies. // ---------------------------------------------- var Microblog = function Microblog(kb) { this.kb = kb; // attempt to fetch user account from local preferences if just // in case the user's foaf was not writable. add it to the store // this will probably need to change. var theUser = UI.authn.currentUser(); if (theUser) { var theAccount = UI.preferences.get('acct'); if (theAccount) { theAccount = kb.sym(theAccount); } if (theUser && theAccount) { kb.add(theUser, FOAF('holdsAccount'), theAccount, theUser.uri.split('#')[0]); } } }; Microblog.prototype.getUser = function (uri) { var User = {}; User.name = kb.any(uri, SIOC('name')) ? kb.any(uri, SIOC('name')) : ''; User.avatar = kb.any(uri, SIOC('avatar')) ? kb.any(uri, SIOC('avatar')) : ''; User.id = kb.any(uri, SIOC('id')); User.sym = uri; return User; }; Microblog.prototype.getPost = function (uri) { var Post = {}; // date ---------- var postLink = new Date(kb.anyValue(uri, terms('created'))); var h = postLink.getHours(); var a = h > 12 ? ' PM' : ' AM'; h = h > 12 ? h - 12 : h; var m = postLink.getMinutes(); m = m < 10 ? '0' + m : m; var mo = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; var da = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; var ds = da[postLink.getDay()] + ' ' + postLink.getDate() + ' ' + mo[postLink.getMonth()] + ' ' + postLink.getFullYear(); postLink = h + ':' + m + a + ' on ' + ds; Post.date = postLink; // --------- Post.mentions = ''; Post.message = String(kb.any(uri, SIOC('content'))); Post.creator = kb.any(uri, SIOC('has_creator')); Post.uri = ''; return Post; }; Microblog.prototype.gen_random_uri = function (base) { // generate random uri var uriNonce = base + '#n' + Math.floor(Math.random() * 10e9); return kb.sym(uriNonce); }; Microblog.prototype.statusUpdate = function (statusMsg, callback, replyTo, meta) { var myUserURI = this.getMyURI(); var myUser = kb.sym(myUserURI.split('#')[0]); var newPost = this.gen_random_uri(myUser.uri); var microlist = kb.each(kb.sym(myUserURI), SIOC('creator_of')); var micro; for (var microlistelement in microlist) { if (kb.whether(microlist[microlistelement], RDF('type'), SIOCt('Microblog')) && !kb.whether(microlist[microlistelement], SIOC('topic'), kb.sym(this.getMyURI()))) { micro = microlist[microlistelement]; break; } } // generate new post var batch = [new UI.rdf.Statement(newPost, RDF('type'), SIOCt('MicroblogPost'), myUser), new UI.rdf.Statement(newPost, SIOC('has_creator'), kb.sym(myUserURI), myUser), new UI.rdf.Statement(newPost, SIOC('content'), statusMsg, myUser), new UI.rdf.Statement(newPost, terms('created'), new Date(), myUser), new UI.rdf.Statement(micro, SIOC('container_of'), newPost, myUser)]; // message replies if (replyTo) { batch.push(new UI.rdf.Statement(newPost, SIOC('reply_of'), kb.sym(replyTo), myUser)); } // @replies, #hashtags, !groupReplies for (var r in meta.recipients) { batch.push(new UI.rdf.Statement(newPost, SIOC('topic'), kb.sym(meta.recipients[r]), myUser)); batch.push(new UI.rdf.Statement(kb.any(), SIOC('container_of'), newPost, myUser)); var mblogs = kb.each(kb.sym(meta.recipients[r]), SIOC('creator_of')); for (var mbl in mblogs) { if (kb.whether(mblogs[mbl], SIOC('topic'), kb.sym(meta.recipients[r]))) { var replyBatch = new UI.rdf.Statement(mblogs[mbl], SIOC('container_of'), newPost, kb.sym(meta.recipients[r].split('#')[0])); sparqlUpdater.insert_statement(replyBatch); } } } sparqlUpdater.insert_statement(batch, function (a, b, c) { callback(a, b, c, batch); }); }; Microblog.prototype.getMyURI = function () { var me = UI.authn.currentUser(); console.log(me); var myMicroblog = kb.any(kb.sym(me), FOAF('holdsAccount')); console.log('\n\n' + myMicroblog); return myMicroblog ? myMicroblog.uri : false; }; Microblog.prototype.generateNewMB = function (id, name, avatar, loc) { var host = loc + '/' + id; var rememberMicroblog = function rememberMicroblog() { UI.preferences.set('acct', host + '#' + id); }; var cbgenUserMB = function cbgenUserMB(a, success, c, d) { if (success) { alert('Microblog generated at ' + host + '#' + id + 'please add <b>' + host + '</b> to your foaf.'); // mbCancelNewMB() @@TBD // assume the foaf is not writable and store the microblog to the // preferences for later retrieval. // this will probably need to change. rememberMicroblog(); for (var triple in d) { kb.add(d[triple].subject, d[triple].predicate, d[triple].object, d[triple].why); } } }; var genUserMB = [// user new UI.rdf.Statement(kb.sym(host + '#' + id), RDF('type'), SIOC('User'), kb.sym(host)), new UI.rdf.Statement(kb.sym(host + '#' + id), SIOC('creator_of'), kb.sym(host + '#mb'), kb.sym(host)), new UI.rdf.Statement(kb.sym(host + '#' + id), SIOC('creator_of'), kb.sym(host + '#mbn'), kb.sym(host)), new UI.rdf.Statement(kb.sym(host + '#' + id), SIOC('creator_of'), kb.sym(host + '#fav'), kb.sym(host)), new UI.rdf.Statement(kb.sym(host + '#' + id), SIOC('name'), name, kb.sym(host)), new UI.rdf.Statement(kb.sym(host + '#' + id), SIOC('id'), id, kb.sym(host)), new UI.rdf.Statement(kb.sym(host + '#' + id), RDF('label'), id, kb.sym(host)), new UI.rdf.Statement(s, FOAF('holdsAccount'), kb.sym(host + '#' + id), kb.sym(host)), // microblog new UI.rdf.Statement(kb.sym(host + '#mb'), RDF('type'), SIOCt('Microblog'), kb.sym(host)), new UI.rdf.Statement(kb.sym(host + '#mb'), SIOC('has_creator'), kb.sym(host + '#' + id), kb.sym(host)), // notification microblog new UI.rdf.Statement(kb.sym(host + '#mbn'), RDF('type'), SIOCt('Microblog'), kb.sym(host)), new UI.rdf.Statement(kb.sym(host + '#mbn'), SIOC('topic'), kb.sym(host + '#' + id), kb.sym(host)), new UI.rdf.Statement(kb.sym(host + '#mbn'), SIOC('has_creator'), kb.sym(host + '#' + id), kb.sym(host)), // favorites container new UI.rdf.Statement(kb.sym(host + '#fav'), RDF('type'), SIOCt('FavouriteThings'), kb.sym(host)), new UI.rdf.Statement(kb.sym(host + '#fav'), SIOC('has_creator'), kb.sym(host + '#' + id), kb.sym(host))]; if (avatar) { // avatar optional genUserMB.push(new UI.rdf.Statement(kb.sym(host + '#' + id), SIOC('avatar'), kb.sym(avatar), kb.sym(host))); } sparqlUpdater.insert_statement(genUserMB, cbgenUserMB); }; var mb = new Microblog(kb); var myFavorites = new Favorites(mb.getMyURI()); var myFollowList = new FollowList(mb.getMyURI()); //* ********************************************** // FRONT END FUNCTIONALITY //* ********************************************** // ---------------------------------------------- // PANE // User Interface for the Microblog Pane // ---------------------------------------------- var Pane = function Pane(s, doc, microblogPane) { var TabManager = function TabManager(doc) { this.tablist = {}; this.doc = doc; this.tabView = doc.createElement('ul'); this.tabView.className = 'tabslist'; }; TabManager.prototype.create = function (id, caption, view, isDefault) { var tab = this.doc.createElement('li'); tab.innerHTML = caption; if (isDefault) { tab.className = 'active'; } tab.id = id; var change = this.change; var tablist = this.tablist; tab.addEventListener('click', function (evt) { change(evt.target.id, tablist, doc); }, false); this.tablist[id] = { view: view.id, tab: tab }; this.tabView.appendChild(tab); }; TabManager.prototype.getTabView = function () { return this.tabView; }; TabManager.prototype.change = function (id, tablist, doc) { for (var tab in tablist) { if (tab === id) { tablist[id].tab.className = 'active'; doc.getElementById(tablist[id].view).className += ' active'; } else { var view = doc.getElementById(tablist[tab].view); view.className = view.className.replace(/\w*active\w*/, ''); tablist[tab].tab.className = tablist[id].tab.className.replace(/\w*active\w*/, ''); } } }; this.microblogPane = microblogPane; var accounts = kb.each(s, FOAF('holdsAccount')); for (var a in accounts) { if (kb.whether(accounts[a], RDF('type'), SIOC('User')) && kb.whether(kb.any(accounts[a], SIOC('creator_of')), RDF('type'), SIOCt('Microblog'))) { var account = accounts[a]; break; } } this.Ifollow = kb.whether(kb.sym(mb.getMyURI()), SIOC('follows'), account); var resourceType = kb.any(s, RDF('type')); if (resourceType.uri === SIOCt('Microblog').uri || resourceType.uri === SIOCt('MicroblogPost').uri) { this.thisIsMe = kb.any(s, SIOC('has_creator')).uri === mb.getMyURI(); } else if (resourceType.uri === SIOC('User').uri) { this.thisIsMe = s.uri === mb.getMyURI(); } else if (resourceType.uri === FOAF('Person').uri) { var me = UI.authn.currentUser(); var meUri = me && me.uri; this.thisIsMe = s.uri === meUri; } else { this.thisIsMe = false; } this.Tab = new TabManager(doc); }; Pane.prototype.notify = function (messageString) { var xmsg = doc.createElement('li'); xmsg.className = 'notify'; xmsg.innerHTML = messageString; doc.getElementById('notify-container').appendChild(xmsg); setTimeout(function () { doc.getElementById('notify-container').removeChild(xmsg); // delete xmsg; }, 4000); }; Pane.prototype.header = function (s, doc) { var that = this; function lsFollowUser() { var myUser = kb.sym(mb.getMyURI()); // var Ifollow = that.Ifollow var username = that.creator.name; var mbconfirmFollow = function mbconfirmFollow(uri, success, _msg) { if (success === true) { if (!that.Ifollow) { // prevent duplicate entries from being added to kb (because that was happening) if (!kb.whether(followMe.subject, followMe.predicate, followMe.object, followMe.why)) { kb.add(followMe.subject, followMe.predicate, followMe.object, followMe.why); } } else { kb.removeMany(followMe.subject, followMe.predicate, followMe.object, followMe.why); } console.log(that.Ifollow); that.Ifollow = !that.Ifollow; xfollowButton.disabled = false; console.log(that.Ifollow); var followButtonLabel = that.Ifollow ? 'Unfollow ' : 'Follow '; var doFollow = that.Ifollow ? 'now follow ' : 'no longer follow '; xfollowButton.value = followButtonLabel + username; that.notify('You ' + doFollow + username + '.'); } }; var followMe = new UI.rdf.Statement(myUser, SIOC('follows'), that.creator.sym, myUser); xfollowButton.disabled = true; xfollowButton.value = 'Updating...'; if (!that.Ifollow) { sparqlUpdater.insert_statement(followMe, mbconfirmFollow); } else { sparqlUpdater.delete_statement(followMe, mbconfirmFollow); } } var notify = function notify(messageString) { var xmsg = doc.createElement('li'); xmsg.className = 'notify'; xmsg.innerHTML = messageString; doc.getElementById('notify-container').appendChild(xmsg); setTimeout(function () { doc.getElementById('notify-container').removeChild(xmsg); // delete xmsg; }, 4000); }; var mbCancelNewMB = function mbCancelNewMB(_evt) { xupdateContainer.removeChild(xupdateContainer.childNodes[xupdateContainer.childNodes.length - 1]); xcreateNewMB.disabled = false; }; var lsCreateNewMB = function lsCreateNewMB(_evt) { // disable the create new microblog button. // then prefills the information. xcreateNewMB.disabled = true; var xcmb = doc.createElement('div'); var xcmbName = doc.createElement('input'); if (kb.whether(s, FOAF('name'))) { // handle use of FOAF:NAME xcmbName.value = kb.any(s, FOAF('name')); } else { // handle use of family and given name xcmbName.value = kb.any(s, FOAF('givenname')) ? kb.any(s, FOAF('givenname')) + ' ' : ''; xcmbName.value += kb.any(s, FOAF('family_name')) ? kb.any(s, FOAF('givenname')) : ''; xcmbName.value = kb.any(s, FOAF('givenname')) + ' ' + kb.any(s, FOAF('family_name')); } var xcmbId = doc.createElement('input'); xcmbId.value = kb.any(s, FOAF('nick')) ? kb.any(s, FOAF('nick')) : ''; var xcmbAvatar = doc.createElement('input'); if (kb.whether(s, FOAF('img'))) { // handle use of img xcmbAvatar.value = kb.any(s, FOAF('img')).uri; } else { // otherwise try depiction xcmbAvatar.value = kb.any(s, FOAF('depiction')) ? kb.any(s, FOAF('depiction')).uri : ''; } var workspace; // = kb.any(s,WORKSPACE) //TODO - ADD URI FOR WORKSPACE DEFINITION var xcmbWritable = doc.createElement('input'); xcmbWritable.value = workspace || 'http://dig.csail.mit.edu/2007/wiki/sandbox'; // @@@ xcmb.innerHTML = "\n <form class =\"createNewMB\" id=\"createNewMB\">\n <p id=\"xcmbname\"><span class=\"\">Name: </span></p>\n <p id=\"xcmbid\">Id: </p>\n <p id=\"xcmbavatar\">Avatar: </p>\n <p id=\"xcmbwritable\">Host my microblog at: </p>\n <input type=\"button\" id=\"mbCancel\" value=\"Cancel\" />\n <input type=\"submit\" id=\"mbCreate\" value=\"Create!\" />\n </form>\n "; xupdateContainer.appendChild(xcmb); doc.getElementById('xcmbname').appendChild(xcmbName); doc.getElementById('xcmbid').appendChild(xcmbId); doc.getElementById('xcmbavatar').appendChild(xcmbAvatar); doc.getElementById('xcmbwritable').appendChild(xcmbWritable); doc.getElementById('mbCancel').addEventListener('click', mbCancelNewMB, false); doc.getElementById('createNewMB').addEventListener('submit', function () { mb.generateNewMB(xcmbId.value, xcmbName.value, xcmbAvatar.value, xcmbWritable.value); }, false); xcmbName.focus(); }; var mbSubmitPost = function mbSubmitPost() { var meta = { recipients: [] }; // user has selected a microblog to post to if (mb.getMyURI()) { // let myUser = kb.sym(mb.getMyURI()) // submission callback var cbconfirmSubmit = function cbconfirmSubmit(uri, success, responseText, d) { if (success === true) { for (var triple in d) { kb.add(d[triple].subject, d[triple].predicate, d[triple].object, d[triple].why); } xupdateSubmit.disabled = false; xupdateStatus.value = ''; mbLetterCount(); notify('Microblog Updated.'); if (that.thisIsMe) { doc.getElementById('postNotificationList').insertBefore(that.generatePost(d[0].subject), doc.getElementById('postNotificationList').childNodes[0]); } } else { notify('There was a problem submitting your post.'); } }; var words = xupdateStatus.value.split(' '); var mbUpdateWithReplies = function mbUpdateWithReplies() { xupdateSubmit.disabled = true; xupdateSubmit.value = 'Updating...'; mb.statusUpdate(xupdateStatus.value, cbconfirmSubmit, xinReplyToContainer.value, meta); }; for (var word in words) { if (words[word].match(/@\w+/)) { var atUser = words[word].replace(/\W/g, ''); var recipient = myFollowList.selectUser(atUser); if (recipient[0] === true) { meta.recipients.push(recipient[1][0]); } else if (recipient[1].length > 1) { // if multiple users allow the user to choose var xrecipients = doc.createElement('select'); var xrecipientsSubmit = doc.createElement('input'); xrecipientsSubmit.type = 'button'; xrecipientsSubmit.value = 'Continue'; xrecipientsSubmit.addEventListener('click', function () { meta.recipients.push(recipient[1][xrecipients.value]); mbUpdateWithReplies(); xrecipients.parentNode.removeChild(xrecipientsSubmit); xrecipients.parentNode.removeChild(xrecipients); }, false); var recipChoice = function recipChoice(recip, c) { var name = kb.any(kb.sym(recip), SIOC('name')); var choice = doc.createElement('option'); choice.value = c; choice.innerHTML = name; return choice; }; for (var r in recipient[1]) { xrecipients.appendChild(recipChoice(recipient[1][r], r)); } xupdateContainer.appendChild(xrecipients); xupdateContainer.appendChild(xrecipientsSubmit); return; } else { // no users known or self reference. if (String(kb.any(kb.sym(mb.getMyURI()), SIOC('id'))).toLowerCase() === atUser.toLowerCase()) { meta.recipients.push(mb.getMyURI()); } else { notify('You do not follow ' + atUser + '. Try following ' + atUser + ' before mentioning them.'); return; } } } /* else if(words[word].match(/\#\w+/)){ //hashtag } else if(words[word].match(/\!\w+/)){ //usergroup } */ } mbUpdateWithReplies(); } else { notify('Please set your microblog first.'); } }; var mbLetterCount = function mbLetterCount() { xupdateStatusCounter.innerHTML = charCount - xupdateStatus.value.length; xupdateStatusCounter.style.color = charCount - xupdateStatus.value.length < 0 ? '#c33' : ''; if (xupdateStatus.value.length === 0) { xinReplyToContainer.value = ''; xupdateSubmit.value = 'Send'; } }; // reply viewer var xviewReply = doc.createElement('ul'); xviewReply.className = 'replyView'; xviewReply.addEventListener('click', function () { xviewReply.className = 'replyView'; }, false); this.xviewReply = xviewReply; var headerContainer = doc.createElement('div'); headerContainer.className = 'header-container'; // ---create status update box--- var xnotify = doc.createElement('ul'); xnotify.id = 'notify-container'; xnotify.className = 'notify-container'; this.xnotify = xnotify; var xupdateContainer = doc.createElement('form'); xupdateContainer.className = 'update-container'; xupdateContainer.innerHTML = '<h3>What are you up to?</h3>'; if (mb.getMyURI()) { var xinReplyToContainer = doc.createElement('input'); xinReplyToContainer.id = 'xinReplyToContainer'; xinReplyToContainer.type = 'hidden'; var xupdateStatus = doc.createElement('textarea'); xupdateStatus.id = 'xupdateStatus'; var xupdateStatusCounter = doc.createElement('span'); xupdateStatusCounter.appendChild(doc.createTextNode(charCount)); xupdateStatus.cols = 30; xupdateStatus.addEventListener('keyup', mbLetterCount, false); xupdateStatus.addEventListener('focus', mbLetterCount, false); var xupdateSubmit = doc.createElement('input'); xupdateSubmit.id = 'xupdateSubmit'; xupdateSubmit.type = 'submit'; xupdateSubmit.value = 'Send'; xupdateContainer.appendChild(xinReplyToContainer); xupdateContainer.appendChild(xupdateStatusCounter); xupdateContainer.appendChild(xupdateStatus); xupdateContainer.appendChild(xupdateSubmit); xupdateContainer.addEventListener('submit', mbSubmitPost, false); } else { var xnewUser = doc.createTextNode("Hi, it looks like you don't have a microblog, " + ' would you like to create one? '); var xcreateNewMB = doc.createElement('input'); xcreateNewMB.type = 'button'; xcreateNewMB.value = 'Create a new Microblog'; xcreateNewMB.addEventListener('click', lsCreateNewMB, false); xupdateContainer.appendChild(xnewUser); xupdateContainer.appendChild(xcreateNewMB); } headerContainer.appendChild(xupdateContainer); var subheaderContainer = doc.createElement('div'); subheaderContainer.className = 'subheader-container'; // user header // this.creator var creators = kb.each(s, FOAF('holdsAccount')); for (var c in creators) { if (kb.whether(creators[c], RDF('type'), SIOC('User')) && kb.whether(kb.any(creators[c], SIOC('creator_of')), RDF('type'), SIOCt('Microblog'))) { var creator = creators[c]; // var mb = kb.sym(creator.uri.split("#")[0]); // UI.store.fetcher.refresh(mb); break; // TODO add support for more than one microblog in same foaf } } if (creator) { this.creator = mb.getUser(creator); // ---display avatar, if available --- if (this.creator.avatar !== '') { var avatar = doc.createElement('img'); avatar.src = this.creator.avatar.uri; subheaderContainer.appendChild(avatar); } // ---generate name --- var userName = doc.createElement('h1'); userName.className = 'fn'; userName.appendChild(doc.createTextNode(this.creator.name + ' (' + this.creator.id + ')')); subheaderContainer.appendChild(userName); // ---display follow button--- if (!this.thisIsMe && mb.getMyURI()) { var xfollowButton = doc.createElement('input'); xfollowButton.setAttribute('type', 'button'); var followButtonLabel = this.Ifollow ? 'Unfollow ' : 'Follow '; xfollowButton.value = followButtonLabel + this.creator.name; xfollowButton.addEventListener('click', lsFollowUser, false); subheaderContainer.appendChild(xfollowButton); } // user header end // header tabs var xtabsList = this.Tab.getTabView(); headerContainer.appendChild(subheaderContainer); headerContainer.appendChild(xtabsList); } return headerContainer; }; Pane.prototype.generatePost = function (post, _me) { /* generatePost - Creates and formats microblog posts post - symbol of the uri the post in question */ var that = this; var viewPost = function viewPost(uris) { var xviewReply = that.xviewReply; for (var i = 0; i < xviewReply.childNodes.length; i++) { xviewReply.removeChild(xviewReply.childNodes[0]); } var xcloseContainer = doc.createElement('li'); xcloseContainer.className = 'closeContainer'; var xcloseButton = doc.createElement('span'); xcloseButton.innerHTML = '&#215;'; xcloseButton.className = 'closeButton'; xcloseContainer.appendChild(xcloseButton); xviewReply.appendChild(xcloseContainer); for (var uri in uris) { xviewReply.appendChild(that.generatePost(kb.sym(uris[uri]), this.thisIsMe, 'view')); } xviewReply.className = 'replyView-active'; that.microblogPane.appendChild(xviewReply); }; // container for post var xpost = doc.createElement('li'); xpost.className = 'post'; xpost.setAttribute('id', String(post.uri).split('#')[1]); var Post = mb.getPost(post); // username text // var uname = kb.any(kb.any(post, SIOC('has_creator')), SIOC('id')) var uholdsaccount = kb.any(undefined, FOAF('holdsAccount'), kb.any(post, SIOC('has_creator'))); var xuname = doc.createElement('a'); xuname.href = uholdsaccount.uri; xuname.className = 'userLink'; var xunameText = doc.createTextNode(mb.getUser(Post.creator).id); xuname.appendChild(xunameText); // user image var xuavatar = doc.createElement('img'); xuavatar.src = mb.getUser(Post.creator).avatar.uri; xuavatar.className = 'postAvatar'; // post content var xpostContent = doc.createElement('blockquote'); var postText = Post.message; // post date var xpostLink = doc.createElement('a'); xpostLink.className = 'postLink'; xpostLink.addEventListener('click', function () { viewPost([post.uri]); }, false); xpostLink.id = 'post_' + String(post.uri).split('#')[1]; xpostLink.setAttribute('content', post.uri); xpostLink.setAttribute('property', 'permalink'); var postLink = doc.createTextNode(Post.date ? Post.date : 'post date unknown'); xpostLink.appendChild(postLink); // LINK META DATA (MENTIONS, HASHTAGS, GROUPS) var mentions = kb.each(post, SIOC('topic')); var tags = {}; for (var mention in mentions) { sf.lookUpThing(mentions[mention]); var id = kb.any(mentions[mention], SIOC('id')); tags['@' + id] = mentions[mention]; } var postTags = postText.match(/(@|#|!)\w+/g); var postFunction = function postFunction() { var p = postTags.pop(); return tags[p] ? kb.any(undefined, FOAF('holdsAccount'), tags[p]).uri : p; }; for (var t in tags) { var person = t.replace(/@/, ''); var replacePerson = RegExp('(@|!|#)(' + person + ')'); postText = postText.replace(replacePerson, '$1<a href="' + postFunction() + '">$2</a>'); } xpostContent.innerHTML = postText; // in reply to logic // This has the potential to support a post that replies to many messages. var inReplyTo = kb.each(post, SIOC('reply_of')); var xreplyTo = doc.createElement('span'); for (var reply in inReplyTo) { var theReply; theReply = String(inReplyTo[reply]).replace(/<|>/g, ''); var genReplyTo = function genReplyTo() { var reply = doc.createElement('a'); reply.innerHTML = ', <b>in reply to</b>'; reply.addEventListener('click', function () { viewPost([post.uri, theReply]); return false; }, false); return reply; }; xreplyTo.appendChild(genReplyTo()); } // END LINK META DATA // add the reply to and delete buttons to the interface var mbReplyTo = function mbReplyTo() { var id = mb.getUser(Post.creator).id; var xupdateStatus = doc.getElementById('xupdateStatus'); var xinReplyToContainer = doc.getElementById('xinReplyToContainer'); var xupdateSubmit = doc.getElementById('xupdateSubmit'); xupdateStatus.value = '@' + id + ' '; xupdateStatus.focus(); xinReplyToContainer.value = post.uri; xupdateSubmit.value = 'Reply'; }; var mbDeletePost = function mbDeletePost(evt) { var lsconfirmNo = function lsconfirmNo() { doc.getElementById('notify-container').removeChild(xconfirmDeletionDialog); evt.target.disabled = false; }; var lsconfirmYes = function lsconfirmYes() { reallyDelete(); doc.getElementById('notify-container').removeChild(xconfirmDeletionDialog); }; evt.target.disabled = true; var xconfirmDeletionDialog = doc.createElement('li'); xconfirmDeletionDialog.className = 'notify conf'; xconfirmDeletionDialog.innerHTML += '<p>Are you sure you want to delete this post?</p>'; xconfirmDeletionDialog.addEventListener('keyup', function (evt) { if (evt.keyCode === 27) { lsconfirmNo(); } }, false); var confirmyes = doc.createElement('input'); confirmyes.type = 'button'; confirmyes.className = 'confirm'; confirmyes.value = 'Delete'; confirmyes.addEventListener('click', lsconfirmYes, false); var confirmno = doc.createElement('input'); confirmno.type = 'button'; confirmno.className = 'confirm'; confirmno.value = 'Cancel'; confirmno.addEventListener('click', lsconfirmNo, false); xconfirmDeletionDialog.appendChild(confirmno); xconfirmDeletionDialog.appendChild(confirmyes); doc.getElementById('notify-container').appendChild(xconfirmDeletionDialog); confirmno.focus(); var reallyDelete = function reallyDelete() { // callback after deletion var mbconfirmDeletePost = function mbconfirmDeletePost(a, success) { if (success) { that.notify('Post deleted.'); // update the ui to reflect model changes. var deleteThisNode = evt.target.parentNode; deleteThisNode.parentNode.removeChild(deleteThisNode); kb.removeMany(deleteMe); } else { that.notify('Oops, there was a problem, please try again'); evt.target.disabled = true; } }; // delete references to post var deleteContainerOf = function deleteContainerOf(a, success) { if (success) { var deleteContainer = kb.statementsMatching(undefined, SIOC('container_of'), kb.sym(doc.getElementById('post_' + evt.target.parentNode.id).getAttribute('content'))); sparqlUpdater.batch_delete_statement(deleteContainer, mbconfirmDeletePost); } else { that.notify('Oops, there was a problem, please try again'); evt.target.disabled = false; } }; // delete attributes of post evt.target.disabled = true; var deleteMe = kb.statementsMatching(kb.sym(doc.getElementById('post_' + evt.target.parentNode.id).getAttribute('content'))); sparqlUpdater.batch_delete_statement(deleteMe, deleteContainerOf); }; }; if (mb.getMyURI()) { // If the microblog in question does not belong to the user, // display the delete post and reply to post buttons. var themaker = kb.any(post, SIOC('has_creator')); if (mb.getMyURI() !== themaker.uri) { var xreplyButton = doc.createElement('input'); xreplyButton.type = 'button'; xreplyButton.value = 'reply'; xreplyButton.className = 'reply'; xreplyButton.addEventListener('click', mbReplyTo, false); } else { var xdeleteButton = doc.createElement('input'); xdeleteButton.type = 'button'; xdeleteButton.value = 'Delete'; xdeleteButton.className = 'reply'; xdeleteButton.addEventListener('click', mbDeletePost, false); } } var mbFavorite = function mbFavorite(evt) { var nid = evt.target.parentNode.id; var favpost = doc.getElementById('post_' + nid).getAttribute('content'); xfavorite.className += ' ing'; var cbFavorite = function cbFavorite(a, success, _c, _d) { if (success) { xfavorite.className = xfavorite.className.split(' ')[1] === 'ed' ? 'favorit' : 'favorit ed'; } }; if (!myFavorites.favorited(favpost)) { myFavorites.add(favpost, cbFavorite); } else { myFavorites.remove(favpost, cbFavorite); } }; var xfavorite = doc.createElement('a'); xfavorite.innerHTML = '&#9733;'; xfavorite.addEventListener('click', mbFavorite, false); if (myFavorites.favorited(post.uri)) { xfavorite.className = 'favorit ed'; } else { xfavorite.className = 'favorit'; } // build xpost.appendChild(xuavatar); xpost.appendChild(xpostContent); if (mb.getMyURI()) { xpost.appendChild(xfavorite); if (mb.getMyURI() !== themaker.uri) { xpost.appendChild(xreplyButton); } else { xpost.appendChild(xdeleteButton); } } xpost.appendChild(xuname); xpost.appendChild(xpostLink); if (inReplyTo !== '') { xpost.appendChild(xreplyTo); } return xpost; }; Pane.prototype.generatePostList = function (gmbPosts) { /* generatePostList - Generate the posts and display their results on the interface. */ var postList = doc.createElement('ul'); var postlist = {}; var datelist = []; for (var post in gmbPosts) { var postDate = kb.any(gmbPosts[post], terms('created')); if (postDate) { datelist.push(postDate); postlist[postDate] = this.generatePost(gmbPosts[post], this.thisIsMe); } } datelist.sort().reverse(); for (var d in datelist) { postList.appendChild(postlist[datelist[d]]); } return postList; }; Pane.prototype.followsView = function () { var getFollowed = function getFollowed(user) { var userid = kb.any(user, SIOC('id')); var follow = doc.createElement('li'); follow.className = 'follow'; userid = userid || user.uri; var fol = kb.any(undefined, FOAF('holdsAccount'), user); fol = fol ? fol.uri : user.uri; follow.innerHTML = '<a href="' + fol + '">' + userid + '</a>'; return follow; }; var xfollows = doc.createElement('div'); xfollows.id = 'xfollows'; xfollows.className = 'followlist-container view-container'; if (this.creator && kb.whether(this.creator.sym, SIOC('follows'))) { var creatorFollows = kb.each(this.creator.sym, SIOC('follows')); var xfollowsList = doc.createElement('ul'); for (var thisPerson in creatorFollows) { xfollowsList.appendChild(getFollowed(creatorFollows[thisPerson])); } xfollows.appendChild(xfollowsList); } this.Tab.create('tab-follows', 'Follows', xfollows, false); return xfollows; }; Pane.prototype.streamView = function (s, doc) { var postContainer = doc.createElement('div'); postContainer.id = 'postContainer'; postContainer.className = 'post-container view-container active'; var mbPosts = []; if (kb.whether(s, FOAF('name')) && kb.whether(s, FOAF('holdsAccount'))) { sf.lookUpThing(kb.any(s, FOAF('holdsAccount'))); var follows = kb.each(kb.any(s, FOAF('holdsAccount')), SIOC('follows')); for (var f in follows) { sf.lookUpThing(follows[f]); // look up people user follows var smicroblogs = kb.each(follows[f], SIOC('creator_of')); // get the follows microblogs for (var smb in smicroblogs) { sf.lookUpThing(smicroblogs[smb]); if (kb.whether(smicroblogs[smb], SIOC('topic'), follows[f])) { continue; } else { mbPosts = mbPosts.concat(kb.each(smicroblogs[smb], SIOC('container_of'))); } } } } if (mbPosts.length > 0) { var postList = this.generatePostList(mbPosts); // generate stream postList.id = 'postList'; postList.className = 'postList'; postContainer.appendChild(postList); } this.Tab.create('tab-stream', 'By Follows', postContainer, true); return postContainer; }; Pane.prototype.notificationsView = function (s, doc) { var postNotificationContainer = doc.createElement('div'); postNotificationContainer.id = 'postNotificationContainer'; postNotificationContainer.className = 'notification-container view-container'; var postMentionContainer = doc.createElement('div'); postMentionContainer.id = 'postMentionContainer'; postMentionContainer.className = 'mention-container view-container'; var mbnPosts = []; var mbmPosts = []; // get mbs that I am the creator of. var theUser = kb.any(s, FOAF('holdsAccount')); var user = kb.any(theUser, SIOC('id')); var microblogs = kb.each(theUser, SIOC('creator_of')); for (var mbm in microblogs) { sf.lookUpThing(microblogs[mbm]); if (kb.whether(microblogs[mbm], SIOC('topic'), theUser)) { mbmPosts = mbmPosts.concat(kb.each(microblogs[mbm], SIOC('container_of'))); } else { if (kb.whether(microblogs[mbm], RDF('type'), SIOCt('Microblog'))) { mbnPosts = mbnPosts.concat(kb.each(microblogs[mbm], SIOC('container_of'))); } } } var postNotificationList = this.generatePostList(mbnPosts); postNotificationList.id = 'postNotificationList'; postNotificationList.className = 'postList'; postNotificationContainer.appendChild(postNotificationList); var postMentionList = this.generatePostList(mbmPosts); postMentionList.id = 'postMentionList'; postMentionList.className = 'postList'; postMentionContainer.appendChild(postMentionList); this.postMentionContainer = postMentionContainer; this.postNotificationContainer = postNotificationContainer; this.Tab.create('tab-by-user', 'By ' + user, postNotificationContainer, false); this.Tab.create('tab-at-user', '@' + user, postMentionContainer, false); }; Pane.prototype.build = function () { var microblogPane = this.microblogPane; this.headerContainer = this.header(s, doc); this.postContainer = this.streamView(s, doc); this.notificationsView(s, doc); this.xfollows = this.followsView(); microblogPane.className = 'ppane'; microblogPane.appendChild(this.xviewReply); microblogPane.appendChild(this.xnotify); microblogPane.appendChild(this.headerContainer); if (this.xfollows !== undefined) { microblogPane.appendChild(this.xfollows); } microblogPane.appendChild(this.postContainer); microblogPane.appendChild(this.postNotificationContainer); microblogPane.appendChild(this.postMentionContainer); }; var microblogpane = doc.createElement('div'); // var getusersfollows = function(uri){ // var follows = new Object(); // var followsa = {follows:0, matches:0}; // var accounts = kb.each(s, FOAF("holdsAccount")); // //get all of the accounts that a person holds // for (var acct in accounts){ // var account = accounts[acct].uri; // var act = kb.each(kb.sym(account),SIOC("follows")); // for (var a in act){ // var thisuri = act[a].uri.split("#")[0]; // if (!follows[thisuri]){followsa.follows+=1;} // follows[thisuri] =true; // } // } // // var buildPaneUI = function(uri){ // followsa.matches = (follows[uri]) ? followsa.matches+1: followsa.matches; // console.log(follows.toSource()); // if(followsa.follows == followsa.matches ){ var ppane = new Pane(s, doc, microblogpane); ppane.build(); // return false; // } // else{ // return true; // } // } // sf.addCallback('done',buildPaneUI); // sf.addCallback('fail',buildPaneUI); // //fetch each of the followers // for (var f in follows){ // sf.refresh(kb.sym(f)); // } // }(s); return microblogpane; } }; //# sourceMappingURL=microblogPane.js.map