friend/unfriend working

This commit is contained in:
David Kelly 2017-03-31 15:05:21 -07:00
parent 6a4c2c5e12
commit 8ceb6a20f0
2 changed files with 81 additions and 21 deletions

View file

@ -218,7 +218,7 @@ Rectangle {
color: activeTab == "connectionsTab" ? "white" : "#CCCCCC"; color: activeTab == "connectionsTab" ? "white" : "#CCCCCC";
MouseArea { MouseArea {
anchors.fill: parent; anchors.fill: parent;
onClicked: { onClicked: {
if (activeTab != "connectionsTab") { if (activeTab != "connectionsTab") {
connectionsLoading.visible = false; connectionsLoading.visible = false;
connectionsLoading.visible = true; connectionsLoading.visible = true;
@ -309,7 +309,7 @@ Rectangle {
} }
} }
} }
/***************************************** /*****************************************
NEARBY TAB NEARBY TAB
*****************************************/ *****************************************/
@ -663,7 +663,7 @@ Rectangle {
} }
width: parent.width - 12; width: parent.width - 12;
visible: activeTab == "connectionsTab"; visible: activeTab == "connectionsTab";
AnimatedImage { AnimatedImage {
id: connectionsLoading; id: connectionsLoading;
source: "../../icons/profilePicLoading.gif" source: "../../icons/profilePicLoading.gif"
@ -677,8 +677,8 @@ Rectangle {
if (visible) { if (visible) {
connectionsTimeoutTimer.start(); connectionsTimeoutTimer.start();
} else { } else {
connectionsTimeoutTimer.stop(); connectionsTimeoutTimer.stop();
connectionsRefreshProblemText.visible = false; connectionsRefreshProblemText.visible = false;
} }
} }
} }
@ -820,13 +820,12 @@ Rectangle {
checked: model ? (model["connection"] === "friend" ? true : false) : false; checked: model ? (model["connection"] === "friend" ? true : false) : false;
boxSize: 24; boxSize: 24;
onClicked: { onClicked: {
var newValue = !model[styleData.role]; var newValue = !(model["connection"] === "friend");
connectionsUserModel.setProperty(model.userIndex, styleData.role, newValue); connectionsUserModel.setProperty(model.userIndex, styleData.role, newValue);
connectionsUserModelData[model.userIndex][styleData.role] = newValue; // Defensive programming connectionsUserModelData[model.userIndex][styleData.role] = newValue; // Defensive programming
// Insert line here about actually taking the friend/unfriend action pal.sendToScript({method: newValue ? 'addFriend' : 'removeFriend', params: model.userName});
//pal.sendToScript({method: 'addFriend', params: model.userName});
// Also insert line here about logging the activity, similar to the commented line below UserActivityLogger["palAction"](newValue ? styleData.role : "un-" + styleData.role, model.sessionId);
//UserActivityLogger["palAction"](newValue ? styleData.role : "un-" + styleData.role, model.sessionId);
// http://doc.qt.io/qt-5/qtqml-syntax-propertybinding.html#creating-property-bindings-from-javascript // http://doc.qt.io/qt-5/qtqml-syntax-propertybinding.html#creating-property-bindings-from-javascript
// I'm using an explicit binding here because clicking a checkbox breaks the implicit binding as set by // I'm using an explicit binding here because clicking a checkbox breaks the implicit binding as set by
@ -836,7 +835,7 @@ Rectangle {
} }
} }
} }
// "Make a Connection" instructions // "Make a Connection" instructions
Rectangle { Rectangle {
id: connectionInstructions; id: connectionInstructions;
@ -947,7 +946,7 @@ Rectangle {
height: parent.height; height: parent.height;
anchors.top: parent.top; anchors.top: parent.top;
anchors.right: parent.right; anchors.right: parent.right;
RalewayRegular { RalewayRegular {
id: availabilityText; id: availabilityText;
text: "set availability"; text: "set availability";

View file

@ -269,6 +269,38 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
getConnectionData(); getConnectionData();
UserActivityLogger.palAction("refresh_connections", ""); UserActivityLogger.palAction("refresh_connections", "");
break; break;
case 'removeFriend':
friendUserName = message.params;
request({
uri: METAVERSE_BASE + '/api/v1/user/friends/' + friendUserName,
method: 'DELETE'
}, function (error, response) {
print(JSON.stringify(response));
if (error || (response.status !== 'success')) {
print("Error: unable to unfriend", friendUserName, error || response.status);
return;
}
getConnectionData();
});
break
case 'addFriend':
friendUserName = message.params;
request({
uri: METAVERSE_BASE + '/api/v1/user/friends',
method: 'POST',
json: true,
body: {
username: friendUserName,
}
}, function (error, response) {
if (error || (response.status !== 'success')) {
print("Error: unable to friend " + friendUserName, error || response.status);
return;
}
getConnectionData(); // For now, just refresh all connection data. Later, just refresh the one friended row.
}
);
break;
default: default:
print('Unrecognized message from Pal.qml:', JSON.stringify(message)); print('Unrecognized message from Pal.qml:', JSON.stringify(message));
} }
@ -286,10 +318,8 @@ function updateUser(data) {
// //
// These are prototype versions that will be changed when the back end changes. // These are prototype versions that will be changed when the back end changes.
var METAVERSE_BASE = location.metaverseServerUrl; var METAVERSE_BASE = location.metaverseServerUrl;
function request(options, callback) { // cb(error, responseOfCorrectContentType) of url. A subset of npm request.
var httpRequest = new XMLHttpRequest(), key;
function request(url, callback) { // cb(error, responseOfCorrectContentType) of url. General for 'get' text/html/json, but without redirects.
var httpRequest = new XMLHttpRequest();
// QT bug: apparently doesn't handle onload. Workaround using readyState. // QT bug: apparently doesn't handle onload. Workaround using readyState.
httpRequest.onreadystatechange = function () { httpRequest.onreadystatechange = function () {
var READY_STATE_DONE = 4; var READY_STATE_DONE = 4;
@ -298,7 +328,7 @@ function request(url, callback) { // cb(error, responseOfCorrectContentType) of
var error = (httpRequest.status !== HTTP_OK) && httpRequest.status.toString() + ':' + httpRequest.statusText, var error = (httpRequest.status !== HTTP_OK) && httpRequest.status.toString() + ':' + httpRequest.statusText,
response = !error && httpRequest.responseText, response = !error && httpRequest.responseText,
contentType = !error && httpRequest.getResponseHeader('content-type'); contentType = !error && httpRequest.getResponseHeader('content-type');
if (!error && contentType.indexOf('application/json') === 0) { if (!error && contentType.indexOf('application/json') === 0) { // ignoring charset, etc.
try { try {
response = JSON.parse(response); response = JSON.parse(response);
} catch (e) { } catch (e) {
@ -308,11 +338,40 @@ function request(url, callback) { // cb(error, responseOfCorrectContentType) of
callback(error, response); callback(error, response);
} }
}; };
httpRequest.open("GET", url, true); if (typeof options === 'string') {
httpRequest.send(); options = {uri: options};
}
if (options.url) {
options.uri = options.url;
}
if (!options.method) {
options.method = 'GET';
}
if (options.body && (options.method === 'GET')) { // add query parameters
var params = [], appender = (-1 === options.uri.search('?')) ? '?' : '&';
for (key in options.body) {
params.push(key + '=' + options.body[key]);
}
options.uri += appender + params.join('&');
delete options.body;
}
if (options.json) {
options.headers = options.headers || {};
options.headers["Content-type"] = "application/json";
options.body = JSON.stringify(options.body);
}
for (key in options.headers || {}) {
httpRequest.setRequestHeader(key, options.headers[key]);
}
httpRequest.open(options.method, options.uri, true);
httpRequest.send(options.body);
} }
function requestJSON(url, callback) { // callback(data) if successfull. Logs otherwise. function requestJSON(url, callback) { // callback(data) if successfull. Logs otherwise.
request(url, function (error, response) { request({
uri: url
}, function (error, response) {
if (error || (response.status !== 'success')) { if (error || (response.status !== 'success')) {
print("Error: unable to get", url, error || response.status); print("Error: unable to get", url, error || response.status);
return; return;
@ -322,7 +381,9 @@ function requestJSON(url, callback) { // callback(data) if successfull. Logs oth
} }
function getProfilePicture(username, callback) { // callback(url) if successfull. (Logs otherwise) function getProfilePicture(username, callback) { // callback(url) if successfull. (Logs otherwise)
// FIXME Prototype scrapes profile picture. We should include in user status, and also make available somewhere for myself // FIXME Prototype scrapes profile picture. We should include in user status, and also make available somewhere for myself
request(METAVERSE_BASE + '/users/' + username, function (error, html) { request({
uri: METAVERSE_BASE + '/users/' + username
}, function (error, html) {
var matched = !error && html.match(/img class="users-img" src="([^"]*)"/); var matched = !error && html.match(/img class="users-img" src="([^"]*)"/);
if (!matched) { if (!matched) {
print('Error: Unable to get profile picture for', username, error); print('Error: Unable to get profile picture for', username, error);