diff --git a/config.js.dist b/config.js.dist
index f61828e4c..b79777eb7 100644
--- a/config.js.dist
+++ b/config.js.dist
@@ -10,7 +10,7 @@ module.exports = {
// the port on which your httpd will listen
httpPort: 3000,
// the port used for websockets
- websocketPort: 3001,
+ websocketPort: 3000,
// You now have a choice of storage engines
@@ -19,7 +19,7 @@ module.exports = {
* it will not scale well if your server stays alive for a long time.
* but it is completely dependency free
*/
- storage: './storage/amnesia',
+ //storage: './storage/amnesia',
/* the 'lvl' storage module uses leveldb
* it persists, and will perform better than amnesiadb
@@ -31,8 +31,8 @@ module.exports = {
*
* to delete all pads, run `rm -rf $YOUR_DB`
*/
- // storage: './storage/lvl',
- // levelPath: './test.level.db'
+ storage: './storage/lvl',
+ levelPath: './test.level.db'
/* mongo is the original storage engine for cryptpad
* it has been more thoroughly tested, but requires a little more setup
diff --git a/storage/amnesia.js b/storage/amnesia.js
index f068a5e75..bd414b8fb 100644
--- a/storage/amnesia.js
+++ b/storage/amnesia.js
@@ -18,6 +18,7 @@ module.exports.create = function(conf, cb){
var db=[],
index=0;
+
cb({
message: function(channelName, content, cb){
var val = {
@@ -27,17 +28,18 @@ module.exports.create = function(conf, cb){
time: new Date().getTime(),
};
db.push(val);
- cb();
+ if (cb) { cb(); }
},
- getMessages: function(channelName, cb){
+ getMessages: function(channelName, handler, cb){
db.sort(function(a,b){
return a.id - b.id;
});
db.filter(function(val){
return val.chan === channelName;
}).forEach(function(doc){
- cb(doc.msg);
+ handler(doc.msg);
});
+ if (cb) { cb(); }
},
});
};
diff --git a/www/canvas/main.js b/www/canvas/main.js
index f25b64ecb..212f12bfe 100644
--- a/www/canvas/main.js
+++ b/www/canvas/main.js
@@ -4,7 +4,7 @@ require.config({ paths: {
define([
'/api/config?cb=' + Math.random().toString(16).substring(2),
- '/common/RealtimeTextarea.js',
+ '/common/realtime-input.js',
'/common/messages.js',
'/common/crypto.js',
'/common/TextPatcher.js',
@@ -17,12 +17,15 @@ define([
var $ = module.$ = window.jQuery;
var Fabric = module.Fabric = window.fabric;
- $(window).on('hashchange', function() {
- window.location.reload();
- });
- if (window.location.href.indexOf('#') === -1) {
- window.location.href = window.location.href + '#' + Crypto.genKey();
- return;
+
+ var key;
+ var channel = '';
+ if (!/#/.test(window.location.href)) {
+ key = Crypto.genKey();
+ } else {
+ var hash = window.location.hash.slice(1);
+ channel = hash.slice(0, 32);
+ key = hash.slice(32);
}
/* Initialize Fabric */
@@ -56,17 +59,23 @@ define([
$canvas.css('border-color', bool? 'black': 'red');
};
- var key = Crypto.parseKey(window.location.hash.substring(1));
var initializing = true;
var config = module.config = {
- websocketURL: Config.websocketURL + '_old',
+ // TODO initialState ?
+ websocketURL: Config.websocketURL,
userName: Crypto.rand64(8),
- channel: key.channel,
- cryptKey: key.cryptKey
+ channel: channel,
+ cryptKey: key,
+ crypto: Crypto,
};
- var onInit = config.onInit = function (info) { };
+ var onInit = config.onInit = function (info) {
+ window.location.hash = info.channel + key;
+ $(window).on('hashchange', function() {
+ window.location.reload();
+ });
+ };
var onRemote = config.onRemote = function () {
if (initializing) { return; }
diff --git a/www/common/RealtimeTextarea.js b/www/common/RealtimeTextarea.js
deleted file mode 100644
index ee9fcdeb8..000000000
--- a/www/common/RealtimeTextarea.js
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright 2014 XWiki SAS
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-define([
- '/common/messages.js',
- '/bower_components/reconnectingWebsocket/reconnecting-websocket.js',
- '/common/crypto.js',
- '/common/chainpad.js',
- '/bower_components/jquery/dist/jquery.min.js',
-], function (Messages, ReconnectingWebSocket, Crypto) {
- var $ = window.jQuery;
- var ChainPad = window.ChainPad;
- var PARANOIA = true;
- var module = { exports: {} };
-
- /**
- * If an error is encountered but it is recoverable, do not immediately fail
- * but if it keeps firing errors over and over, do fail.
- */
- var MAX_RECOVERABLE_ERRORS = 15;
-
- /** Maximum number of milliseconds of lag before we fail the connection. */
- var MAX_LAG_BEFORE_DISCONNECT = 20000;
-
- var warn = function (x) { console.error(x); };
-
- /* websocket stuff */
- var isSocketDisconnected = function (socket, realtime) {
- var sock = socket._socket;
- return sock.readyState === sock.CLOSING
- || sock.readyState === sock.CLOSED
- || (realtime.getLag().waiting && realtime.getLag().lag > MAX_LAG_BEFORE_DISCONNECT);
- };
-
- // this differs from other functions with similar names in that
- // you are expected to pass a socket into it.
- var checkSocket = function (socket) {
- if (isSocketDisconnected(socket, socket.realtime) &&
- !socket.intentionallyClosing) {
- return true;
- } else {
- return false;
- }
- };
-
- // TODO before removing websocket implementation
- // bind abort to onLeaving
- var abort = function (socket, realtime) {
- realtime.abort();
- try { socket._socket.close(); } catch (e) { warn(e); }
- };
-
- var makeWebsocket = function (url) {
- var socket = new ReconnectingWebSocket(url);
- var out = {
- onOpen: [],
- onClose: [],
- onError: [],
- onMessage: [],
- send: function (msg) { socket.send(msg); },
- close: function () { socket.close(); },
- _socket: socket
- };
- var mkHandler = function (name) {
- return function (evt) {
- for (var i = 0; i < out[name].length; i++) {
- if (out[name][i](evt) === false) {
- console.log(name +"Handler");
- return;
- }
- }
- };
- };
- socket.onopen = mkHandler('onOpen');
- socket.onclose = mkHandler('onClose');
- socket.onerror = mkHandler('onError');
- socket.onmessage = mkHandler('onMessage');
- return out;
- };
- /* end websocket stuff */
-
- var start = module.exports.start = function (config) {
-
- var websocketUrl = config.websocketURL;
- var userName = config.userName;
- var channel = config.channel;
- var cryptKey = config.cryptKey;
- var passwd = 'y';
-
- var toReturn = {};
-
- var socket = makeWebsocket(websocketUrl);
-
- var allMessages = [];
- var isErrorState = false;
- var initializing = true;
- var recoverableErrorCount = 0;
-
- socket.onOpen.push(function (evt) {
- var realtime = socket.realtime = ChainPad.create(userName,
- passwd,
- channel,
- config.initialState || '',
- {
- transformFunction: config.transformFunction
- });
-
- if (config.onInit) {
- // extend as you wish
- config.onInit({
- realtime: realtime
- });
- }
-
- realtime.onUserListChange(function (userList) {
- if (!initializing || userList.indexOf(userName) === -1) {
- return;
- }
- // if we spot ourselves being added to the document, we'll switch
- // 'initializing' off because it means we're fully synced.
- initializing = false;
-
- // execute an onReady callback if one was supplied
- // pass an object so we can extend this later
- if (config.onReady) {
- // extend as you wish
- config.onReady({
- userList: userList,
- realtime: realtime
- });
- }
- });
-
- // when you receive a message...
- socket.onMessage.push(function (evt) {
- if (isErrorState) { return; }
-
- var message = Crypto.decrypt(evt.data, cryptKey);
- allMessages.push(message);
-
- // super important step that avoids us having
- // the 'backspace bug'
- if (config.onLocal) {
- config.onLocal();
- }
-
- realtime.message(message);
- });
-
- // when you receive a patch
- realtime.onPatch(function () {
- if (config.onRemote) {
- config.onRemote({
- realtime: realtime
- });
- }
- });
-
- // when a message is ready to send
- realtime.onMessage(function (message) {
- if (isErrorState) { return; }
- message = Crypto.encrypt(message, cryptKey);
- try {
- socket.send(message);
- } catch (e) {
- warn(e);
- }
- });
-
- var socketChecker = setInterval(function () {
- if (checkSocket(socket)) {
- warn("Socket disconnected!");
-
- recoverableErrorCount += 1;
-
- if (recoverableErrorCount >= MAX_RECOVERABLE_ERRORS) {
- warn("Giving up!");
- abort(socket, realtime);
- if (config.onAbort) {
- config.onAbort({
- realtime: realtime
- });
- }
- if (socketChecker) { clearInterval(socketChecker); }
- }
- }
- },200);
-
- realtime.start();
- });
- return toReturn;
- };
- return module.exports;
-});
diff --git a/www/common/json-ot.js b/www/common/json-ot.js
index a785d524c..f04cf3b75 100644
--- a/www/common/json-ot.js
+++ b/www/common/json-ot.js
@@ -4,10 +4,9 @@ define([
var ChainPad = window.ChainPad;
var JsonOT = {};
-/* FIXME
- resultOp after transform0() might be null, in which case you should return null
- because it is simply a transformation which yields a "do nothing" operation */
var validate = JsonOT.validate = function (text, toTransform, transformBy) {
+ var DEBUG = window.REALTIME_DEBUG = window.REALTIME_DEBUG || {};
+
var resultOp, text2, text3;
try {
// text = O (mutual common ancestor)
@@ -28,7 +27,7 @@ define([
return resultOp;
} catch (e) {
console.error(e);
- var info = window.REALTIME_MODULE.ot_parseError = {
+ var info = DEBUG.ot_parseError = {
type: 'resultParseError',
resultOp: resultOp,
@@ -40,11 +39,11 @@ define([
text3: text3,
error: e
};
- console.log('Debugging info available at `window.REALTIME_MODULE.ot_parseError`');
+ console.log('Debugging info available at `window.REALTIME_DEBUG.ot_parseError`');
}
} catch (x) {
console.error(x);
- window.REALTIME_MODULE.ot_applyError = {
+ window.DEBUG.ot_applyError = {
type: 'resultParseError',
resultOp: resultOp,
@@ -56,7 +55,7 @@ define([
text3: text3,
error: x
};
- console.log('Debugging info available at `window.REALTIME_MODULE.ot_applyError`');
+ console.log('Debugging info available at `window.REALTIME_DEBUG.ot_applyError`');
}
// returning **null** breaks out of the loop
diff --git a/www/common/netflux-client.js b/www/common/netflux-client.js
index e6567229a..7d436f018 100644
--- a/www/common/netflux-client.js
+++ b/www/common/netflux-client.js
@@ -51,6 +51,7 @@ const mkChannel = (ctx, id) => {
};
const chan = {
_: internal,
+ time: now(),
id: id,
members: internal.members,
bcast: (msg) => channelBcast(ctx, chan.id, msg),
diff --git a/www/common/realtime-input.js b/www/common/realtime-input.js
index 7e818f8ae..5a8726e35 100644
--- a/www/common/realtime-input.js
+++ b/www/common/realtime-input.js
@@ -15,16 +15,15 @@
* along with this program. If not, see .
*/
define([
- '/common/messages.js',
'/common/netflux-client.js',
- '/common/crypto.js',
'/common/es6-promise.min.js',
'/common/chainpad.js',
'/bower_components/jquery/dist/jquery.min.js',
-], function (Messages, Netflux, Crypto) {
+], function (Netflux) {
var $ = window.jQuery;
var ChainPad = window.ChainPad;
var PARANOIA = true;
+ var USE_HISTORY = true;
var module = { exports: {} };
/**
@@ -44,16 +43,14 @@ define([
var websocketUrl = config.websocketURL;
var userName = config.userName;
var channel = config.channel;
- var chanKey = config.cryptKey;
+ var chanKey = config.cryptKey || '';
+ var Crypto = config.crypto;
var cryptKey = Crypto.parseKey(chanKey).cryptKey;
var passwd = 'y';
// make sure configuration is defined
config = config || {};
- var doc = config.doc || null;
-
- var allMessages = [];
var initializing = true;
var recoverableErrorCount = 0; // unused
var toReturn = {};
@@ -101,14 +98,17 @@ define([
};
var onReady = function(wc, network) {
+ if(config.setMyID) {
+ config.setMyID({
+ myID: wc.myID
+ });
+ }
// Trigger onJoining with our own Cryptpad username to tell the toolbar that we are synced
onJoining(wc.myID);
// we're fully synced
initializing = false;
- // execute an onReady callback if one was supplied
- // FIXME this should be once the chain has synced
if (config.onReady) {
config.onReady({
realtime: realtime
@@ -131,11 +131,10 @@ define([
var message = chainpadAdapter.msgIn(peer, msg);
verbose(message);
- allMessages.push(message);
if (!initializing) {
- if (toReturn.onLocal) {
- toReturn.onLocal();
+ if (config.onLocal) {
+ config.onLocal();
}
}
// pass the message into Chainpad
@@ -209,11 +208,6 @@ define([
wc.on('join', onJoining);
wc.on('leave', onLeaving);
- if(config.setMyID) {
- config.setMyID({
- myID: wc.myID
- });
- }
// Open a Chainpad session
realtime = createRealtime();
@@ -253,14 +247,22 @@ define([
});
// Get the channel history
- var hc;
- wc.members.forEach(function (p) {
- if (p.length === 16) { hc = p; }
- });
- wc.history_keeper = hc;
- if (hc) { network.sendto(hc, JSON.stringify(['GET_HISTORY', wc.id])); }
+ if(USE_HISTORY) {
+ var hc;
+
+ wc.members.forEach(function (p) {
+ if (p.length === 16) { hc = p; }
+ });
+ wc.history_keeper = hc;
+
+ if (hc) { network.sendto(hc, JSON.stringify(['GET_HISTORY', wc.id])); }
+ }
realtime.start();
+
+ if(!USE_HISTORY) {
+ onReady(wc, network);
+ }
};
var findChannelById = function(webChannels, channelId) {
diff --git a/www/hack/main.js b/www/hack/main.js
index 8805a3169..fe71ac64d 100644
--- a/www/hack/main.js
+++ b/www/hack/main.js
@@ -1,21 +1,24 @@
define([
'/api/config?cb=' + Math.random().toString(16).substring(2),
- '/common/RealtimeTextarea.js',
+ '/common/realtime-input.js',
'/common/crypto.js',
'/common/TextPatcher.js',
'/bower_components/jquery/dist/jquery.min.js'
], function (Config, Realtime, Crypto, TextPatcher) {
var $ = window.jQuery;
- $(window).on('hashchange', function() {
- window.location.reload();
- });
+
+ var key;
+ var channel = '';
if (window.location.href.indexOf('#') === -1) {
- window.location.href = window.location.href + '#' + Crypto.genKey();
- return;
+ key = Crypto.genKey();
+ //window.location.href = window.location.href + '#' + Crypto.genKey();
+ //return;
+ } else {
+ var hash = window.location.hash.substr(1);
+ channel = hash.substr(0,32);
+ key = hash.substr(32);
}
- var key = Crypto.parseKey(window.location.hash.substring(1));
-
var $textarea = $('textarea'),
$run = $('#run');
@@ -29,13 +32,15 @@ define([
transformFunction
*/
+ var userName = Crypto.rand64(8);
+
var config = {
- textarea: $textarea[0],
- websocketURL: Config.websocketURL + '_old',
- webrtcURL: Config.webrtcURL,
- userName: Crypto.rand64(8),
- channel: key.channel,
- cryptKey: key.cryptKey,
+ initialState: '',
+ websocketURL: Config.websocketURL,
+ userName: userName,
+ channel: channel,
+ cryptKey: key,
+ crypto: Crypto,
};
var initializing = true;
@@ -44,7 +49,10 @@ define([
setEditable(false);
- var onInit = config.onInit = function (info) { };
+ var onInit = config.onInit = function (info) {
+ window.location.hash = info.channel + key;
+ $(window).on('hashchange', function() { window.location.reload(); });
+ };
var onRemote = config.onRemote = function (info) {
if (initializing) { return; }
diff --git a/www/p/main.js b/www/p/main.js
index 023f9b9f1..64eda9f70 100644
--- a/www/p/main.js
+++ b/www/p/main.js
@@ -194,9 +194,6 @@ define([
var now = function () { return new Date().getTime(); };
var realtimeOptions = {
- // configuration :D
- doc: inner,
-
// provide initialstate...
initialState: stringifyDOM(inner) || '{}',
@@ -213,7 +210,9 @@ define([
channel: key.channel,
// encryption key
- cryptKey: key.cryptKey
+ cryptKey: key.cryptKey,
+
+ crypto: Crypto,
};
var DD = new DiffDom(diffOptions);
diff --git a/www/pad/main.js b/www/pad/main.js
index c535b678b..11b45843e 100644
--- a/www/pad/main.js
+++ b/www/pad/main.js
@@ -87,7 +87,6 @@ define([
}
var fixThings = false;
- // var key = Crypto.parseKey(window.location.hash.substring(1));
var editor = window.editor = Ckeditor.replace('editor1', {
// https://dev.ckeditor.com/ticket/10907
needsBrFiller: fixThings,
@@ -184,7 +183,6 @@ define([
}
};
- var now = function () { return new Date().getTime(); };
var initializing = true;
var userList = {}; // List of pretty name of all users (mapped with their server ID)
@@ -250,16 +248,29 @@ define([
// our encryption key
cryptKey: key,
- // configuration :D
- doc: inner,
-
+ // method which allows us to get the id of the user
setMyID: setMyID,
+ // Crypto object to avoid loading it twice in Cryptpad
+ crypto: Crypto,
+
// really basic operational transform
transformFunction : JsonOT.validate
- // pass in websocket/netflux object TODO
};
+ var updateUserList = function(shjson) {
+ // Extract the user list (metadata) from the hyperjson
+ var hjson = JSON.parse(shjson);
+ var peerUserList = hjson[hjson.length-1];
+ if(peerUserList.metadata) {
+ var userData = peerUserList.metadata;
+ // Update the local user data
+ addToUserList(userData);
+ hjson.pop();
+ }
+ return hjson;
+ }
+
var onRemote = realtimeOptions.onRemote = function (info) {
if (initializing) { return; }
@@ -269,18 +280,7 @@ define([
cursor.update();
// Extract the user list (metadata) from the hyperjson
- var hjson = JSON.parse(shjson);
- var peerUserList = hjson[hjson.length-1];
- if(peerUserList.metadata) {
- var userData = peerUserList.metadata;
- // Update the local user data
- userList = userData;
- // Send the new data to the toolbar
- if(toolbarList && typeof toolbarList.onChange === "function") {
- toolbarList.onChange(userList);
- }
- hjson.pop();
- }
+ var hjson = updateUserList(shjson);
// build a dom from HJSON, diff, and patch the editor
applyHjson(shjson);
diff --git a/www/padrtc/main.js b/www/padrtc/main.js
index ba983e799..233241a86 100644
--- a/www/padrtc/main.js
+++ b/www/padrtc/main.js
@@ -206,14 +206,12 @@ define([
// our encryption key
cryptKey: key,
- // configuration :D
- doc: inner,
-
setMyID: setMyID,
// really basic operational transform
- transformFunction : JsonOT.validate
- // pass in websocket/netflux object TODO
+ transformFunction : JsonOT.validate,
+
+ crypto: Crypto,
};
var onRemote = realtimeOptions.onRemote = function (info) {
diff --git a/www/style/index.html b/www/style/index.html
index e9fdf2855..4ede5c688 100644
--- a/www/style/index.html
+++ b/www/style/index.html
@@ -8,7 +8,6 @@
Edit this document's style
-
HTML Ipsum Presents
diff --git a/www/style/main.js b/www/style/main.js
index b230bbb3f..7fe78cc34 100644
--- a/www/style/main.js
+++ b/www/style/main.js
@@ -1,31 +1,34 @@
define([
'/api/config?cb=' + Math.random().toString(16).substring(2),
'/common/realtime-input.js',
- '/common/messages.js',
'/common/crypto.js',
+ '/common/TextPatcher.js',
'/bower_components/jquery/dist/jquery.min.js',
'/customize/pad.js'
-], function (Config, Realtime, Messages, Crypto) {
+], function (Config, Realtime, Crypto, TextPatcher) {
// TODO consider adding support for less.js
var $ = window.jQuery;
- $(window).on('hashchange', function() {
- window.location.reload();
- });
- var userName = Crypto.rand64(8);
+ var module = window.APP = {};
- if (window.location.href.indexOf('#') === -1) {
- window.location.href = window.location.href + '#' + Crypto.genKey();
- return;
+ var key;
+ var channel = '';
+ if (!/#/.test(window.location.href)) {
+ key = Crypto.genKey();
+ } else {
+ var hash = window.location.hash.slice(1);
+ channel = hash.slice(0, 32);
+ key = hash.slice(32);
}
- var key = Crypto.parseKey(window.location.hash.slice(1));
-
- var $style = $('style').first(),
- $css = $('#css'),
- $edit = $('#edit');
+ var config = {
+ websocketURL: Config.websocketURL,
+ channel: channel,
+ cryptKey: key,
+ crypto: Crypto,
+ };
- $edit.attr('href', '/text/'+ window.location.hash);
+ var userName = module.userName = config.userName = Crypto.rand64(8);
var lazyDraw = (function () {
var to,
@@ -38,29 +41,47 @@ define([
};
}());
- var draw = function () {
- lazyDraw($css.val());
+ var draw = function (content) { lazyDraw(content); };
+
+ var initializing = true;
+
+ var onInit = config.onInit = function (info) {
+ window.location.hash = info.channel + key;
+ var realtime = module.realtime = info.realtime;
+ module.patchText = TextPatcher.create({
+ realtime: realtime,
+ logging: true,
+ });
+
+ $(window).on('hashchange', function() {
+ window.location.reload();
+ });
+ };
+
+ var onReady = config.onReady = function (info) {
+ var userDoc = module.realtime.getUserDoc();
+ draw(userDoc);
+ console.log("Ready");
+ initializing = false;
};
- $css // set the initial value
- .val($style.text())
- .on('change', draw);
+ var onRemote = config.onRemote = function () {
+ draw(module.realtime.getUserDoc());
+ };
- var rts = $('textarea').toArray().map(function (e, i) {
+ var onAbort = config.onAbort = function (info) {
+ // notify the user of the abort
+ window.alert("Network Connection Lost");
+ };
- var config = {
- onRemote: draw,
- onInit: draw,
- onReady: draw,
+ var onLocal = config.onLocal = function () {
+ // nope
+ };
- textarea: e,
- websocketURL: Config.websocketURL,
- userName: userName,
- channel: key.channel,
- cryptKey: key.cryptKey
- };
+ var $style = $('style').first(),
+ $edit = $('#edit');
+
+ $edit.attr('href', '/text/'+ window.location.hash);
- var rt = Realtime.start(config);
- return rt;
- });
+ var rt = Realtime.start(config);
});
diff --git a/www/text/main.js b/www/text/main.js
index 0143a0f10..2b91c446d 100644
--- a/www/text/main.js
+++ b/www/text/main.js
@@ -1,32 +1,38 @@
define([
'/api/config?cb=' + Math.random().toString(16).substring(2),
- '/common/RealtimeTextarea.js',
- '/common/messages.js',
+ '/common/realtime-input.js',
'/common/crypto.js',
'/common/TextPatcher.js',
'/bower_components/jquery/dist/jquery.min.js',
'/customize/pad.js'
-], function (Config, Realtime, Messages, Crypto, TextPatcher) {
+], function (Config, Realtime, Crypto, TextPatcher) {
var $ = window.jQuery;
- $(window).on('hashchange', function() {
- window.location.reload();
- });
+
+ var key;
+ var channel = '';
if (window.location.href.indexOf('#') === -1) {
- window.location.href = window.location.href + '#' + Crypto.genKey();
- return;
+ key = Crypto.genKey();
+ } else {
+ var hash = window.location.hash.substr(1);
+ channel = hash.substr(0, 32);
+ key = hash.substr(32);
}
var module = window.APP = {};
- var key = Crypto.parseKey(window.location.hash.substring(1));
+
+ var userName = module.userName = Crypto.rand64(8);
+
var initializing = true;
var $textarea = $('textarea');
var config = module.config = {
+ initialState: '',
textarea: $textarea[0],
- websocketURL: Config.websocketURL + '_old',
- userName: Crypto.rand64(8),
- channel: key.channel,
- cryptKey: key.cryptKey
+ websocketURL: Config.websocketURL,
+ userName: userName,
+ channel: channel,
+ cryptKey: key,
+ crypto: Crypto,
};
var setEditable = function (bool) { $textarea.attr('disabled', !bool); };
@@ -34,7 +40,12 @@ define([
setEditable(false);
- var onInit = config.onInit = function (info) { };
+ var onInit = config.onInit = function (info) {
+ window.location.hash = info.channel + key;
+ $(window).on('hashchange', function() {
+ window.location.reload();
+ });
+ };
var onRemote = config.onRemote = function (info) {
if (initializing) { return; }