diff --git a/interface/resources/qml/hifi/NameCard.qml b/interface/resources/qml/hifi/NameCard.qml
index 86cc0218a4..3343cec26f 100644
--- a/interface/resources/qml/hifi/NameCard.qml
+++ b/interface/resources/qml/hifi/NameCard.qml
@@ -14,6 +14,7 @@ import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtGraphicalEffects 1.0
import "../styles-uit"
+import "../controls-uit" as HifiControls
import "toolbars"
// references Users, UserActivityLogger, MyAvatar, Vec3, Quat, AddressManager from root context
@@ -42,8 +43,9 @@ Item {
property bool selected: false
property bool isAdmin: false
property bool isPresent: true
+ property string placeName: ""
property string profilePicBorderColor: (connectionStatus == "connection" ? hifi.colors.indigoAccent : (connectionStatus == "friend" ? hifi.colors.greenHighlight : "transparent"))
-
+ property alias avImage: avatarImage
Item {
id: avatarImage
visible: profileUrl !== "" && userName !== "";
@@ -79,25 +81,6 @@ Item {
anchors.fill: parent;
visible: userImage.status != Image.Ready;
}
- StateImage {
- id: infoHoverImage;
- visible: false;
- imageURL: "../../images/info-icon-2-state.svg";
- size: 32;
- buttonState: 1;
- anchors.centerIn: parent;
- }
- MouseArea {
- anchors.fill: parent
- enabled: selected || isMyCard;
- hoverEnabled: enabled
- onClicked: {
- userInfoViewer.url = defaultBaseUrl + "/users/" + userName;
- userInfoViewer.visible = true;
- }
- onEntered: infoHoverImage.visible = true;
- onExited: infoHoverImage.visible = false;
- }
}
// Colored border around avatarImage
@@ -316,9 +299,10 @@ Item {
visible: thisNameCard.userName !== "";
// Size
width: parent.width
- height: pal.activeTab == "nearbyTab" || isMyCard ? usernameTextPixelSize + 4 : parent.height;
+ height: usernameTextPixelSize + 4
// Anchors
- anchors.top: isMyCard ? myDisplayName.bottom : (pal.activeTab == "nearbyTab" ? displayNameContainer.bottom : parent.top);
+ anchors.top: isMyCard ? myDisplayName.bottom : pal.activeTab == "nearbyTab" ? displayNameContainer.bottom : undefined //(parent.height - displayNameTextPixelSize/2));
+ anchors.verticalCenter: pal.activeTab == "connectionsTab" ? avatarImage.verticalCenter : undefined
anchors.left: avatarImage.right;
anchors.leftMargin: avatarImage.visible ? 5 : 0;
anchors.rightMargin: 5;
@@ -346,6 +330,92 @@ Item {
}
}
}
+ StateImage {
+ id: nameCardConnectionInfoImage
+ visible: selected && !isMyCard && pal.activeTab == "connectionsTab"
+ imageURL: "../../images/info-icon-2-state.svg" // PLACEHOLDER!!!
+ size: 32;
+ buttonState: 0;
+ anchors.left: avatarImage.right
+ anchors.bottom: parent.bottom
+ }
+ MouseArea {
+ anchors.fill:nameCardConnectionInfoImage
+ enabled: selected
+ hoverEnabled: true
+ onClicked: {
+ userInfoViewer.url = defaultBaseUrl + "/users/" + userName;
+ userInfoViewer.visible = true;
+ }
+ onEntered: {
+ nameCardConnectionInfoImage.buttonState = 1;
+ }
+ onExited: {
+ nameCardConnectionInfoImage.buttonState = 0;
+ }
+ }
+ FiraSansRegular {
+ id: nameCardConnectionInfoText
+ visible: selected && !isMyCard && pal.activeTab == "connectionsTab" && !isMyCard
+ width: parent.width
+ height: displayNameTextPixelSize
+ size: displayNameTextPixelSize - 4
+ anchors.left: nameCardConnectionInfoImage.right
+ anchors.verticalCenter: nameCardConnectionInfoImage.verticalCenter
+ anchors.leftMargin: 5
+ verticalAlignment: Text.AlignVCenter
+ text: "Info"
+ color: hifi.colors.baseGray
+ }
+ HiFiGlyphs {
+ id: nameCardRemoveConnectionImage
+ visible: selected && !isMyCard && pal.activeTab == "connectionsTab"
+ text: hifi.glyphs.close
+ size: 28;
+ x: 120
+ anchors.verticalCenter: nameCardConnectionInfoImage.verticalCenter
+ }
+ MouseArea {
+ anchors.fill:nameCardRemoveConnectionImage
+ enabled: selected
+ hoverEnabled: true
+ onClicked: {
+ // send message to pal.js to forgetConnection
+ pal.sendToScript({method: 'removeConnection', params: thisNameCard.userName});
+ }
+ onEntered: {
+ nameCardRemoveConnectionImage.text = hifi.glyphs.closeInverted;
+ }
+ onExited: {
+ nameCardRemoveConnectionImage.text = hifi.glyphs.close;
+ }
+ }
+ FiraSansRegular {
+ id: nameCardRemoveConnectionText
+ visible: selected && !isMyCard && pal.activeTab == "connectionsTab" && !isMyCard
+ width: parent.width
+ height: displayNameTextPixelSize
+ size: displayNameTextPixelSize - 4
+ anchors.left: nameCardRemoveConnectionImage.right
+ anchors.verticalCenter: nameCardRemoveConnectionImage.verticalCenter
+ anchors.leftMargin: 5
+ verticalAlignment: Text.AlignVCenter
+ text: "Forget"
+ color: hifi.colors.baseGray
+ }
+ HifiControls.Button {
+ id: visitConnectionButton
+ visible: selected && !isMyCard && pal.activeTab == "connectionsTab" && !isMyCard
+ text: "Visit"
+ enabled: thisNameCard.placeName !== ""
+ anchors.verticalCenter: nameCardRemoveConnectionImage.verticalCenter
+ x: 240
+ onClicked: {
+ AddressManager.goToUser(thisNameCard.userName);
+ UserActivityLogger.palAction("go_to_user", thisNameCard.userName);
+ }
+ }
+
// VU Meter
Rectangle {
id: nameCardVUMeter
@@ -484,7 +554,7 @@ Item {
}
}
}
-
+
function updateGainFromQML(avatarUuid, sliderValue, isReleased) {
Users.setAvatarGain(avatarUuid, sliderValue);
if (isReleased) {
diff --git a/interface/resources/qml/hifi/Pal.qml b/interface/resources/qml/hifi/Pal.qml
index 50fba660d8..d627fb54f9 100644
--- a/interface/resources/qml/hifi/Pal.qml
+++ b/interface/resources/qml/hifi/Pal.qml
@@ -770,7 +770,7 @@ Rectangle {
// This Rectangle refers to each Row in the connectionsTable.
rowDelegate: Rectangle {
// Size
- height: rowHeight;
+ height: rowHeight + (styleData.selected ? 15 : 0);
color: rowColor(styleData.selected, styleData.alternate);
}
@@ -786,6 +786,7 @@ Rectangle {
profileUrl: (model && model.profileUrl) || "";
displayName: "";
userName: model ? model.userName : "";
+ placeName: model ? model.placeName : ""
connectionStatus : model ? model.connection : "";
selected: styleData.selected;
// Size
@@ -804,12 +805,16 @@ Rectangle {
elide: Text.ElideRight;
// Size
width: parent.width;
- // Anchors
- anchors.fill: parent;
+ // you would think that this would work:
+ // anchors.verticalCenter: connectionsNameCard.avImage.verticalCenter
+ // but no! you cannot anchor to a non-sibling or parent. So I will
+ // align with the friends checkbox, where I did the manual alignment
+ anchors.verticalCenter: friendsCheckBox.verticalCenter
// Text Size
size: 16;
// Text Positioning
verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
// Style
color: hifi.colors.blueAccent;
font.underline: true;
@@ -829,8 +834,12 @@ Rectangle {
// "Friends" checkbox
HifiControlsUit.CheckBox {
id: friendsCheckBox;
- visible: styleData.role === "friends" && model.userName !== myData.userName;
- anchors.centerIn: parent;
+ visible: styleData.role === "friends" && model && model.userName !== myData.userName;
+ // you would think that this would work:
+ // anchors.verticalCenter: connectionsNameCard.avImage.verticalCenter
+ // but no! you cannot anchor to a non-sibling or parent. So:
+ x: parent.width/2 - boxSize/2
+ y: connectionsNameCard.avImage.y + connectionsNameCard.avImage.height/2 - boxSize/2
checked: model ? (model["connection"] === "friend" ? true : false) : false;
boxSize: 24;
onClicked: {
@@ -908,7 +917,7 @@ Rectangle {
wrapMode: Text.WordWrap
textFormat: Text.StyledText;
// Text
- text: HMD.active ?
+ text: HMD.isMounted ?
"When you meet someone you want to remember later, you can connect with a handshake:
" +
"1. Put your hand out onto their hand and squeeze your controller's grip button on its side.
" +
"2. Once the other person puts their hand onto yours, you'll see your connection form.
" +
@@ -967,7 +976,6 @@ Rectangle {
// Text size
size: hifi.fontSizes.tabularData;
// Anchors
- anchors.top: myCard.top;
anchors.left: parent.left;
// Style
color: hifi.colors.baseGrayHighlight;
diff --git a/scripts/system/pal.js b/scripts/system/pal.js
index b39c993894..5fbea90025 100644
--- a/scripts/system/pal.js
+++ b/scripts/system/pal.js
@@ -269,13 +269,26 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
getConnectionData();
UserActivityLogger.palAction("refresh_connections", "");
break;
+ case 'removeConnection':
+ connectionUserName = message.params;
+ request({
+ uri: METAVERSE_BASE + '/api/v1/user/connections/' + connectionUserName,
+ method: 'DELETE'
+ }, function (error, response) {
+ if (error || (response.status !== 'success')) {
+ print("Error: unable to remove connection", connectionUserName, error || response.status);
+ return;
+ }
+ getConnectionData();
+ });
+ 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;