mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 11:45:36 +02:00
use html card from user_story id, and close things when
receiveHifiSchemeUrl
This commit is contained in:
parent
e75f950ac7
commit
d58cc8ddd9
3 changed files with 541 additions and 4 deletions
|
@ -15,6 +15,7 @@ import "styles"
|
|||
import "windows"
|
||||
import "hifi"
|
||||
import "hifi/toolbars"
|
||||
import "controls-uit" as HifiControls
|
||||
|
||||
Window {
|
||||
id: root
|
||||
|
@ -46,15 +47,21 @@ Window {
|
|||
anchors.centerIn = parent;
|
||||
}
|
||||
|
||||
function resetAfterTeleport() {
|
||||
console.log('hrs fixme got reset')
|
||||
storyCardFrame.shown = root.shown = false;
|
||||
}
|
||||
function goCard(card) {
|
||||
if (addressBarDialog.useFeed) {
|
||||
storyCard.imageUrl = card.imageUrl;
|
||||
/*storyCard.imageUrl = card.imageUrl; // hrs fixme
|
||||
storyCard.userName = card.userName;
|
||||
storyCard.placeName = card.placeName;
|
||||
storyCard.actionPhrase = card.actionPhrase;
|
||||
storyCard.timePhrase = card.timePhrase;
|
||||
storyCard.hifiUrl = card.hifiUrl;
|
||||
storyCard.visible = true;
|
||||
storyCard.visible = true;*/
|
||||
storyCard.url = metaverseBase + "user_stories/" + card.storyId + ".html";
|
||||
storyCardFrame.shown = true;
|
||||
return;
|
||||
}
|
||||
addressLine.text = card.hifiUrl;
|
||||
|
@ -74,6 +81,7 @@ Window {
|
|||
onBackEnabledChanged: backArrow.buttonState = addressBarDialog.backEnabled ? 1 : 0;
|
||||
onForwardEnabledChanged: forwardArrow.buttonState = addressBarDialog.forwardEnabled ? 1 : 0;
|
||||
onUseFeedChanged: { updateFeedState(); }
|
||||
onReceivedHifiSchemeURL: { console.log('hrs status change'); console.log('hrs status got', url); resetAfterTeleport(); }
|
||||
|
||||
ListModel { id: suggestions }
|
||||
|
||||
|
@ -102,6 +110,7 @@ Window {
|
|||
action: model.action;
|
||||
timestamp: model.created_at;
|
||||
onlineUsers: model.online_users;
|
||||
storyId: model.metaverseId;
|
||||
hoverThunk: function () { ListView.view.currentIndex = index; }
|
||||
unhoverThunk: function () { ListView.view.currentIndex = -1; }
|
||||
}
|
||||
|
@ -114,6 +123,7 @@ Window {
|
|||
Image { // Just a visual indicator that the user can swipe the cards over to see more.
|
||||
source: "../images/Swipe-Icon-single.svg"
|
||||
width: 50;
|
||||
visible: suggestions.count > 3;
|
||||
anchors {
|
||||
right: scroll.right;
|
||||
verticalCenter: scroll.verticalCenter;
|
||||
|
@ -214,14 +224,27 @@ Window {
|
|||
}
|
||||
}
|
||||
|
||||
UserStoryCard {
|
||||
/*UserStoryCard { // hrs fixme remove
|
||||
id: storyCard;
|
||||
visible: false;
|
||||
visitPlace: function (hifiUrl) {
|
||||
storyCard.visible = false;
|
||||
addressLine.text = hifiUrl;
|
||||
toggleOrGo(true);
|
||||
};
|
||||
};*/
|
||||
Window {
|
||||
width: 750;
|
||||
height: 360;
|
||||
HifiControls.WebView {
|
||||
anchors.fill: parent;
|
||||
id: storyCard;
|
||||
}
|
||||
id: storyCardFrame;
|
||||
|
||||
shown: false;
|
||||
destroyOnCloseButton: false;
|
||||
pinnable: false;
|
||||
|
||||
anchors {
|
||||
verticalCenter: scroll.verticalCenter;
|
||||
horizontalCenter: scroll.horizontalCenter;
|
||||
|
@ -348,6 +371,7 @@ Window {
|
|||
console.log(name, "has bad details", data.details);
|
||||
}
|
||||
}
|
||||
console.log('hrs fixme id', data.id, typeof data.id, JSON.stringify(data));
|
||||
return {
|
||||
place_name: name,
|
||||
username: data.username || "",
|
||||
|
@ -357,6 +381,8 @@ Window {
|
|||
thumbnail_url: thumbnail_url,
|
||||
image_url: image_url,
|
||||
|
||||
metaverseId: (data.id || "").toString(), // Some are strings from server while others are numbers. Model objects require uniformity.
|
||||
|
||||
tags: tags,
|
||||
description: description,
|
||||
online_users: data.online_users || 0,
|
||||
|
|
510
interface/resources/qml/AddressBarDialog.qml~
Normal file
510
interface/resources/qml/AddressBarDialog.qml~
Normal file
|
@ -0,0 +1,510 @@
|
|||
//
|
||||
// AddressBarDialog.qml
|
||||
//
|
||||
// Created by Austin Davis on 2015/04/14
|
||||
// Copyright 2015 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.4
|
||||
import "controls"
|
||||
import "styles"
|
||||
import "windows"
|
||||
import "hifi"
|
||||
import "hifi/toolbars"
|
||||
|
||||
Window {
|
||||
id: root
|
||||
HifiConstants { id: hifi }
|
||||
|
||||
objectName: "AddressBarDialog"
|
||||
frame: HiddenFrame {}
|
||||
hideBackground: true
|
||||
|
||||
shown: false
|
||||
destroyOnHidden: false
|
||||
resizable: false
|
||||
scale: 1.25 // Make this dialog a little larger than normal
|
||||
|
||||
width: addressBarDialog.implicitWidth
|
||||
height: addressBarDialog.implicitHeight
|
||||
|
||||
onShownChanged: addressBarDialog.observeShownChanged(shown);
|
||||
Component.onCompleted: {
|
||||
root.parentChanged.connect(center);
|
||||
center();
|
||||
}
|
||||
Component.onDestruction: {
|
||||
root.parentChanged.disconnect(center);
|
||||
}
|
||||
|
||||
function center() {
|
||||
// Explicitly center in order to avoid warnings at shutdown
|
||||
anchors.centerIn = parent;
|
||||
}
|
||||
|
||||
function goCard(card) {
|
||||
if (addressBarDialog.useFeed) {
|
||||
storyCard.imageUrl = card.imageUrl;
|
||||
storyCard.userName = card.userName;
|
||||
storyCard.placeName = card.placeName;
|
||||
storyCard.actionPhrase = card.actionPhrase;
|
||||
storyCard.timePhrase = card.timePhrase;
|
||||
storyCard.hifiUrl = card.hifiUrl;
|
||||
storyCard.visible = true;
|
||||
return;
|
||||
}
|
||||
addressLine.text = card.hifiUrl;
|
||||
toggleOrGo(true);
|
||||
}
|
||||
property var allPlaces: [];
|
||||
property var allStories: [];
|
||||
property int cardWidth: 200;
|
||||
property int cardHeight: 152;
|
||||
//property string metaverseBase: "https://metaverse.highfidelity.com/api/v1/";
|
||||
property string metaverseBase: "http://10.0.0.242:3000/api/v1/";
|
||||
|
||||
AddressBarDialog {
|
||||
id: addressBarDialog
|
||||
implicitWidth: backgroundImage.width
|
||||
implicitHeight: backgroundImage.height
|
||||
// The buttons have their button state changed on hover, so we have to manually fix them up here
|
||||
onBackEnabledChanged: backArrow.buttonState = addressBarDialog.backEnabled ? 1 : 0;
|
||||
onForwardEnabledChanged: forwardArrow.buttonState = addressBarDialog.forwardEnabled ? 1 : 0;
|
||||
onUseFeedChanged: { updateFeedState(); }
|
||||
|
||||
ListModel { id: suggestions }
|
||||
|
||||
ListView {
|
||||
id: scroll
|
||||
width: backgroundImage.width;
|
||||
height: cardHeight;
|
||||
spacing: hifi.layout.spacing;
|
||||
clip: true;
|
||||
anchors {
|
||||
bottom: backgroundImage.top;
|
||||
bottomMargin: 2 * hifi.layout.spacing;
|
||||
horizontalCenter: backgroundImage.horizontalCenter
|
||||
}
|
||||
model: suggestions;
|
||||
orientation: ListView.Horizontal;
|
||||
delegate: Card {
|
||||
width: cardWidth;
|
||||
height: cardHeight;
|
||||
goFunction: goCard;
|
||||
userName: model.username;
|
||||
placeName: model.place_name;
|
||||
hifiUrl: model.place_name + model.path;
|
||||
imageUrl: model.image_url;
|
||||
thumbnail: model.thumbnail_url;
|
||||
action: model.action;
|
||||
timestamp: model.created_at;
|
||||
onlineUsers: model.online_users;
|
||||
hoverThunk: function () { ListView.view.currentIndex = index; }
|
||||
unhoverThunk: function () { ListView.view.currentIndex = -1; }
|
||||
}
|
||||
highlightMoveDuration: -1;
|
||||
highlightMoveVelocity: -1;
|
||||
highlight: Rectangle { color: "transparent"; border.width: 4; border.color: "#1DB5ED"; z: 1; }
|
||||
leftMargin: 50; // Start the first item over be about the same amount as the last item peeks through on the other side.
|
||||
rightMargin: 50;
|
||||
}
|
||||
Image { // Just a visual indicator that the user can swipe the cards over to see more.
|
||||
source: "../images/Swipe-Icon-single.svg"
|
||||
width: 50;
|
||||
anchors {
|
||||
right: scroll.right;
|
||||
verticalCenter: scroll.verticalCenter;
|
||||
}
|
||||
}
|
||||
Image {
|
||||
id: backgroundImage
|
||||
source: "../images/address-bar.svg"
|
||||
width: 576 * root.scale
|
||||
height: 80 * root.scale
|
||||
property int inputAreaHeight: 56.0 * root.scale // Height of the background's input area
|
||||
property int inputAreaStep: (height - inputAreaHeight) / 2
|
||||
|
||||
ToolbarButton {
|
||||
id: homeButton
|
||||
imageURL: "../images/home.svg"
|
||||
buttonState: 1
|
||||
defaultState: 1
|
||||
hoverState: 2
|
||||
onClicked: addressBarDialog.loadHome();
|
||||
anchors {
|
||||
left: parent.left
|
||||
leftMargin: homeButton.width / 2
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
ToolbarButton {
|
||||
id: backArrow;
|
||||
imageURL: "../images/backward.svg";
|
||||
hoverState: addressBarDialog.backEnabled ? 2 : 0;
|
||||
defaultState: addressBarDialog.backEnabled ? 1 : 0;
|
||||
buttonState: addressBarDialog.backEnabled ? 1 : 0;
|
||||
onClicked: addressBarDialog.loadBack();
|
||||
anchors {
|
||||
left: homeButton.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
ToolbarButton {
|
||||
id: forwardArrow;
|
||||
imageURL: "../images/forward.svg";
|
||||
hoverState: addressBarDialog.forwardEnabled ? 2 : 0;
|
||||
defaultState: addressBarDialog.forwardEnabled ? 1 : 0;
|
||||
buttonState: addressBarDialog.forwardEnabled ? 1 : 0;
|
||||
onClicked: addressBarDialog.loadForward();
|
||||
anchors {
|
||||
left: backArrow.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME replace with TextField
|
||||
TextInput {
|
||||
id: addressLine
|
||||
focus: true
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
left: forwardArrow.right
|
||||
right: placesButton.left
|
||||
leftMargin: forwardArrow.width
|
||||
rightMargin: placesButton.width
|
||||
topMargin: parent.inputAreaStep + hifi.layout.spacing
|
||||
bottomMargin: parent.inputAreaStep + hifi.layout.spacing
|
||||
}
|
||||
font.pixelSize: hifi.fonts.pixelSize * root.scale * 0.75
|
||||
helperText: "Go to: place, @user, /path, network address"
|
||||
helperPixelSize: font.pixelSize * 0.75
|
||||
helperItalic: true
|
||||
onTextChanged: filterChoicesByText()
|
||||
}
|
||||
// These two are radio buttons.
|
||||
ToolbarButton {
|
||||
id: placesButton
|
||||
imageURL: "../images/places.svg"
|
||||
buttonState: 1
|
||||
defaultState: addressBarDialog.useFeed ? 0 : 1;
|
||||
hoverState: addressBarDialog.useFeed ? 2 : -1;
|
||||
onClicked: addressBarDialog.useFeed ? toggleFeed() : identity()
|
||||
anchors {
|
||||
right: feedButton.left;
|
||||
bottom: addressLine.bottom;
|
||||
}
|
||||
}
|
||||
ToolbarButton {
|
||||
id: feedButton;
|
||||
imageURL: "../images/snap-feed.svg";
|
||||
buttonState: 0
|
||||
defaultState: addressBarDialog.useFeed ? 1 : 0;
|
||||
hoverState: addressBarDialog.useFeed ? -1 : 2;
|
||||
onClicked: addressBarDialog.useFeed ? identity() : toggleFeed();
|
||||
anchors {
|
||||
right: parent.right;
|
||||
bottom: addressLine.bottom;
|
||||
rightMargin: feedButton.width / 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
addressBarDialog.useFeed = !addressBarDialog.useFeed;
|
||||
updateFeedState();
|
||||
}
|
||||
function updateFeedState() {
|
||||
placesButton.buttonState = addressBarDialog.useFeed ? 0 : 1;
|
||||
feedButton.buttonState = addressBarDialog.useFeed ? 1 : 0;
|
||||
filterChoicesByText();
|
||||
}
|
||||
function getRequest(url, cb) { // cb(error, responseOfCorrectContentType) of url. General for 'get' text/html/json, but without redirects.
|
||||
// TODO: make available to other .qml.
|
||||
var request = new XMLHttpRequest();
|
||||
// QT bug: apparently doesn't handle onload. Workaround using readyState.
|
||||
request.onreadystatechange = function () {
|
||||
var READY_STATE_DONE = 4;
|
||||
var HTTP_OK = 200;
|
||||
if (request.readyState >= READY_STATE_DONE) {
|
||||
var error = (request.status !== HTTP_OK) && request.status.toString() + ':' + request.statusText,
|
||||
response = !error && request.responseText,
|
||||
contentType = !error && request.getResponseHeader('content-type');
|
||||
if (!error && contentType.indexOf('application/json') === 0) {
|
||||
try {
|
||||
response = JSON.parse(response);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
}
|
||||
cb(error, response);
|
||||
}
|
||||
};
|
||||
request.open("GET", url, true);
|
||||
request.send();
|
||||
}
|
||||
function asyncMap(array, iterator, cb) {
|
||||
// call iterator(element, icb) once for each element of array, and then cb(error, mappedResult)
|
||||
// when icb(error, mappedElement) has been called by each iterator.
|
||||
// Calls to iterator are overlapped and map call icb in any order, but the mappedResults are collected in the same
|
||||
// order as the elements of the array.
|
||||
// short-circuits if error. Note that iterator MUST be an asynchronous function. (Use setTimeout if necessary.)
|
||||
var count = array.length, results = [];
|
||||
if (!count) {
|
||||
return cb(null, results);
|
||||
}
|
||||
array.forEach(function (element, index) {
|
||||
if (count < 0) { // don't keep iterating after we short-circuit
|
||||
return;
|
||||
}
|
||||
iterator(element, function (error, mapped) {
|
||||
results[index] = mapped;
|
||||
if (error || !--count) {
|
||||
count = 1; // don't cb multiple times if error
|
||||
cb(error, results);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
// Example:
|
||||
/*asyncMap([0, 1, 2, 3, 4, 5, 6], function (elt, icb) {
|
||||
console.log('called', elt);
|
||||
setTimeout(function () {
|
||||
console.log('answering', elt);
|
||||
icb(null, elt);
|
||||
}, Math.random() * 1000);
|
||||
}, console.log); */
|
||||
|
||||
function identity(x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
function handleError(url, error, data, cb) { // cb(error) and answer truthy if needed, else falsey
|
||||
if (!error && (data.status === 'success')) {
|
||||
return;
|
||||
}
|
||||
if (!error) { // Create a message from the data
|
||||
error = data.status + ': ' + data.error;
|
||||
}
|
||||
if (typeof(error) === 'string') { // Make a proper Error object
|
||||
error = new Error(error);
|
||||
}
|
||||
error.message += ' in ' + url; // Include the url.
|
||||
cb(error);
|
||||
return true;
|
||||
}
|
||||
|
||||
function getPlace(placeData, cb) { // cb(error, side-effected-placeData), after adding path, thumbnails, and description
|
||||
var url = metaverseBase + 'places/' + placeData.place_name;
|
||||
getRequest(url, function (error, data) {
|
||||
if (handleError(url, error, data, cb)) {
|
||||
return;
|
||||
}
|
||||
var place = data.data.place, previews = place.previews;
|
||||
placeData.path = place.path;
|
||||
if (previews && previews.thumbnail) {
|
||||
placeData.thumbnail_url = previews.thumbnail;
|
||||
}
|
||||
if (place.description) {
|
||||
placeData.description = place.description;
|
||||
placeData.searchText += ' ' + place.description.toUpperCase();
|
||||
}
|
||||
cb(error, placeData);
|
||||
});
|
||||
}
|
||||
function makeModelData(data, optionalPlaceName) { // create a new obj from data
|
||||
// ListModel elements will only ever have those properties that are defined by the first obj that is added.
|
||||
// So here we make sure that we have all the properties we need, regardless of whether it is a place data or user story.
|
||||
var name = optionalPlaceName || data.place_name,
|
||||
tags = data.tags || [data.action, data.username],
|
||||
description = data.description || "",
|
||||
thumbnail_url = data.thumbnail_url || "",
|
||||
image_url = thumbnail_url;
|
||||
if (data.details) {
|
||||
try {
|
||||
image_url = JSON.parse(data.details).image_url || thumbnail_url;
|
||||
} catch (e) {
|
||||
console.log(name, "has bad details", data.details);
|
||||
}
|
||||
}
|
||||
return {
|
||||
place_name: name,
|
||||
username: data.username || "",
|
||||
path: data.path || "",
|
||||
created_at: data.created_at || "",
|
||||
action: data.action || "",
|
||||
thumbnail_url: thumbnail_url,
|
||||
image_url: image_url,
|
||||
|
||||
tags: tags,
|
||||
description: description,
|
||||
online_users: data.online_users || 0,
|
||||
|
||||
searchText: [name].concat(tags, description || []).join(' ').toUpperCase()
|
||||
}
|
||||
}
|
||||
function mapDomainPlaces(domain, cb) { // cb(error, arrayOfDomainPlaceData)
|
||||
function addPlace(name, icb) {
|
||||
getPlace(makeModelData(domain, name), icb);
|
||||
}
|
||||
// IWBNI we could get these results in order with most-recent-entered first.
|
||||
// In any case, we don't really need to preserve the domain.names order in the results.
|
||||
asyncMap(domain.names || [], addPlace, cb);
|
||||
}
|
||||
|
||||
function suggestable(place) {
|
||||
if (addressBarDialog.useFeed) {
|
||||
return true;
|
||||
}
|
||||
return (place.place_name !== AddressManager.hostname) // Not our entry, but do show other entry points to current domain.
|
||||
&& place.thumbnail_url
|
||||
&& place.online_users // at least one present means it's actually online
|
||||
&& place.online_users <= 20;
|
||||
}
|
||||
function getDomainPage(pageNumber, cb) { // cb(error) after all pages of domain data have been added to model
|
||||
// Each page of results is processed completely before we start on the next page.
|
||||
// For each page of domains, we process each domain in parallel, and for each domain, process each place name in parallel.
|
||||
// This gives us minimum latency within the page, but we do preserve the order within the page by using asyncMap and
|
||||
// only appending the collected results.
|
||||
var params = [
|
||||
'open', // published hours handle now
|
||||
// FIXME: should determine if place is actually running
|
||||
'restriction=open', // Not by whitelist, etc. FIXME: If logged in, add hifi to the restriction options, in order to include places that require login.
|
||||
// FIXME add maturity
|
||||
'protocol=' + encodeURIComponent(AddressManager.protocolVersion()),
|
||||
'sort_by=users',
|
||||
'sort_order=desc',
|
||||
'page=' + pageNumber
|
||||
];
|
||||
var url = metaverseBase + 'domains/all?' + params.join('&');
|
||||
getRequest(url, function (error, data) {
|
||||
if (handleError(url, error, data, cb)) {
|
||||
return;
|
||||
}
|
||||
asyncMap(data.data.domains, mapDomainPlaces, function (error, pageResults) {
|
||||
if (error) {
|
||||
return cb(error);
|
||||
}
|
||||
// pageResults is now [ [ placeDataOneForDomainOne, placeDataTwoForDomainOne, ...], [ placeDataTwoForDomainTwo...] ]
|
||||
pageResults.forEach(function (domainResults) {
|
||||
allPlaces = allPlaces.concat(domainResults);
|
||||
if (!addressLine.text && !addressBarDialog.useFeed) { // Don't add if the user is already filtering
|
||||
domainResults.forEach(function (place) {
|
||||
if (suggestable(place)) {
|
||||
suggestions.append(place);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
if (data.current_page < data.total_pages) {
|
||||
return getDomainPage(pageNumber + 1, cb);
|
||||
}
|
||||
cb();
|
||||
});
|
||||
});
|
||||
}
|
||||
function getUserStoryPage(pageNumber, cb) { // cb(error) after all pages of domain data have been added to model
|
||||
var url = metaverseBase + 'user_stories?page=' + pageNumber;
|
||||
getRequest(url, function (error, data) {
|
||||
if (handleError(url, error, data, cb)) {
|
||||
return;
|
||||
}
|
||||
var stories = data.user_stories.map(function (story) { // explicit single-argument function
|
||||
return makeModelData(story);
|
||||
});
|
||||
allStories = allStories.concat(stories);
|
||||
if (!addressLine.text && addressBarDialog.useFeed) { // Don't add if the user is already filtering
|
||||
stories.forEach(function (story) {
|
||||
suggestions.append(story);
|
||||
});
|
||||
}
|
||||
if ((data.current_page < data.total_pages) && (data.current_page <= 10)) { // just 10 pages = 100 stories for now
|
||||
return getUserStoryPage(pageNumber + 1, cb);
|
||||
}
|
||||
cb();
|
||||
});
|
||||
}
|
||||
function filterChoicesByText() {
|
||||
suggestions.clear();
|
||||
var words = addressLine.text.toUpperCase().split(/\s+/).filter(identity),
|
||||
data = addressBarDialog.useFeed ? allStories : allPlaces;
|
||||
function matches(place) {
|
||||
if (!words.length) {
|
||||
return suggestable(place);
|
||||
}
|
||||
return words.every(function (word) {
|
||||
return place.searchText.indexOf(word) >= 0;
|
||||
});
|
||||
}
|
||||
data.forEach(function (place) {
|
||||
if (matches(place)) {
|
||||
suggestions.append(place);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fillDestinations() {
|
||||
allPlaces = [];
|
||||
allStories = [];
|
||||
suggestions.clear();
|
||||
getDomainPage(1, function (error) {
|
||||
console.log('domain query', error || 'ok', allPlaces.length);
|
||||
});
|
||||
getUserStoryPage(1, function (error) {
|
||||
console.log('user stories query', error || 'ok', allStories.length);
|
||||
});
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
addressLine.forceActiveFocus()
|
||||
fillDestinations();
|
||||
} else {
|
||||
addressLine.text = ""
|
||||
}
|
||||
}
|
||||
|
||||
function toggleOrGo(fromSuggestions) {
|
||||
if (addressLine.text !== "") {
|
||||
addressBarDialog.loadAddress(addressLine.text, fromSuggestions)
|
||||
}
|
||||
root.shown = false;
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
switch (event.key) {
|
||||
case Qt.Key_Escape:
|
||||
case Qt.Key_Back:
|
||||
root.shown = false
|
||||
event.accepted = true
|
||||
break
|
||||
case Qt.Key_Enter:
|
||||
case Qt.Key_Return:
|
||||
toggleOrGo()
|
||||
event.accepted = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@ Rectangle {
|
|||
property string thumbnail: defaultThumbnail;
|
||||
property string imageUrl: "";
|
||||
property var goFunction: null;
|
||||
property string storyId: "";
|
||||
|
||||
property string timePhrase: pastTime(timestamp);
|
||||
property string actionPhrase: makeActionPhrase(action);
|
||||
|
|
Loading…
Reference in a new issue