navigation mostly works but still buggy
This commit is contained in:
+65
-52
@@ -258,6 +258,8 @@
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper functions for hash navigation.
|
||||||
|
|
||||||
// Parse hash as in http://www.example.com/path#hash as if it were
|
// Parse hash as in http://www.example.com/path#hash as if it were
|
||||||
// path and arguments.
|
// path and arguments.
|
||||||
function parseUrlHash(hash) {
|
function parseUrlHash(hash) {
|
||||||
@@ -293,22 +295,31 @@
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addParamToHash(hash, key, value) {
|
function addUrlParam(hash, key, value) {
|
||||||
var hash = parseUrlHash(hash);
|
var parsed = parseUrlHash(hash);
|
||||||
if (!hash.params) {
|
parsed.params[key] = value;
|
||||||
hash.params = {};
|
return composeUrlHash(parsed.path, parsed.params);
|
||||||
}
|
|
||||||
hash.params[key] = value;
|
|
||||||
return composeUrlHash(hash.path, hash.params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeParamFromHash(hash, key) {
|
function removeUrlParam(hash, key) {
|
||||||
var hash = parseUrlHash(hash);
|
var parsed = parseUrlHash(hash);
|
||||||
if (hash.params) {
|
delete parsed.params[key];
|
||||||
delete hash.params[key];
|
return composeUrlHash(parsed.path, parsed.params);
|
||||||
}
|
|
||||||
return composeUrlHash(hash.path, hash.params);
|
|
||||||
}
|
}
|
||||||
|
function setUrlSidePanel(hash, sidepanel) {
|
||||||
|
var parsed = parseUrlHash(hash);
|
||||||
|
parsed.path[0] = sidepanel;
|
||||||
|
return composeUrlHash(parsed.path, parsed.params);
|
||||||
|
}
|
||||||
|
function setUrlTopic(hash, topic) {
|
||||||
|
var parsed = parseUrlHash(hash);
|
||||||
|
parsed.path[1] = topic;
|
||||||
|
// Close InfoView on topic change.
|
||||||
|
delete parsed.params.info;
|
||||||
|
return composeUrlHash(parsed.path, parsed.params);
|
||||||
|
}
|
||||||
|
// END of hash navigation helper functions
|
||||||
|
|
||||||
|
|
||||||
// Detect server address from the URL
|
// Detect server address from the URL
|
||||||
function detectServerAddress() {
|
function detectServerAddress() {
|
||||||
@@ -2201,21 +2212,21 @@
|
|||||||
},
|
},
|
||||||
handleTabClick: function(e) {
|
handleTabClick: function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
window.location.hash = addParamToHash(window.location.hash, 'tab', e.currentTarget.dataset.id);
|
window.location.hash = addUrlParam(window.location.hash, 'tab', e.currentTarget.dataset.id);
|
||||||
this.setState({tabSelected: e.currentTarget.dataset.id, contactSelected: null});
|
this.setState({tabSelected: e.currentTarget.dataset.id, contactSelected: null});
|
||||||
},
|
},
|
||||||
handleContactSelected: function(sel) {
|
handleContactSelected: function(sel) {
|
||||||
if (this.state.tabSelected === "p2p") {
|
if (this.state.tabSelected === "p2p") {
|
||||||
window.location.hash = removeParamFromHash(window.location.hash, 'tab');
|
window.location.hash = removeUrlParam(window.location.hash, 'tab');
|
||||||
this.props.onCreateTopic(sel, undefined);
|
this.props.onCreateTopic(sel, undefined);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleNewGroupSubmit: function(name, dataUrl, priv, tags) {
|
handleNewGroupSubmit: function(name, dataUrl, priv, tags) {
|
||||||
window.location.hash = removeParamFromHash(window.location.hash, 'tab');
|
window.location.hash = removeUrlParam(window.location.hash, 'tab');
|
||||||
this.props.onCreateTopic(undefined, vcard(name, dataUrl), priv, tags);
|
this.props.onCreateTopic(undefined, vcard(name, dataUrl), priv, tags);
|
||||||
},
|
},
|
||||||
handleGroupByID: function(topicName) {
|
handleGroupByID: function(topicName) {
|
||||||
window.location.hash = removeParamFromHash(window.location.hash, 'tab');
|
window.location.hash = removeUrlParam(window.location.hash, 'tab');
|
||||||
this.props.onCreateTopic(topicName);
|
this.props.onCreateTopic(topicName);
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
@@ -2406,7 +2417,7 @@
|
|||||||
var ValidationView = React.createClass({
|
var ValidationView = React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
code: '',
|
code: this.props.credCode || '',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
handleChange: function(e) {
|
handleChange: function(e) {
|
||||||
@@ -2420,12 +2431,12 @@
|
|||||||
handleSubmit: function(e) {
|
handleSubmit: function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (this.state.code && this.state.code.trim()) {
|
if (this.state.code && this.state.code.trim()) {
|
||||||
this.props.onSubmit(this.props.credMethod[0], this.state.code.trim());
|
this.props.onSubmit(this.props.credMethod, this.state.code.trim());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
var methods = {'email': 'email', 'tel': 'phone'};
|
var methods = {'email': 'email', 'tel': 'phone'};
|
||||||
var method = methods[this.props.credMethod[0]] || this.props.credMethod[0];
|
var method = methods[this.props.credMethod] || this.props.credMethod;
|
||||||
return (
|
return (
|
||||||
<div className="panel-form">
|
<div className="panel-form">
|
||||||
<div className="panel-form-row">
|
<div className="panel-form-row">
|
||||||
@@ -3767,7 +3778,7 @@
|
|||||||
serverVersion: 'no connection',
|
serverVersion: 'no connection',
|
||||||
contactsSearchQuery: '',
|
contactsSearchQuery: '',
|
||||||
foundContacts: [],
|
foundContacts: [],
|
||||||
credMethod: []
|
credMethod: ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
@@ -3807,11 +3818,11 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Handle for hashchange event: display appropriate panels.
|
// Handle for hashchange event: display appropriate panels.
|
||||||
handleHashRoute: function(e) {
|
handleHashRoute: function() {
|
||||||
var hash = parseUrlHash(window.location.hash);
|
var hash = parseUrlHash(window.location.hash);
|
||||||
// Left-side panel selector.
|
// Left-side panel selector.
|
||||||
if (hash.path && hash.path.length >0) {
|
if (hash.path && hash.path.length >0) {
|
||||||
if (['register','settings','edit','cred','newtpk',''].includes(hash.path[0])) {
|
if (['register','settings','edit','cred','newtpk','contacts',''].includes(hash.path[0])) {
|
||||||
this.setState({sidePanelSelected: hash.path[0]});
|
this.setState({sidePanelSelected: hash.path[0]});
|
||||||
} else {
|
} else {
|
||||||
console.log("Unknown sidepanel view", hash.path[0]);
|
console.log("Unknown sidepanel view", hash.path[0]);
|
||||||
@@ -3829,7 +3840,7 @@
|
|||||||
// Additional parameters of panels.
|
// Additional parameters of panels.
|
||||||
this.setState({
|
this.setState({
|
||||||
credCode: hash.params.code,
|
credCode: hash.params.code,
|
||||||
credMethod: hash.params.cred,
|
credMethod: hash.params.method,
|
||||||
showInfoPanel: hash.params.info,
|
showInfoPanel: hash.params.info,
|
||||||
newTopicTabSelected: hash.params.tab
|
newTopicTabSelected: hash.params.tab
|
||||||
});
|
});
|
||||||
@@ -3875,8 +3886,14 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
doLogin: function(login, password, cred) {
|
doLogin: function(login, password, cred) {
|
||||||
var instance = this;
|
if (Tinode.isAuthenticated()) {
|
||||||
cred = cred ? Tinode.addCredential(null, cred).cred : undefined;
|
// Already logged in. Go to default screen.
|
||||||
|
window.location.hash = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
cred = cred ? Tinode.addCredential(null, cred) : undefined;
|
||||||
|
cred = cred ? cred.cred : undefined;
|
||||||
|
|
||||||
// Try to login with login/password. If they are not available, try token. If no token, ask for login/password.
|
// Try to login with login/password. If they are not available, try token. If no token, ask for login/password.
|
||||||
var promise = null;
|
var promise = null;
|
||||||
var token = Tinode.getAuthToken();
|
var token = Tinode.getAuthToken();
|
||||||
@@ -3890,6 +3907,7 @@
|
|||||||
this.setState({loginDisabled: false});
|
this.setState({loginDisabled: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var instance = this;
|
||||||
if (promise) {
|
if (promise) {
|
||||||
promise.then(function(ctrl) {
|
promise.then(function(ctrl) {
|
||||||
if (ctrl.code >= 300 && ctrl.text === "validate credentials") {
|
if (ctrl.code >= 300 && ctrl.text === "validate credentials") {
|
||||||
@@ -3902,6 +3920,7 @@
|
|||||||
instance.setState({loginDisabled: false});
|
instance.setState({loginDisabled: false});
|
||||||
instance.handleError(err.message, "err");
|
instance.handleError(err.message, "err");
|
||||||
localStorage.removeItem("auth-token");
|
localStorage.removeItem("auth-token");
|
||||||
|
window.location.hash = "";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3909,7 +3928,7 @@
|
|||||||
handleCredentialsRequest: function(params) {
|
handleCredentialsRequest: function(params) {
|
||||||
var parsed = parseUrlHash(window.location.hash);
|
var parsed = parseUrlHash(window.location.hash);
|
||||||
parsed.path[0] = 'cred';
|
parsed.path[0] = 'cred';
|
||||||
parsed.params['cred'] = params.cred;
|
parsed.params['method'] = params.cred[0];
|
||||||
window.location.hash = composeUrlHash(parsed.path, parsed.params);
|
window.location.hash = composeUrlHash(parsed.path, parsed.params);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -3922,10 +3941,13 @@
|
|||||||
// Logged in fine, subscribe to 'me' attaching callbacks from the contacts view.
|
// Logged in fine, subscribe to 'me' attaching callbacks from the contacts view.
|
||||||
var me = Tinode.getMeTopic();
|
var me = Tinode.getMeTopic();
|
||||||
me.onMetaDesc = instance.tnMeMetaDesc;
|
me.onMetaDesc = instance.tnMeMetaDesc;
|
||||||
window.location.hash = "";
|
if (!window.location.hash) {
|
||||||
|
window.location.hash = 'contacts';
|
||||||
|
} else {
|
||||||
|
instance.handleHashRoute();
|
||||||
|
}
|
||||||
instance.setState({
|
instance.setState({
|
||||||
connected: true,
|
connected: true,
|
||||||
sidePanelSelected: '',
|
|
||||||
myUserId: Tinode.getCurrentUserID()
|
myUserId: Tinode.getCurrentUserID()
|
||||||
});
|
});
|
||||||
// Subscribe, fetch topic desc, the list of subscriptions. Messages are not fetched.
|
// Subscribe, fetch topic desc, the list of subscriptions. Messages are not fetched.
|
||||||
@@ -4017,28 +4039,25 @@
|
|||||||
if (topicName) {
|
if (topicName) {
|
||||||
// Contact selected
|
// Contact selected
|
||||||
if (this.state.topicSelected != topicName) {
|
if (this.state.topicSelected != topicName) {
|
||||||
var parsed = parseUrlHash(window.location.hash);
|
window.location.hash = setUrlTopic(window.location.hash, topicName);
|
||||||
parsed.path[1] = topicName;
|
|
||||||
window.location.hash = composeUrlHash(parsed.path, parsed.params);
|
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
|
errorText: '',
|
||||||
|
errorLevel: null,
|
||||||
mobilePanel: 'topic-view',
|
mobilePanel: 'topic-view',
|
||||||
showInfoPanel: false,
|
|
||||||
topicSelectedOnline: online,
|
topicSelectedOnline: online,
|
||||||
topicSelectedAcs: acs,
|
topicSelectedAcs: acs,
|
||||||
sidePanelSelected: '',
|
|
||||||
infoPanelShowMembers: Tinode.getTopicType(topicName) === "grp"
|
infoPanelShowMembers: Tinode.getTopicType(topicName) === "grp"
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (this.state.topicSelected) {
|
if (this.state.topicSelected) {
|
||||||
var parsed = parseUrlHash(window.location.hash);
|
window.history.replaceState({}, "", setUrlTopic(window.location.hash, ''));
|
||||||
parsed.path[1] = '';
|
|
||||||
window.history.replaceState({}, "", composeUrlHash(parsed.path, parsed.params));
|
|
||||||
}
|
}
|
||||||
// Currently selected contact deleted
|
// Currently selected contact deleted
|
||||||
this.setState({
|
this.setState({
|
||||||
|
errorText: '',
|
||||||
|
errorLevel: null,
|
||||||
mobilePanel: 'sidepanel',
|
mobilePanel: 'sidepanel',
|
||||||
showInfoPanel: false,
|
|
||||||
topicSelectedOnline: false,
|
topicSelectedOnline: false,
|
||||||
topicSelectedAcs: null,
|
topicSelectedAcs: null,
|
||||||
infoPanelShowMembers: false
|
infoPanelShowMembers: false
|
||||||
@@ -4082,9 +4101,7 @@
|
|||||||
},
|
},
|
||||||
// User chose a Sign Up menu item.
|
// User chose a Sign Up menu item.
|
||||||
handleNewAccount: function() {
|
handleNewAccount: function() {
|
||||||
var parsed = parseUrlHash(window.location.hash);
|
window.location.hash = setUrlSidePanel(window.location.hash, 'register');
|
||||||
parsed.path[0] = 'register';
|
|
||||||
window.location.hash = composeUrlHash(parsed.path, parsed.params);
|
|
||||||
},
|
},
|
||||||
// Actual registration of a new account.
|
// Actual registration of a new account.
|
||||||
handleNewAccountRequest: function(login_, password_, public_, cred_, tags_) {
|
handleNewAccountRequest: function(login_, password_, public_, cred_, tags_) {
|
||||||
@@ -4127,9 +4144,7 @@
|
|||||||
|
|
||||||
// User chose Settings menu item.
|
// User chose Settings menu item.
|
||||||
handleSettings: function() {
|
handleSettings: function() {
|
||||||
var parsed = parseUrlHash(window.location.hash);
|
window.location.hash = setUrlSidePanel(window.location.hash, this.state.myUserId ? 'edit' : 'settings');
|
||||||
parsed.path[0] = this.state.myUserId ? 'edit' : 'settings';
|
|
||||||
window.location.hash = composeUrlHash(parsed.path, parsed.params);
|
|
||||||
},
|
},
|
||||||
// User updated connection parameters - transport and server address
|
// User updated connection parameters - transport and server address
|
||||||
handleConnectionSettings: function(serverAddress, transport) {
|
handleConnectionSettings: function(serverAddress, transport) {
|
||||||
@@ -4141,7 +4156,7 @@
|
|||||||
// User clicked Cancel button in Setting or Sign Up panel.
|
// User clicked Cancel button in Setting or Sign Up panel.
|
||||||
handleSidepanelCancel: function() {
|
handleSidepanelCancel: function() {
|
||||||
var parsed = parseUrlHash(window.location.hash);
|
var parsed = parseUrlHash(window.location.hash);
|
||||||
parsed.path[0] = '';
|
parsed.path[0] = this.state.myUserId ? 'contacts' : '';
|
||||||
if (parsed.params) {
|
if (parsed.params) {
|
||||||
delete parsed.params.tab;
|
delete parsed.params.tab;
|
||||||
}
|
}
|
||||||
@@ -4150,9 +4165,7 @@
|
|||||||
},
|
},
|
||||||
// User clicked a (+) menu item.
|
// User clicked a (+) menu item.
|
||||||
handleNewTopic: function() {
|
handleNewTopic: function() {
|
||||||
var parsed = parseUrlHash(window.location.hash);
|
window.location.hash = setUrlSidePanel(window.location.hash, 'newtpk');
|
||||||
parsed.path[0] = 'newtpk';
|
|
||||||
window.location.hash = composeUrlHash(parsed.path, parsed.params);
|
|
||||||
},
|
},
|
||||||
// Create of a new topic. New P2P topic requires peer's name.
|
// Create of a new topic. New P2P topic requires peer's name.
|
||||||
handleNewTopicRequest: function(peerName, pub, priv, tags) {
|
handleNewTopicRequest: function(peerName, pub, priv, tags) {
|
||||||
@@ -4223,6 +4236,7 @@
|
|||||||
localStorage.removeItem("auth-token");
|
localStorage.removeItem("auth-token");
|
||||||
this.setState(this.getInitialState());
|
this.setState(this.getInitialState());
|
||||||
this.tnSetup(this.state.serverAddress, this.state.transport);
|
this.tnSetup(this.state.serverAddress, this.state.transport);
|
||||||
|
window.location.hash = "";
|
||||||
},
|
},
|
||||||
|
|
||||||
handleLeaveUnsubRequest: function(topicName) {
|
handleLeaveUnsubRequest: function(topicName) {
|
||||||
@@ -4233,9 +4247,8 @@
|
|||||||
var instance = this;
|
var instance = this;
|
||||||
topic.leave(true).then(function(ctrl) {
|
topic.leave(true).then(function(ctrl) {
|
||||||
// Hide MessagesView and InfoView panels.
|
// Hide MessagesView and InfoView panels.
|
||||||
|
window.location.hash = setUrlTopic(window.location.hash, '');
|
||||||
instance.setState({
|
instance.setState({
|
||||||
topicSelected: '',
|
|
||||||
showInfoPanel: false,
|
|
||||||
infoPanelShowMembers: false
|
infoPanelShowMembers: false
|
||||||
});
|
});
|
||||||
}).catch(function(err) {
|
}).catch(function(err) {
|
||||||
@@ -4290,11 +4303,11 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleShowInfoView: function() {
|
handleShowInfoView: function() {
|
||||||
window.location.hash = addParamToHash(window.location.hash, 'info', true);
|
window.location.hash = addUrlParam(window.location.hash, 'info', true);
|
||||||
this.setState({showInfoPanel: true, infoPanelShowMembers: false});
|
this.setState({showInfoPanel: true, infoPanelShowMembers: false});
|
||||||
},
|
},
|
||||||
handleHideInfoView: function() {
|
handleHideInfoView: function() {
|
||||||
window.location.hash = removeParamFromHash(window.location.hash, 'info');
|
window.location.hash = removeUrlParam(window.location.hash, 'info');
|
||||||
this.setState({showInfoPanel: false, infoPanelShowMembers: false});
|
this.setState({showInfoPanel: false, infoPanelShowMembers: false});
|
||||||
},
|
},
|
||||||
handleMemberUpdateRequest: function(topicName, added, removed) {
|
handleMemberUpdateRequest: function(topicName, added, removed) {
|
||||||
|
|||||||
Reference in New Issue
Block a user