diff --git a/www/common/realtime-input.js b/www/common/realtime-input.js index d5f3efef0..fd69f6da0 100644 --- a/www/common/realtime-input.js +++ b/www/common/realtime-input.js @@ -271,19 +271,24 @@ define([ wc.onPeerMessage = function(peerId, type) { onPeerMessage(peerId, type, wc); }; - + if(config.setMyID) { + config.setMyID({ + myID: wc.myID + }); + } // Open a Chainpad session realtime = createRealtime(); if(config.onInit) { config.onInit({ + myID: wc.myID, realtime: realtime, webChannel: wc, userList: userList }); } // Trigger onJoining with our own Cryptpad username to tell the toolbar that we are synced - onJoining(userName); + onJoining(wc.myID); // we're fully synced initializing = false; diff --git a/www/common/toolbar.js b/www/common/toolbar.js index 49b3f2cab..ac7d61d5c 100644 --- a/www/common/toolbar.js +++ b/www/common/toolbar.js @@ -8,6 +8,9 @@ define([ /** Id of the div containing the user list. */ var USER_LIST_CLS = 'rtwysiwyg-user-list'; + /** Id of the button to change my username. */ + var USERNAME_BUTTON_ID = 'rtwysiwyg-change-username'; + /** Id of the div containing the lag info. */ var LAG_ELEM_CLS = 'rtwysiwyg-lag'; @@ -123,29 +126,37 @@ define([ return $container.find('#'+id)[0]; }; - var getOtherUsers = function(myUserName, userList) { + var getOtherUsers = function(myUserName, userList, userData) { var length = userList.length; var list = (length > 1) ? ' : ' : ''; userList.forEach(function(user) { if(user !== myUserName) { - list += user + ', '; + var data = (userData) ? (userData[user] || null) : null; + var userName = (data) ? data.name : user; + list += userName + ', '; } }); return (length > 1) ? list.slice(0, -2) : list; } - var updateUserList = function (myUserName, listElement, userList) { + var createChangeName = function($container, userList, buttonID) { + var id = uid(); + userList.innerHTML = 'Change name'; + return $container.find('#'+id)[0]; + } + + var updateUserList = function (myUserName, listElement, userList, userData) { var meIdx = userList.indexOf(myUserName); if (meIdx === -1) { listElement.textContent = Messages.synchronizing; return; } if (userList.length === 1) { - listElement.textContent = Messages.editingAlone; + listElement.innerHTML = Messages.editingAlone; } else if (userList.length === 2) { - listElement.textContent = Messages.editingWithOneOtherPerson + getOtherUsers(myUserName, userList); + listElement.innerHTML = Messages.editingWithOneOtherPerson + getOtherUsers(myUserName, userList, userData); } else { - listElement.textContent = Messages.editingWith + ' ' + (userList.length - 1) + ' ' + Messages.otherPeople + getOtherUsers(myUserName, userList); + listElement.innerHTML = Messages.editingWith + ' ' + (userList.length - 1) + ' ' + Messages.otherPeople + getOtherUsers(myUserName, userList, userData); } }; @@ -199,22 +210,33 @@ define([ localStorage['CryptPad_RECENTPADS'] = JSON.stringify(out); }; - var create = function ($container, myUserName, realtime, webChannel, userList) { + var create = function ($container, myUserName, realtime, webChannel, userList, config) { var toolbar = createRealtimeToolbar($container); createEscape(toolbar.find('.rtwysiwyg-toolbar-leftside')); var userListElement = createUserList(toolbar.find('.rtwysiwyg-toolbar-leftside')); var spinner = createSpinner(toolbar.find('.rtwysiwyg-toolbar-rightside')); var lagElement = createLagElement(toolbar.find('.rtwysiwyg-toolbar-rightside')); + var userData = config.userData; + var changeNameID = config.changeNameID; + + // Check if the suer is allowed to change his name + if(changeNameID) { + // Create the button and update the element containing the user list + userListElement = createChangeName($container, userListElement, changeNameID); + } rememberPad(); var connected = false; - userList.onChange = function() { + userList.onChange = function(newUserData) { var users = userList.users; if (users.indexOf(myUserName) !== -1) { connected = true; } if (!connected) { return; } - updateUserList(myUserName, userListElement, users); + if(newUserData) { // Someone has changed his name/color + userData = newUserData; + } + updateUserList(myUserName, userListElement, users, userData); } var ks = function () { diff --git a/www/vdom/main.js b/www/vdom/main.js index 532eba384..e849166c7 100644 --- a/www/vdom/main.js +++ b/www/vdom/main.js @@ -122,10 +122,51 @@ define([ }; var initializing = true; + var userList = []; // List of pretty name of all users (mapped with their server ID) + var toolbarList; // List of users still connected to the channel (server IDs) + var addToUserList = function(data) { + for (var attrname in data) { userList[attrname] = data[attrname]; } + if(toolbarList && typeof toolbarList.onChange === "function") { + toolbarList.onChange(userList); + } + }; + + var myData = {}; + var myUserName = ''; // My "pretty name" + var myID; // My server ID + + var setMyID = function(info) { + myID = info.myID || null; + myUserName = myID; + }; + + var createChangeName = function(id, $container) { + var buttonElmt = $container.find('#'+id)[0]; + buttonElmt.addEventListener("click", function() { + var newName = prompt("Change your name :", myUserName) + if (newName && newName.trim()) { + myUserName = newName.trim(); + myData[myID] = { + name: myUserName + }; + addToUserList(myData); + editor.fire( 'change' ); + } + }); + }; // apply patches, and try not to lose the cursor in the process! var applyHjson = function (shjson) { - var userDocStateDom = Convert.hjson.to.dom(JSON.parse(shjson)); + var hjson = JSON.parse(shjson); + console.log(hjson); + var peerUserList = hjson[hjson.length-1]; + if(peerUserList.mydata) { + var userData = peerUserList.mydata; + console.log(userData); + addToUserList(userData); + delete hjson[hjson.length-1]; + } + var userDocStateDom = Convert.hjson.to.dom(hjson); userDocStateDom.setAttribute("contenteditable", "true"); // lol wtf var DD = new DiffDom(diffOptions); var patch = (DD).diff(inner, userDocStateDom); @@ -144,7 +185,13 @@ define([ var onInit = function (info) { var $bar = $('#pad-iframe')[0].contentWindow.$('#cke_1_toolbox'); - toolbar = info.realtime.toolbar = Toolbar.create($bar, userName, info.realtime, info.webChannel, info.userList); + toolbarList = info.userList; + var config = { + userList: userList, + changeNameID: 'cryptpad-changeName' + }; + toolbar = info.realtime.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.webChannel, info.userList, config); + createChangeName('cryptpad-changeName', $bar); /* TODO handle disconnects and such*/ }; @@ -164,6 +211,8 @@ define([ toolbar.failed(); }; + + var realtimeOptions = { // the textarea that we will sync textarea: $textarea[0], @@ -188,6 +237,8 @@ define([ onReady: onReady, + setMyID: setMyID, + // when remote changes occur onRemote: onRemote, @@ -205,7 +256,10 @@ define([ editor.on('change', function () { var hjson = Convert.core.hyperjson.fromDOM(inner); - + if(myData !== {}) { + hjson[hjson.length] = {mydata: myData}; + myData = {}; + } $textarea.val(JSON.stringify(hjson)); rti.bumpSharejs(); });