mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-22 20:15:55 +02:00
basic user story card
This commit is contained in:
parent
e3aae0e93f
commit
747c43d065
4 changed files with 167 additions and 32 deletions
|
@ -47,7 +47,16 @@ Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
function goCard(card) {
|
function goCard(card) {
|
||||||
addressLine.text = card.path;
|
if (useFeed) {
|
||||||
|
storyCard.imageUrl = card.imageUrl; //"http://howard-stearns.github.io/models/images/dancing-avatars.jpg";
|
||||||
|
storyCard.userName = card.userName;
|
||||||
|
storyCard.placeName = card.placeName;
|
||||||
|
storyCard.actionPhrase = card.actionPhrase;
|
||||||
|
storyCard.timePhrase = card.timePhrase;
|
||||||
|
storyCard.visible = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addressLine.text = card.hifiUrl;
|
||||||
toggleOrGo(true);
|
toggleOrGo(true);
|
||||||
}
|
}
|
||||||
property bool useFeed: false;
|
property bool useFeed: false;
|
||||||
|
@ -56,26 +65,6 @@ Window {
|
||||||
property int cardWidth: 200;
|
property int cardWidth: 200;
|
||||||
property int cardHeight: 152;
|
property int cardHeight: 152;
|
||||||
property string metaverseBase: "https://metaverse.highfidelity.com/api/v1/";
|
property string metaverseBase: "https://metaverse.highfidelity.com/api/v1/";
|
||||||
function pastTime(timestamp) { // Answer a descriptive string
|
|
||||||
timestamp = new Date(timestamp);
|
|
||||||
var then = timestamp.getTime(),
|
|
||||||
now = Date.now(),
|
|
||||||
since = now - then,
|
|
||||||
ONE_MINUTE = 1000 * 60,
|
|
||||||
ONE_HOUR = ONE_MINUTE * 60,
|
|
||||||
hours = since / ONE_HOUR,
|
|
||||||
minutes = (hours % 1) * 60;
|
|
||||||
if (hours > 24) {
|
|
||||||
return timestamp.toDateString();
|
|
||||||
}
|
|
||||||
if (hours > 1) {
|
|
||||||
return Math.floor(hours).toString() + ' hr ' + Math.floor(minutes) + ' min ago';
|
|
||||||
}
|
|
||||||
if (minutes >= 2) {
|
|
||||||
return Math.floor(minutes).toString() + ' min ago';
|
|
||||||
}
|
|
||||||
return 'about a minute ago';
|
|
||||||
}
|
|
||||||
|
|
||||||
AddressBarDialog {
|
AddressBarDialog {
|
||||||
id: addressBarDialog
|
id: addressBarDialog
|
||||||
|
@ -88,6 +77,7 @@ Window {
|
||||||
ListModel { id: suggestions }
|
ListModel { id: suggestions }
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
|
id: scroll
|
||||||
width: (3 * cardWidth) + (2 * hifi.layout.spacing);
|
width: (3 * cardWidth) + (2 * hifi.layout.spacing);
|
||||||
height: cardHeight;
|
height: cardHeight;
|
||||||
spacing: hifi.layout.spacing;
|
spacing: hifi.layout.spacing;
|
||||||
|
@ -103,10 +93,14 @@ Window {
|
||||||
width: cardWidth;
|
width: cardWidth;
|
||||||
height: cardHeight;
|
height: cardHeight;
|
||||||
goFunction: goCard;
|
goFunction: goCard;
|
||||||
path: model.place_name + model.path;
|
userName: model.username;
|
||||||
|
placeName: model.place_name;
|
||||||
|
hifiUrl: model.place_name + model.path;
|
||||||
|
imageUrl: model.thumbnail_url; // This is wrong, but it will have to wait.
|
||||||
thumbnail: model.thumbnail_url;
|
thumbnail: model.thumbnail_url;
|
||||||
placeText: model.created_at ? "" : model.place_name;
|
action: model.action;
|
||||||
usersText: model.created_at ? pastTime(model.created_at) : (model.online_users + ((model.online_users === 1) ? ' person' : ' people'));
|
timestamp: model.created_at;
|
||||||
|
onlineUsers: model.online_users;
|
||||||
hoverThunk: function () { ListView.view.currentIndex = index; }
|
hoverThunk: function () { ListView.view.currentIndex = index; }
|
||||||
unhoverThunk: function () { ListView.view.currentIndex = -1; }
|
unhoverThunk: function () { ListView.view.currentIndex = -1; }
|
||||||
}
|
}
|
||||||
|
@ -209,8 +203,24 @@ Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UserStoryCard {
|
||||||
|
id: storyCard;
|
||||||
|
visible: false;
|
||||||
|
visitPlace: function (hifiUrl) {
|
||||||
|
storyCard.visible = false;
|
||||||
|
addressLine.text = hifiUrl;
|
||||||
|
toggleOrGo(true);
|
||||||
|
};
|
||||||
|
anchors {
|
||||||
|
verticalCenter: scroll.verticalCenter;
|
||||||
|
horizontalCenter: scroll.horizontalCenter;
|
||||||
|
verticalCenterOffset: 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function toggleFeed () {
|
function toggleFeed () {
|
||||||
useFeed = !useFeed;
|
useFeed = !useFeed;
|
||||||
placesButton.buttonState = useFeed ? 0 : 1;
|
placesButton.buttonState = useFeed ? 0 : 1;
|
||||||
|
@ -318,13 +328,15 @@ Window {
|
||||||
description = data.description || "";
|
description = data.description || "";
|
||||||
return {
|
return {
|
||||||
place_name: name,
|
place_name: name,
|
||||||
|
username: data.username || "",
|
||||||
path: data.path || "",
|
path: data.path || "",
|
||||||
created_at: data.created_at || "",
|
created_at: data.created_at || "",
|
||||||
|
action: data.action || "",
|
||||||
thumbnail_url: data.thumbnail_url || "",
|
thumbnail_url: data.thumbnail_url || "",
|
||||||
|
|
||||||
tags: tags,
|
tags: tags,
|
||||||
description: description,
|
description: description,
|
||||||
online_users: data.online_users,
|
online_users: data.online_users || 0,
|
||||||
|
|
||||||
searchText: [name].concat(tags, description).join(' ').toUpperCase()
|
searchText: [name].concat(tags, description).join(' ').toUpperCase()
|
||||||
}
|
}
|
||||||
|
@ -402,7 +414,6 @@ Window {
|
||||||
{created_at: "8/3/2016", action: "snapshot", path: "/10077.4,4003.6,9972.56/0,-0.410351,0,0.911928", place_name: "Ventura", thumbnail_url:"https://hifi-metaverse.s3-us-west-1.amazonaws.com/images/places/previews/1f5/e6b/00-/thumbnail/hifi-place-1f5e6b00-2bf0-4319-b9ae-a2344a72354c.png?1454321596"}
|
{created_at: "8/3/2016", action: "snapshot", path: "/10077.4,4003.6,9972.56/0,-0.410351,0,0.911928", place_name: "Ventura", thumbnail_url:"https://hifi-metaverse.s3-us-west-1.amazonaws.com/images/places/previews/1f5/e6b/00-/thumbnail/hifi-place-1f5e6b00-2bf0-4319-b9ae-a2344a72354c.png?1454321596"}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
var stories = data.user_stories.map(function (story) { // explicit single-argument function
|
var stories = data.user_stories.map(function (story) { // explicit single-argument function
|
||||||
return makeModelData(story);
|
return makeModelData(story);
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,6 +21,8 @@ Original.Button {
|
||||||
width: 120
|
width: 120
|
||||||
height: hifi.dimensions.controlLineHeight
|
height: hifi.dimensions.controlLineHeight
|
||||||
|
|
||||||
|
HifiConstants { id: hifi }
|
||||||
|
|
||||||
style: ButtonStyle {
|
style: ButtonStyle {
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
|
|
|
@ -17,17 +17,54 @@ import QtGraphicalEffects 1.0
|
||||||
import "../styles-uit"
|
import "../styles-uit"
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
property string userName: "";
|
||||||
|
property string placeName: "";
|
||||||
|
property string action: "";
|
||||||
|
property string timestamp: "";
|
||||||
|
property string hifiUrl: "";
|
||||||
|
property string thumbnail: defaultThumbnail;
|
||||||
|
property string imageUrl: "";
|
||||||
property var goFunction: null;
|
property var goFunction: null;
|
||||||
property alias image: lobby;
|
|
||||||
property alias placeText: place.text;
|
property string timePhrase: pastTime(timestamp);
|
||||||
property alias usersText: users.text;
|
property string actionPhrase: makeActionPhrase(action);
|
||||||
|
property int onlineUsers: 0;
|
||||||
|
property bool isUserStory: userName && !onlineUsers;
|
||||||
|
|
||||||
property int textPadding: 20;
|
property int textPadding: 20;
|
||||||
property int textSize: 24;
|
property int textSize: 24;
|
||||||
property int textSizeSmall: 18;
|
property int textSizeSmall: 18;
|
||||||
property string defaultThumbnail: Qt.resolvedUrl("../../images/default-domain.gif");
|
property string defaultThumbnail: Qt.resolvedUrl("../../images/default-domain.gif");
|
||||||
property string thumbnail: defaultThumbnail;
|
|
||||||
property string path: "";
|
|
||||||
HifiConstants { id: hifi }
|
HifiConstants { id: hifi }
|
||||||
|
function pastTime(timestamp) { // Answer a descriptive string
|
||||||
|
timestamp = new Date(timestamp);
|
||||||
|
var then = timestamp.getTime(),
|
||||||
|
now = Date.now(),
|
||||||
|
since = now - then,
|
||||||
|
ONE_MINUTE = 1000 * 60,
|
||||||
|
ONE_HOUR = ONE_MINUTE * 60,
|
||||||
|
hours = since / ONE_HOUR,
|
||||||
|
minutes = (hours % 1) * 60;
|
||||||
|
if (hours > 24) {
|
||||||
|
return timestamp.toDateString();
|
||||||
|
}
|
||||||
|
if (hours > 1) {
|
||||||
|
return Math.floor(hours).toString() + ' hr ' + Math.floor(minutes) + ' min ago';
|
||||||
|
}
|
||||||
|
if (minutes >= 2) {
|
||||||
|
return Math.floor(minutes).toString() + ' min ago';
|
||||||
|
}
|
||||||
|
return 'about a minute ago';
|
||||||
|
}
|
||||||
|
function makeActionPhrase(actionLabel) {
|
||||||
|
switch (actionLabel) {
|
||||||
|
case "snapshot":
|
||||||
|
return "took a snapshot";
|
||||||
|
default:
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: lobby;
|
id: lobby;
|
||||||
width: parent.width;
|
width: parent.width;
|
||||||
|
@ -39,7 +76,7 @@ Rectangle {
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
onStatusChanged: {
|
onStatusChanged: {
|
||||||
if (status == Image.Error) {
|
if (status == Image.Error) {
|
||||||
console.log("source: " + source + ": failed to load " + path);
|
console.log("source: " + source + ": failed to load " + hfiUrl);
|
||||||
source = defaultThumbnail;
|
source = defaultThumbnail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,6 +108,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
RalewaySemiBold {
|
RalewaySemiBold {
|
||||||
id: place;
|
id: place;
|
||||||
|
text: isUserStory ? "" : placeName;
|
||||||
color: hifi.colors.white;
|
color: hifi.colors.white;
|
||||||
size: textSize;
|
size: textSize;
|
||||||
anchors {
|
anchors {
|
||||||
|
@ -81,6 +119,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
RalewayRegular {
|
RalewayRegular {
|
||||||
id: users;
|
id: users;
|
||||||
|
text: isUserStory ? timePhrase : (onlineUsers + ((onlineUsers === 1) ? ' person' : ' people'));
|
||||||
size: textSizeSmall;
|
size: textSizeSmall;
|
||||||
color: hifi.colors.white;
|
color: hifi.colors.white;
|
||||||
anchors {
|
anchors {
|
||||||
|
|
83
interface/resources/qml/hifi/UserStoryCard.qml
Normal file
83
interface/resources/qml/hifi/UserStoryCard.qml
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
//
|
||||||
|
// UserStoryCard.qml
|
||||||
|
// qml/hifi
|
||||||
|
//
|
||||||
|
// Displays a clickable card representing a user story or destination.
|
||||||
|
//
|
||||||
|
// Created by Howard Stearns on 8/11/2016
|
||||||
|
// Copyright 2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
import Hifi 1.0
|
||||||
|
import QtQuick 2.5
|
||||||
|
import "../styles-uit" as HifiStyles
|
||||||
|
import "../controls-uit" as HifiControls
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: storyCard;
|
||||||
|
width: 500;
|
||||||
|
height: 330;
|
||||||
|
property string userName: "User";
|
||||||
|
property string placeName: "Home";
|
||||||
|
property string actionPhrase: "did something";
|
||||||
|
property string timePhrase: "";
|
||||||
|
property string hifiUrl: storyCard.placeName;
|
||||||
|
property string imageUrl: Qt.resolvedUrl("../images/default-domain.gif");
|
||||||
|
property var visitPlace: function (ignore) { };
|
||||||
|
color: "white";
|
||||||
|
HifiStyles.HifiConstants { id: otherHifi }
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent;
|
||||||
|
acceptedButtons: Qt.LeftButton;
|
||||||
|
onClicked: storyCard.visible = false;
|
||||||
|
hoverEnabled: true;
|
||||||
|
// The content of the storyCard has buttons. For these to work without being
|
||||||
|
// blanketed by the MouseArea, they need to be children of the MouseArea.
|
||||||
|
Image {
|
||||||
|
id: storyImage;
|
||||||
|
source: storyCard.imageUrl;
|
||||||
|
width: storyCard.width - 100;
|
||||||
|
height: storyImage.width / 1.91;
|
||||||
|
fillMode: Image.PreserveAspectCrop;
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter;
|
||||||
|
top: parent.top;
|
||||||
|
topMargin: 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HifiStyles.RalewayRegular {
|
||||||
|
id: storyLabel;
|
||||||
|
text: storyCard.userName + " " + storyCard.actionPhrase + " in " + storyCard.placeName
|
||||||
|
size: 20;
|
||||||
|
color: "black"
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: storyImage.horizontalCenter;
|
||||||
|
top: storyImage.bottom;
|
||||||
|
topMargin: hifi.layout.spacing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HifiStyles.RalewayRegular {
|
||||||
|
text: storyCard.timePhrase;
|
||||||
|
size: 15;
|
||||||
|
color: "slategrey"
|
||||||
|
anchors {
|
||||||
|
verticalCenter: visitButton.verticalCenter;
|
||||||
|
left: storyImage.left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HifiControls.Button {
|
||||||
|
id: visitButton;
|
||||||
|
text: "visit " + storyCard.placeName;
|
||||||
|
color: otherHifi.buttons.blue;
|
||||||
|
onClicked: visitPlace(storyCard.hifiUrl);
|
||||||
|
anchors {
|
||||||
|
top: storyLabel.bottom;
|
||||||
|
topMargin: hifi.layout.spacing;
|
||||||
|
right: storyImage.right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue