mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 09:48:44 +02:00
Merge pull request #12638 from zfox23/commerce_upgrades_1
Commerce: Item Updates!
This commit is contained in:
commit
113670e33b
17 changed files with 909 additions and 177 deletions
19
interface/resources/icons/tablet-icons/market-a-msg.svg
Normal file
19
interface/resources/icons/tablet-icons/market-a-msg.svg
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#EF3B4E;}
|
||||||
|
</style>
|
||||||
|
<circle class="st0" cx="44.1" cy="6" r="5.6"/>
|
||||||
|
<g>
|
||||||
|
<path d="M17.6,33.4c0.4,0,0.6,0,0.9,0c6.5,0,13,0,19.5,0c1.3,0,2,0.5,2.2,1.5c0.2,1.1-0.5,2.2-1.6,2.3c-0.2,0-0.5,0-0.7,0
|
||||||
|
c-7.4,0-14.8,0-22.3,0c-2,0-2.7-0.9-2.2-2.9c0.3-1.1,0.5-2.3,0.8-3.4c0.3-0.9,0.2-1.8,0-2.8C12.7,22,11.1,15.9,9.6,9.8
|
||||||
|
C9.4,9.3,9.2,9.1,8.7,9.1c-1.3,0-2.6,0-3.9,0c-1.2,0-2-0.8-2-1.9c0-1.1,0.8-1.9,2-1.9c2,0,3.9,0,5.9,0c1.1,0,1.7,0.5,2,1.5
|
||||||
|
c0.4,1.3,1.6,4.8,1.9,6.2c2.2,0.1,4.3,0.2,6.5,0.3c6.7,0.3,11.4,0.4,18.1,0.7c1.2,0.1,2.3,0.1,3.5,0.2c1.4,0.1,2.2,1.4,1.6,2.6
|
||||||
|
c-0.9,2.5-3.5,8.5-4.4,10.4c-0.4,0.8-1,1.1-1.9,1.2c-5.9,0.3-12.5,0.5-18.4,0.7c-0.8,0-1.2,0.3-1.3,1.1
|
||||||
|
C18.4,30.7,17.7,32.9,17.6,33.4z"/>
|
||||||
|
<path d="M39.2,42c0,1.9-1.6,3.6-3.5,3.6c-2,0-3.6-1.6-3.6-3.6c0-1.9,1.6-3.6,3.6-3.6C37.6,38.5,39.2,40.1,39.2,42z"/>
|
||||||
|
<path d="M17.8,41.9c0,1.9-1.7,3.5-3.6,3.5c-1.9,0-3.5-1.7-3.5-3.6c0-2,1.6-3.6,3.6-3.6C16.2,38.3,17.8,39.9,17.8,41.9z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -1,64 +1,15 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
<svg
|
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
<g>
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
<path d="M17.6,33.4c0.4,0,0.6,0,0.9,0c6.5,0,13,0,19.5,0c1.3,0,2,0.5,2.2,1.5c0.2,1.1-0.5,2.2-1.6,2.3c-0.2,0-0.5,0-0.7,0
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
c-7.4,0-14.8,0-22.3,0c-2,0-2.7-0.9-2.2-2.9c0.3-1.1,0.5-2.3,0.8-3.4c0.3-0.9,0.2-1.8,0-2.8C12.7,22,11.1,15.9,9.6,9.8
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
C9.4,9.3,9.2,9.1,8.7,9.1c-1.3,0-2.6,0-3.9,0c-1.2,0-2-0.8-2-1.9c0-1.1,0.8-1.9,2-1.9c2,0,3.9,0,5.9,0c1.1,0,1.7,0.5,2,1.5
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
c0.4,1.3,1.6,4.8,1.9,6.2c2.2,0.1,4.3,0.2,6.5,0.3c6.7,0.3,11.4,0.4,18.1,0.7c1.2,0.1,2.3,0.1,3.5,0.2c1.4,0.1,2.2,1.4,1.6,2.6
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
c-0.9,2.5-3.5,8.5-4.4,10.4c-0.4,0.8-1,1.1-1.9,1.2c-5.9,0.3-12.5,0.5-18.4,0.7c-0.8,0-1.2,0.3-1.3,1.1
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
C18.4,30.7,17.7,32.9,17.6,33.4z"/>
|
||||||
version="1.1"
|
<path d="M39.2,42c0,1.9-1.6,3.6-3.5,3.6c-2,0-3.6-1.6-3.6-3.6c0-1.9,1.6-3.6,3.6-3.6C37.6,38.5,39.2,40.1,39.2,42z"/>
|
||||||
x="0px"
|
<path d="M17.8,41.9c0,1.9-1.7,3.5-3.6,3.5c-1.9,0-3.5-1.7-3.5-3.6c0-2,1.6-3.6,3.6-3.6C16.2,38.3,17.8,39.9,17.8,41.9z"/>
|
||||||
y="0px"
|
</g>
|
||||||
viewBox="0 0 50 50"
|
</svg>
|
||||||
style="enable-background:new 0 0 50 50;"
|
|
||||||
xml:space="preserve"
|
|
||||||
id="svg2"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="market-a.svg"><metadata
|
|
||||||
id="metadata20"><rdf:RDF><cc:Work
|
|
||||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
|
||||||
id="defs18" /><sodipodi:namedview
|
|
||||||
pagecolor="#ff0000"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1"
|
|
||||||
objecttolerance="10"
|
|
||||||
gridtolerance="10"
|
|
||||||
guidetolerance="10"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:window-width="852"
|
|
||||||
inkscape:window-height="480"
|
|
||||||
id="namedview16"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:zoom="4.72"
|
|
||||||
inkscape:cx="25"
|
|
||||||
inkscape:cy="25"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="0"
|
|
||||||
inkscape:current-layer="svg2" /><style
|
|
||||||
type="text/css"
|
|
||||||
id="style4">
|
|
||||||
.st0{fill:#FFFFFF;}
|
|
||||||
</style><g
|
|
||||||
id="Layer_2" /><g
|
|
||||||
id="Layer_1"
|
|
||||||
style="fill:#000000;fill-opacity:1"><g
|
|
||||||
id="g8"
|
|
||||||
style="fill:#000000;fill-opacity:1"><path
|
|
||||||
class="st0"
|
|
||||||
d="M45.4,13.7c-1.6-0.1-3.2,0-4.8,0c-7.5,0-18,0-25.7,0c-0.6-1.8-1-3.5-1.7-5.2C13,7.9,12.2,7.1,11.5,7 C9.4,6.7,7.3,6.7,5.2,6.7c-1.1,0-1.9,0.5-1.9,1.7c0,1.2,0.8,1.7,1.9,1.7c1.3,0,2.7,0,4,0.1c0.5,0.1,1.2,0.6,1.4,1.1 c0.9,2.6,1.7,5.2,2.5,7.8c1.3,4.3,1.8,5.5,3.1,10.2c0.6,2.3,1.2,2.8,2.2,3.3c1.1,0.4,2.1,0.4,2.1,0.4h1.8c4.6,0,12.2,0,16.8,0 c1.1,0,2.1-0.1,2.6-1.4c1.9-5.1,3.8-10.2,5.7-15.3C47.8,14.7,47.1,13.8,45.4,13.7z M38.9,28.7c-0.1,0.3-0.8,0.7-1.2,0.7 c-4.6,0-12.2,0-16.8,0c-0.4,0-1.1-0.3-1.2-0.7c-1.3-3.8-2.4-7.6-3.7-11.5h27.1C41.8,21.2,40.4,24.9,38.9,28.7z"
|
|
||||||
id="path10"
|
|
||||||
style="fill:#000000;fill-opacity:1" /><path
|
|
||||||
class="st0"
|
|
||||||
d="M17.2,37.3L17.2,37.3c-1,0-1.7,0.2-2.2,0.7c-0.6,0.6-0.9,1.3-0.9,2.3c0,1,0.3,1.8,0.8,2.4 c0.6,0.6,1.4,0.9,2.2,0.9c1.8,0,3.2-1.4,3.2-3.2c0-0.9-0.3-1.7-0.9-2.3C18.8,37.6,18,37.3,17.2,37.3z"
|
|
||||||
id="path12"
|
|
||||||
style="fill:#000000;fill-opacity:1" /><path
|
|
||||||
class="st0"
|
|
||||||
d="M35.1,37.3L35.1,37.3c-1,0-1.7,0.2-2.2,0.7c-0.6,0.6-0.9,1.4-0.9,2.4c0,1,0.3,1.8,0.8,2.4 c0.6,0.6,1.3,0.9,2.2,0.9c1.8,0,3.2-1.5,3.2-3.3c0-0.9-0.3-1.6-0.9-2.2C36.8,37.6,36,37.3,35.1,37.3z"
|
|
||||||
id="path14"
|
|
||||||
style="fill:#000000;fill-opacity:1" /></g></g></svg>
|
|
||||||
|
|
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 1.2 KiB |
21
interface/resources/icons/tablet-icons/market-i-msg.svg
Normal file
21
interface/resources/icons/tablet-icons/market-i-msg.svg
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#EF3B4E;}
|
||||||
|
.st1{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<circle class="st0" cx="44.1" cy="6" r="5.6"/>
|
||||||
|
<g>
|
||||||
|
<path class="st1" d="M17.6,33.4c0.4,0,0.6,0,0.9,0c6.5,0,13,0,19.5,0c1.3,0,2,0.5,2.2,1.5c0.2,1.1-0.5,2.2-1.6,2.3
|
||||||
|
c-0.2,0-0.5,0-0.7,0c-7.4,0-14.8,0-22.3,0c-2,0-2.7-0.9-2.2-2.9c0.3-1.1,0.5-2.3,0.8-3.4c0.3-0.9,0.2-1.8,0-2.8
|
||||||
|
C12.7,22,11.1,15.9,9.6,9.8C9.4,9.3,9.2,9.1,8.7,9.1c-1.3,0-2.6,0-3.9,0c-1.2,0-2-0.8-2-1.9c0-1.1,0.8-1.9,2-1.9c2,0,3.9,0,5.9,0
|
||||||
|
c1.1,0,1.7,0.5,2,1.5c0.4,1.3,1.6,4.8,1.9,6.2c2.2,0.1,4.3,0.2,6.5,0.3c6.7,0.3,11.4,0.4,18.1,0.7c1.2,0.1,2.3,0.1,3.5,0.2
|
||||||
|
c1.4,0.1,2.2,1.4,1.6,2.6c-0.9,2.5-3.5,8.5-4.4,10.4c-0.4,0.8-1,1.1-1.9,1.2c-5.9,0.3-12.5,0.5-18.4,0.7c-0.8,0-1.2,0.3-1.3,1.1
|
||||||
|
C18.4,30.7,17.7,32.9,17.6,33.4z"/>
|
||||||
|
<path class="st1" d="M39.2,42c0,1.9-1.6,3.6-3.5,3.6c-2,0-3.6-1.6-3.6-3.6c0-1.9,1.6-3.6,3.6-3.6C37.6,38.5,39.2,40.1,39.2,42z"/>
|
||||||
|
<path class="st1" d="M17.8,41.9c0,1.9-1.7,3.5-3.6,3.5c-1.9,0-3.5-1.7-3.5-3.6c0-2,1.6-3.6,3.6-3.6C16.2,38.3,17.8,39.9,17.8,41.9z
|
||||||
|
"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -1,23 +1,19 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.st0{fill:#FFFFFF;}
|
.st0{fill:#FFFFFF;}
|
||||||
</style>
|
</style>
|
||||||
<g id="Layer_2">
|
<g>
|
||||||
</g>
|
<path class="st0" d="M17.6,33.4c0.4,0,0.6,0,0.9,0c6.5,0,13,0,19.5,0c1.3,0,2,0.5,2.2,1.5c0.2,1.1-0.5,2.2-1.6,2.3
|
||||||
<g id="Layer_1">
|
c-0.2,0-0.5,0-0.7,0c-7.4,0-14.8,0-22.3,0c-2,0-2.7-0.9-2.2-2.9c0.3-1.1,0.5-2.3,0.8-3.4c0.3-0.9,0.2-1.8,0-2.8
|
||||||
<g>
|
C12.7,22,11.1,15.9,9.6,9.8C9.4,9.3,9.2,9.1,8.7,9.1c-1.3,0-2.6,0-3.9,0c-1.2,0-2-0.8-2-1.9c0-1.1,0.8-1.9,2-1.9c2,0,3.9,0,5.9,0
|
||||||
<path class="st0" d="M45.4,13.7c-1.6-0.1-3.2,0-4.8,0c-7.5,0-18,0-25.7,0c-0.6-1.8-1-3.5-1.7-5.2C13,7.9,12.2,7.1,11.5,7
|
c1.1,0,1.7,0.5,2,1.5c0.4,1.3,1.6,4.8,1.9,6.2c2.2,0.1,4.3,0.2,6.5,0.3c6.7,0.3,11.4,0.4,18.1,0.7c1.2,0.1,2.3,0.1,3.5,0.2
|
||||||
C9.4,6.7,7.3,6.7,5.2,6.7c-1.1,0-1.9,0.5-1.9,1.7c0,1.2,0.8,1.7,1.9,1.7c1.3,0,2.7,0,4,0.1c0.5,0.1,1.2,0.6,1.4,1.1
|
c1.4,0.1,2.2,1.4,1.6,2.6c-0.9,2.5-3.5,8.5-4.4,10.4c-0.4,0.8-1,1.1-1.9,1.2c-5.9,0.3-12.5,0.5-18.4,0.7c-0.8,0-1.2,0.3-1.3,1.1
|
||||||
c0.9,2.6,1.7,5.2,2.5,7.8c1.3,4.3,1.8,5.5,3.1,10.2c0.6,2.3,1.2,2.8,2.2,3.3c1.1,0.4,2.1,0.4,2.1,0.4h1.8c4.6,0,12.2,0,16.8,0
|
C18.4,30.7,17.7,32.9,17.6,33.4z"/>
|
||||||
c1.1,0,2.1-0.1,2.6-1.4c1.9-5.1,3.8-10.2,5.7-15.3C47.8,14.7,47.1,13.8,45.4,13.7z M38.9,28.7c-0.1,0.3-0.8,0.7-1.2,0.7
|
<path class="st0" d="M39.2,42c0,1.9-1.6,3.6-3.5,3.6c-2,0-3.6-1.6-3.6-3.6c0-1.9,1.6-3.6,3.6-3.6C37.6,38.5,39.2,40.1,39.2,42z"/>
|
||||||
c-4.6,0-12.2,0-16.8,0c-0.4,0-1.1-0.3-1.2-0.7c-1.3-3.8-2.4-7.6-3.7-11.5h27.1C41.8,21.2,40.4,24.9,38.9,28.7z"/>
|
<path class="st0" d="M17.8,41.9c0,1.9-1.7,3.5-3.6,3.5c-1.9,0-3.5-1.7-3.5-3.6c0-2,1.6-3.6,3.6-3.6C16.2,38.3,17.8,39.9,17.8,41.9z
|
||||||
<path class="st0" d="M17.2,37.3L17.2,37.3c-1,0-1.7,0.2-2.2,0.7c-0.6,0.6-0.9,1.3-0.9,2.3c0,1,0.3,1.8,0.8,2.4
|
"/>
|
||||||
c0.6,0.6,1.4,0.9,2.2,0.9c1.8,0,3.2-1.4,3.2-3.2c0-0.9-0.3-1.7-0.9-2.3C18.8,37.6,18,37.3,17.2,37.3z"/>
|
|
||||||
<path class="st0" d="M35.1,37.3L35.1,37.3c-1,0-1.7,0.2-2.2,0.7c-0.6,0.6-0.9,1.4-0.9,2.4c0,1,0.3,1.8,0.8,2.4
|
|
||||||
c0.6,0.6,1.3,0.9,2.2,0.9c1.8,0,3.2-1.5,3.2-3.3c0-0.9-0.3-1.6-0.9-2.2C36.8,37.6,36,37.3,35.1,37.3z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
321
interface/resources/qml/controls-uit/FilterBar.qml
Normal file
321
interface/resources/qml/controls-uit/FilterBar.qml
Normal file
|
@ -0,0 +1,321 @@
|
||||||
|
//
|
||||||
|
// FilterBar.qml
|
||||||
|
//
|
||||||
|
// Created by Zach Fox on 17 Feb 2018-03-12
|
||||||
|
// Copyright 2018 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 QtQuick 2.9
|
||||||
|
import QtQuick.Controls 2.2
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
|
import "../styles-uit"
|
||||||
|
import "../controls-uit" as HifiControls
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root;
|
||||||
|
|
||||||
|
property int colorScheme: hifi.colorSchemes.light
|
||||||
|
readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light
|
||||||
|
readonly property bool isFaintGrayColorScheme: colorScheme == hifi.colorSchemes.faintGray
|
||||||
|
property bool error: false;
|
||||||
|
property alias textFieldHeight: textField.height;
|
||||||
|
property string placeholderText;
|
||||||
|
property alias dropdownHeight: dropdownContainer.height;
|
||||||
|
property alias text: textField.text;
|
||||||
|
property alias primaryFilterChoices: filterBarModel;
|
||||||
|
property int primaryFilter_index: -1;
|
||||||
|
property string primaryFilter_filterName: "";
|
||||||
|
property string primaryFilter_displayName: "";
|
||||||
|
signal accepted;
|
||||||
|
|
||||||
|
onPrimaryFilter_indexChanged: {
|
||||||
|
if (primaryFilter_index === -1) {
|
||||||
|
primaryFilter_filterName = "";
|
||||||
|
primaryFilter_displayName = "";
|
||||||
|
} else {
|
||||||
|
primaryFilter_filterName = filterBarModel.get(primaryFilter_index).filterName;
|
||||||
|
primaryFilter_displayName = filterBarModel.get(primaryFilter_index).displayName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: textField;
|
||||||
|
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
|
||||||
|
font.family: "Fira Sans"
|
||||||
|
font.pixelSize: hifi.fontSizes.textFieldInput;
|
||||||
|
|
||||||
|
placeholderText: root.primaryFilter_index === -1 ? root.placeholderText : "";
|
||||||
|
|
||||||
|
TextMetrics {
|
||||||
|
id: primaryFilterTextMetrics;
|
||||||
|
font.family: "FiraSans Regular";
|
||||||
|
font.pixelSize: hifi.fontSizes.textFieldInput;
|
||||||
|
font.capitalization: Font.AllUppercase;
|
||||||
|
text: root.primaryFilter_displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// workaround for https://bugreports.qt.io/browse/QTBUG-49297
|
||||||
|
Keys.onPressed: {
|
||||||
|
switch (event.key) {
|
||||||
|
case Qt.Key_Return:
|
||||||
|
case Qt.Key_Enter:
|
||||||
|
event.accepted = true;
|
||||||
|
|
||||||
|
// emit accepted signal manually
|
||||||
|
if (acceptableInput) {
|
||||||
|
root.accepted();
|
||||||
|
root.forceActiveFocus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Qt.Key_Backspace:
|
||||||
|
if (textField.text === "") {
|
||||||
|
primaryFilter_index = -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
root.forceActiveFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (!activeFocus) {
|
||||||
|
dropdownContainer.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
color: {
|
||||||
|
if (isLightColorScheme) {
|
||||||
|
if (textField.activeFocus) {
|
||||||
|
hifi.colors.black
|
||||||
|
} else {
|
||||||
|
hifi.colors.lightGray
|
||||||
|
}
|
||||||
|
} else if (isFaintGrayColorScheme) {
|
||||||
|
if (textField.activeFocus) {
|
||||||
|
hifi.colors.black
|
||||||
|
} else {
|
||||||
|
hifi.colors.lightGray
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (textField.activeFocus) {
|
||||||
|
hifi.colors.white
|
||||||
|
} else {
|
||||||
|
hifi.colors.lightGrayText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
id: mainFilterBarRectangle;
|
||||||
|
|
||||||
|
color: {
|
||||||
|
if (isLightColorScheme) {
|
||||||
|
if (textField.activeFocus) {
|
||||||
|
hifi.colors.white
|
||||||
|
} else {
|
||||||
|
hifi.colors.textFieldLightBackground
|
||||||
|
}
|
||||||
|
} else if (isFaintGrayColorScheme) {
|
||||||
|
if (textField.activeFocus) {
|
||||||
|
hifi.colors.white
|
||||||
|
} else {
|
||||||
|
hifi.colors.faintGray50
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (textField.activeFocus) {
|
||||||
|
hifi.colors.black
|
||||||
|
} else {
|
||||||
|
hifi.colors.baseGrayShadow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
border.color: textField.error ? hifi.colors.redHighlight :
|
||||||
|
(textField.activeFocus ? hifi.colors.primaryHighlight : (isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray))
|
||||||
|
border.width: 1
|
||||||
|
radius: 4
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: searchButtonContainer;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
height: parent.height;
|
||||||
|
width: 42;
|
||||||
|
|
||||||
|
// Search icon
|
||||||
|
HiFiGlyphs {
|
||||||
|
id: searchIcon;
|
||||||
|
text: hifi.glyphs.search
|
||||||
|
color: textField.color
|
||||||
|
size: 40;
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
width: paintedWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Carat
|
||||||
|
HiFiGlyphs {
|
||||||
|
text: hifi.glyphs.caratDn;
|
||||||
|
color: textField.color;
|
||||||
|
size: 40;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.leftMargin: 15;
|
||||||
|
width: paintedWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent;
|
||||||
|
onClicked: {
|
||||||
|
textField.forceActiveFocus();
|
||||||
|
dropdownContainer.visible = !dropdownContainer.visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
z: 999;
|
||||||
|
id: primaryFilterContainer;
|
||||||
|
color: textField.activeFocus ? hifi.colors.faintGray : hifi.colors.white;
|
||||||
|
width: primaryFilterTextMetrics.tightBoundingRect.width + 14;
|
||||||
|
height: parent.height - 8;
|
||||||
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
anchors.left: searchButtonContainer.right;
|
||||||
|
anchors.leftMargin: 4;
|
||||||
|
visible: primaryFilterText.text !== "";
|
||||||
|
radius: height/2;
|
||||||
|
|
||||||
|
FiraSansRegular {
|
||||||
|
id: primaryFilterText;
|
||||||
|
text: root.primaryFilter_displayName;
|
||||||
|
anchors.fill: parent;
|
||||||
|
color: textField.activeFocus ? hifi.colors.black : hifi.colors.lightGray;
|
||||||
|
horizontalAlignment: Text.AlignHCenter;
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
size: hifi.fontSizes.textFieldInput;
|
||||||
|
font.capitalization: Font.AllUppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent;
|
||||||
|
onClicked: {
|
||||||
|
textField.forceActiveFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Clear" button
|
||||||
|
HiFiGlyphs {
|
||||||
|
text: hifi.glyphs.error
|
||||||
|
color: textField.color
|
||||||
|
size: 40
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: hifi.dimensions.textPadding - 2
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: root.text !== "" || root.primaryFilter_index !== -1;
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent;
|
||||||
|
onClicked: {
|
||||||
|
root.text = "";
|
||||||
|
root.primaryFilter_index = -1;
|
||||||
|
dropdownContainer.visible = false;
|
||||||
|
textField.forceActiveFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedTextColor: hifi.colors.black
|
||||||
|
selectionColor: hifi.colors.primaryHighlight
|
||||||
|
leftPadding: 44 + (root.primaryFilter_index === -1 ? 0 : primaryFilterTextMetrics.tightBoundingRect.width + 20);
|
||||||
|
rightPadding: 44;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: dropdownContainer;
|
||||||
|
visible: false;
|
||||||
|
height: 50 * filterBarModel.count;
|
||||||
|
width: parent.width;
|
||||||
|
anchors.top: textField.bottom;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
color: hifi.colors.white;
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: filterBarModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: dropdownListView;
|
||||||
|
interactive: false;
|
||||||
|
anchors.fill: parent;
|
||||||
|
model: filterBarModel;
|
||||||
|
delegate: Rectangle {
|
||||||
|
id: dropDownButton;
|
||||||
|
color: hifi.colors.white;
|
||||||
|
width: parent.width;
|
||||||
|
height: 50;
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: dropDownButtonText;
|
||||||
|
text: model.displayName;
|
||||||
|
anchors.fill: parent;
|
||||||
|
anchors.leftMargin: 12;
|
||||||
|
color: hifi.colors.baseGray;
|
||||||
|
horizontalAlignment: Text.AlignLeft;
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
size: 18;
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent;
|
||||||
|
hoverEnabled: true;
|
||||||
|
propagateComposedEvents: false;
|
||||||
|
onEntered: {
|
||||||
|
dropDownButton.color = hifi.colors.blueHighlight;
|
||||||
|
}
|
||||||
|
onExited: {
|
||||||
|
dropDownButton.color = hifi.colors.white;
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
textField.forceActiveFocus();
|
||||||
|
root.primaryFilter_index = index;
|
||||||
|
dropdownContainer.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DropShadow {
|
||||||
|
anchors.fill: dropdownContainer;
|
||||||
|
horizontalOffset: 0;
|
||||||
|
verticalOffset: 4;
|
||||||
|
radius: 4.0;
|
||||||
|
samples: 9
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.25);
|
||||||
|
source: dropdownContainer;
|
||||||
|
visible: dropdownContainer.visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeFilterByDisplayName(name) {
|
||||||
|
for (var i = 0; i < filterBarModel.count; i++) {
|
||||||
|
if (filterBarModel.get(i).displayName === name) {
|
||||||
|
root.primaryFilter_index = i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Passed displayName not found in filterBarModel! primaryFilter unchanged.");
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,25 +30,31 @@ Rectangle {
|
||||||
property string activeView: "initialize";
|
property string activeView: "initialize";
|
||||||
property bool ownershipStatusReceived: false;
|
property bool ownershipStatusReceived: false;
|
||||||
property bool balanceReceived: false;
|
property bool balanceReceived: false;
|
||||||
|
property bool availableUpdatesReceived: false;
|
||||||
|
property string baseItemName: "";
|
||||||
property string itemName;
|
property string itemName;
|
||||||
property string itemId;
|
property string itemId;
|
||||||
property string itemHref;
|
property string itemHref;
|
||||||
property string itemAuthor;
|
property string itemAuthor;
|
||||||
|
property int itemEdition: -1;
|
||||||
|
property string certificateId;
|
||||||
property double balanceAfterPurchase;
|
property double balanceAfterPurchase;
|
||||||
property bool alreadyOwned: false;
|
property bool alreadyOwned: false;
|
||||||
property int itemPrice: -1;
|
property int itemPrice: -1;
|
||||||
property bool isCertified;
|
property bool isCertified;
|
||||||
property string itemType;
|
property string itemType;
|
||||||
property var itemTypesArray: ["entity", "wearable", "contentSet", "app", "avatar"];
|
property var itemTypesArray: ["entity", "wearable", "contentSet", "app", "avatar", "unknown"];
|
||||||
property var itemTypesText: ["entity", "wearable", "content set", "app", "avatar"];
|
property var itemTypesText: ["entity", "wearable", "content set", "app", "avatar", "item"];
|
||||||
property var buttonTextNormal: ["REZ", "WEAR", "REPLACE CONTENT SET", "INSTALL", "WEAR"];
|
property var buttonTextNormal: ["REZ", "WEAR", "REPLACE CONTENT SET", "INSTALL", "WEAR", "REZ"];
|
||||||
property var buttonTextClicked: ["REZZED!", "WORN!", "CONTENT SET REPLACED!", "INSTALLED!", "AVATAR CHANGED!"]
|
property var buttonTextClicked: ["REZZED!", "WORN!", "CONTENT SET REPLACED!", "INSTALLED!", "AVATAR CHANGED!", "REZZED!"]
|
||||||
property var buttonGlyph: [hifi.glyphs.wand, hifi.glyphs.hat, hifi.glyphs.globe, hifi.glyphs.install, hifi.glyphs.avatar];
|
property var buttonGlyph: [hifi.glyphs.wand, hifi.glyphs.hat, hifi.glyphs.globe, hifi.glyphs.install, hifi.glyphs.avatar, hifi.glyphs.wand];
|
||||||
property bool shouldBuyWithControlledFailure: false;
|
property bool shouldBuyWithControlledFailure: false;
|
||||||
property bool debugCheckoutSuccess: false;
|
property bool debugCheckoutSuccess: false;
|
||||||
property bool canRezCertifiedItems: Entities.canRezCertified() || Entities.canRezTmpCertified();
|
property bool canRezCertifiedItems: Entities.canRezCertified() || Entities.canRezTmpCertified();
|
||||||
property string referrer;
|
property string referrer;
|
||||||
property bool isInstalled;
|
property bool isInstalled;
|
||||||
|
property bool isUpdating;
|
||||||
|
property string baseAppURL;
|
||||||
// Style
|
// Style
|
||||||
color: hifi.colors.white;
|
color: hifi.colors.white;
|
||||||
Connections {
|
Connections {
|
||||||
|
@ -103,8 +109,8 @@ Rectangle {
|
||||||
if (result.status !== 'success') {
|
if (result.status !== 'success') {
|
||||||
console.log("Failed to get balance", result.data.message);
|
console.log("Failed to get balance", result.data.message);
|
||||||
} else {
|
} else {
|
||||||
root.balanceReceived = true;
|
|
||||||
root.balanceAfterPurchase = result.data.balance - root.itemPrice;
|
root.balanceAfterPurchase = result.data.balance - root.itemPrice;
|
||||||
|
root.balanceReceived = true;
|
||||||
root.refreshBuyUI();
|
root.refreshBuyUI();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,13 +119,13 @@ Rectangle {
|
||||||
if (result.status !== 'success') {
|
if (result.status !== 'success') {
|
||||||
console.log("Failed to get Already Owned status", result.data.message);
|
console.log("Failed to get Already Owned status", result.data.message);
|
||||||
} else {
|
} else {
|
||||||
root.ownershipStatusReceived = true;
|
|
||||||
if (result.data.marketplace_item_id === root.itemId) {
|
if (result.data.marketplace_item_id === root.itemId) {
|
||||||
root.alreadyOwned = result.data.already_owned;
|
root.alreadyOwned = result.data.already_owned;
|
||||||
} else {
|
} else {
|
||||||
console.log("WARNING - Received 'Already Owned' status about different Marketplace ID!");
|
console.log("WARNING - Received 'Already Owned' status about different Marketplace ID!");
|
||||||
root.alreadyOwned = false;
|
root.alreadyOwned = false;
|
||||||
}
|
}
|
||||||
|
root.ownershipStatusReceived = true;
|
||||||
root.refreshBuyUI();
|
root.refreshBuyUI();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,11 +135,53 @@ Rectangle {
|
||||||
root.isInstalled = true;
|
root.isInstalled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAvailableUpdatesResult: {
|
||||||
|
if (result.status !== 'success') {
|
||||||
|
console.log("Failed to get Available Updates", result.data.message);
|
||||||
|
} else {
|
||||||
|
for (var i = 0; i < result.data.updates.length; i++) {
|
||||||
|
// If the ItemID of the item we're looking at matches EITHER the ID of a "base" item
|
||||||
|
// OR the ID of an "updated" item, we're updating.
|
||||||
|
if (root.itemId === result.data.updates[i].item_id ||
|
||||||
|
root.itemId === result.data.updates[i].updated_item_id) {
|
||||||
|
if (root.itemEdition !== -1 && root.itemEdition !== parseInt(result.data.updates[i].edition_number)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
root.isUpdating = true;
|
||||||
|
root.baseItemName = result.data.updates[i].base_item_title;
|
||||||
|
// This CertID is the one corresponding to the base item CertID that the user already owns
|
||||||
|
root.certificateId = result.data.updates[i].certificate_id;
|
||||||
|
if (root.itemType === "app") {
|
||||||
|
root.baseAppURL = result.data.updates[i].item_download_url;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
root.availableUpdatesReceived = true;
|
||||||
|
refreshBuyUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onUpdateItemResult: {
|
||||||
|
if (result.status !== 'success') {
|
||||||
|
failureErrorText.text = result.message;
|
||||||
|
root.activeView = "checkoutFailure";
|
||||||
|
} else {
|
||||||
|
root.itemHref = result.data.download_url;
|
||||||
|
if (result.data.categories.indexOf("Wearables") > -1) {
|
||||||
|
root.itemType = "wearable";
|
||||||
|
}
|
||||||
|
root.activeView = "checkoutSuccess";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onItemIdChanged: {
|
onItemIdChanged: {
|
||||||
root.ownershipStatusReceived = false;
|
root.ownershipStatusReceived = false;
|
||||||
Commerce.alreadyOwned(root.itemId);
|
Commerce.alreadyOwned(root.itemId);
|
||||||
|
root.availableUpdatesReceived = false;
|
||||||
|
Commerce.getAvailableUpdates(root.itemId);
|
||||||
itemPreviewImage.source = "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/previews/" + itemId + "/thumbnail/hifi-mp-" + itemId + ".jpg";
|
itemPreviewImage.source = "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/previews/" + itemId + "/thumbnail/hifi-mp-" + itemId + ".jpg";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,6 +209,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
onItemPriceChanged: {
|
onItemPriceChanged: {
|
||||||
|
root.balanceReceived = false;
|
||||||
Commerce.balance();
|
Commerce.balance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,6 +289,7 @@ Rectangle {
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
ownershipStatusReceived = false;
|
ownershipStatusReceived = false;
|
||||||
balanceReceived = false;
|
balanceReceived = false;
|
||||||
|
availableUpdatesReceived = false;
|
||||||
Commerce.getWalletStatus();
|
Commerce.getWalletStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,7 +366,7 @@ Rectangle {
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: loading;
|
id: loading;
|
||||||
z: 997;
|
z: 997;
|
||||||
visible: !root.ownershipStatusReceived || !root.balanceReceived;
|
visible: !root.ownershipStatusReceived || !root.balanceReceived || !root.availableUpdatesReceived;
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
color: hifi.colors.white;
|
color: hifi.colors.white;
|
||||||
|
|
||||||
|
@ -412,6 +462,7 @@ Rectangle {
|
||||||
// "HFC" balance label
|
// "HFC" balance label
|
||||||
HiFiGlyphs {
|
HiFiGlyphs {
|
||||||
id: itemPriceTextLabel;
|
id: itemPriceTextLabel;
|
||||||
|
visible: !(root.isUpdating && root.itemEdition > 0);
|
||||||
text: hifi.glyphs.hfc;
|
text: hifi.glyphs.hfc;
|
||||||
// Size
|
// Size
|
||||||
size: 30;
|
size: 30;
|
||||||
|
@ -427,9 +478,9 @@ Rectangle {
|
||||||
}
|
}
|
||||||
FiraSansSemiBold {
|
FiraSansSemiBold {
|
||||||
id: itemPriceText;
|
id: itemPriceText;
|
||||||
text: (root.itemPrice === -1) ? "--" : root.itemPrice;
|
text: (root.isUpdating && root.itemEdition > 0) ? "FREE\nUPDATE" : ((root.itemPrice === -1) ? "--" : root.itemPrice);
|
||||||
// Text size
|
// Text size
|
||||||
size: 26;
|
size: (root.isUpdating && root.itemEdition > 0) ? 20 : 26;
|
||||||
// Anchors
|
// Anchors
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
|
@ -529,9 +580,13 @@ Rectangle {
|
||||||
height: 50;
|
height: 50;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
text: "VIEW THIS ITEM IN MY PURCHASES";
|
text: root.isUpdating ? "UPDATE TO THIS ITEM FOR FREE" : "VIEW THIS ITEM IN MY PURCHASES";
|
||||||
onClicked: {
|
onClicked: {
|
||||||
sendToScript({method: 'checkout_goToPurchases', filterText: root.itemName});
|
if (root.isUpdating) {
|
||||||
|
sendToScript({method: 'checkout_goToPurchases', filterText: root.baseItemName});
|
||||||
|
} else {
|
||||||
|
sendToScript({method: 'checkout_goToPurchases', filterText: root.itemName});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,7 +594,7 @@ Rectangle {
|
||||||
HifiControlsUit.Button {
|
HifiControlsUit.Button {
|
||||||
id: buyButton;
|
id: buyButton;
|
||||||
visible: !((root.itemType === "avatar" || root.itemType === "app") && viewInMyPurchasesButton.visible)
|
visible: !((root.itemType === "avatar" || root.itemType === "app") && viewInMyPurchasesButton.visible)
|
||||||
enabled: (root.balanceAfterPurchase >= 0 && ownershipStatusReceived && balanceReceived) || (!root.isCertified);
|
enabled: (root.balanceAfterPurchase >= 0 && ownershipStatusReceived && balanceReceived && availableUpdatesReceived) || (!root.isCertified) || root.isUpdating;
|
||||||
color: viewInMyPurchasesButton.visible ? hifi.buttons.white : hifi.buttons.blue;
|
color: viewInMyPurchasesButton.visible ? hifi.buttons.white : hifi.buttons.blue;
|
||||||
colorScheme: hifi.colorSchemes.light;
|
colorScheme: hifi.colorSchemes.light;
|
||||||
anchors.top: viewInMyPurchasesButton.visible ? viewInMyPurchasesButton.bottom :
|
anchors.top: viewInMyPurchasesButton.visible ? viewInMyPurchasesButton.bottom :
|
||||||
|
@ -548,10 +603,19 @@ Rectangle {
|
||||||
height: 50;
|
height: 50;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
text: ((root.isCertified) ? ((ownershipStatusReceived && balanceReceived) ?
|
text: (root.isUpdating && root.itemEdition > 0) ? "CONFIRM UPDATE" : (((root.isCertified) ? ((ownershipStatusReceived && balanceReceived && availableUpdatesReceived) ?
|
||||||
(viewInMyPurchasesButton.visible ? "Buy It Again" : "Confirm Purchase") : "--") : "Get Item");
|
((viewInMyPurchasesButton.visible && !root.isUpdating) ? "Buy It Again" : "Confirm Purchase") : "--") : "Get Item"));
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (root.isCertified) {
|
if (root.isUpdating && root.itemEdition > 0) {
|
||||||
|
// If we're updating an app, the existing app needs to be uninstalled.
|
||||||
|
// This call will fail/return `false` if the app isn't installed, but that's OK.
|
||||||
|
if (root.itemType === "app") {
|
||||||
|
Commerce.uninstallApp(root.baseAppURL);
|
||||||
|
}
|
||||||
|
buyButton.enabled = false;
|
||||||
|
loading.visible = true;
|
||||||
|
Commerce.updateItem(root.certificateId);
|
||||||
|
} else if (root.isCertified) {
|
||||||
if (!root.shouldBuyWithControlledFailure) {
|
if (!root.shouldBuyWithControlledFailure) {
|
||||||
if (root.itemType === "contentSet" && !Entities.canReplaceContent()) {
|
if (root.itemType === "contentSet" && !Entities.canReplaceContent()) {
|
||||||
lightboxPopup.titleText = "Purchase Content Set";
|
lightboxPopup.titleText = "Purchase Content Set";
|
||||||
|
@ -975,7 +1039,7 @@ Rectangle {
|
||||||
buyButton.color = hifi.buttons.red;
|
buyButton.color = hifi.buttons.red;
|
||||||
root.shouldBuyWithControlledFailure = true;
|
root.shouldBuyWithControlledFailure = true;
|
||||||
} else {
|
} else {
|
||||||
buyButton.text = (root.isCertified ? ((ownershipStatusReceived && balanceReceived) ? (root.alreadyOwned ? "Buy Another" : "Buy"): "--") : "Get Item");
|
buyButton.text = (root.isCertified ? ((ownershipStatusReceived && balanceReceived && availableUpdatesReceived) ? (root.alreadyOwned ? "Buy Another" : "Buy"): "--") : "Get Item");
|
||||||
buyButton.color = hifi.buttons.blue;
|
buyButton.color = hifi.buttons.blue;
|
||||||
root.shouldBuyWithControlledFailure = false;
|
root.shouldBuyWithControlledFailure = false;
|
||||||
}
|
}
|
||||||
|
@ -1001,12 +1065,13 @@ Rectangle {
|
||||||
function fromScript(message) {
|
function fromScript(message) {
|
||||||
switch (message.method) {
|
switch (message.method) {
|
||||||
case 'updateCheckoutQML':
|
case 'updateCheckoutQML':
|
||||||
itemId = message.params.itemId;
|
root.itemId = message.params.itemId;
|
||||||
itemName = message.params.itemName;
|
root.itemName = message.params.itemName.trim();
|
||||||
root.itemPrice = message.params.itemPrice;
|
root.itemPrice = message.params.itemPrice;
|
||||||
itemHref = message.params.itemHref;
|
root.itemHref = message.params.itemHref;
|
||||||
referrer = message.params.referrer;
|
root.referrer = message.params.referrer;
|
||||||
itemAuthor = message.params.itemAuthor;
|
root.itemAuthor = message.params.itemAuthor;
|
||||||
|
root.itemEdition = message.params.itemEdition || -1;
|
||||||
refreshBuyUI();
|
refreshBuyUI();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1015,35 +1080,70 @@ Rectangle {
|
||||||
}
|
}
|
||||||
signal sendToScript(var message);
|
signal sendToScript(var message);
|
||||||
|
|
||||||
|
function canBuyAgain() {
|
||||||
|
return (root.itemType === "entity" || root.itemType === "wearable" || root.itemType === "contentSet" || root.itemType === "unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleContentSets() {
|
||||||
|
if (root.itemType === "contentSet" && !Entities.canReplaceContent()) {
|
||||||
|
buyText.text = "The domain owner must enable 'Replace Content' permissions for you in this " +
|
||||||
|
"<b>domain's server settings</b> before you can replace this domain's content with <b>" + root.itemName + "</b>";
|
||||||
|
buyTextContainer.color = "#FFC3CD";
|
||||||
|
buyTextContainer.border.color = "#F3808F";
|
||||||
|
buyGlyph.text = hifi.glyphs.alert;
|
||||||
|
buyGlyph.size = 54;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleBuyAgainLogic() {
|
||||||
|
// If you can buy this item again...
|
||||||
|
if (canBuyAgain()) {
|
||||||
|
// If you can't afford another copy of the item...
|
||||||
|
if (root.balanceAfterPurchase < 0) {
|
||||||
|
// If you already own the item...
|
||||||
|
if (root.alreadyOwned) {
|
||||||
|
buyText.text = "<b>Your Wallet does not have sufficient funds to purchase this item again.</b>";
|
||||||
|
// Else if you don't already own the item...
|
||||||
|
} else {
|
||||||
|
buyText.text = "<b>Your Wallet does not have sufficient funds to purchase this item.</b>";
|
||||||
|
}
|
||||||
|
buyTextContainer.color = "#FFC3CD";
|
||||||
|
buyTextContainer.border.color = "#F3808F";
|
||||||
|
buyGlyph.text = hifi.glyphs.alert;
|
||||||
|
buyGlyph.size = 54;
|
||||||
|
// If you CAN afford another copy of the item...
|
||||||
|
} else {
|
||||||
|
handleContentSets();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function refreshBuyUI() {
|
function refreshBuyUI() {
|
||||||
if (root.isCertified) {
|
if (root.isCertified) {
|
||||||
if (root.ownershipStatusReceived && root.balanceReceived) {
|
if (root.ownershipStatusReceived && root.balanceReceived && root.availableUpdatesReceived) {
|
||||||
if (root.balanceAfterPurchase < 0) {
|
buyText.text = "";
|
||||||
if (root.alreadyOwned) {
|
|
||||||
buyText.text = "<b>Your Wallet does not have sufficient funds to purchase this item again.</b>";
|
// If the user IS on the checkout page for the updated version of an owned item...
|
||||||
viewInMyPurchasesButton.visible = true;
|
if (root.isUpdating) {
|
||||||
|
// If the user HAS already selected a specific edition to update...
|
||||||
|
if (root.itemEdition > 0) {
|
||||||
|
buyText.text = "By pressing \"Confirm Update\", you agree to trade in your old item for the updated item that replaces it.";
|
||||||
|
buyTextContainer.color = "#FFFFFF";
|
||||||
|
buyTextContainer.border.color = "#FFFFFF";
|
||||||
|
// Else if the user HAS NOT selected a specific edition to update...
|
||||||
} else {
|
} else {
|
||||||
buyText.text = "<b>Your Wallet does not have sufficient funds to purchase this item.</b>";
|
viewInMyPurchasesButton.visible = true;
|
||||||
}
|
|
||||||
buyTextContainer.color = "#FFC3CD";
|
handleBuyAgainLogic();
|
||||||
buyTextContainer.border.color = "#F3808F";
|
}
|
||||||
buyGlyph.text = hifi.glyphs.alert;
|
// If the user IS NOT on the checkout page for the updated verison of an owned item...
|
||||||
buyGlyph.size = 54;
|
// (i.e. they are checking out an item "normally")
|
||||||
} else {
|
} else {
|
||||||
if (root.alreadyOwned) {
|
if (root.alreadyOwned) {
|
||||||
viewInMyPurchasesButton.visible = true;
|
viewInMyPurchasesButton.visible = true;
|
||||||
} else {
|
|
||||||
buyText.text = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (root.itemType === "contentSet" && !Entities.canReplaceContent()) {
|
|
||||||
buyText.text = "The domain owner must enable 'Replace Content' permissions for you in this " +
|
|
||||||
"<b>domain's server settings</b> before you can replace this domain's content with <b>" + root.itemName + "</b>";
|
|
||||||
buyTextContainer.color = "#FFC3CD";
|
|
||||||
buyTextContainer.border.color = "#F3808F";
|
|
||||||
buyGlyph.text = hifi.glyphs.alert;
|
|
||||||
buyGlyph.size = 54;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleBuyAgainLogic();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buyText.text = "";
|
buyText.text = "";
|
||||||
|
@ -1062,11 +1162,13 @@ Rectangle {
|
||||||
root.activeView = "checkoutMain";
|
root.activeView = "checkoutMain";
|
||||||
} else {
|
} else {
|
||||||
root.activeView = "checkoutSuccess";
|
root.activeView = "checkoutSuccess";
|
||||||
|
root.ownershipStatusReceived = false;
|
||||||
|
Commerce.alreadyOwned(root.itemId);
|
||||||
|
root.availableUpdatesReceived = false;
|
||||||
|
Commerce.getAvailableUpdates(root.itemId);
|
||||||
|
root.balanceReceived = false;
|
||||||
|
Commerce.balance();
|
||||||
}
|
}
|
||||||
root.balanceReceived = false;
|
|
||||||
root.ownershipStatusReceived = false;
|
|
||||||
Commerce.alreadyOwned(root.itemId);
|
|
||||||
Commerce.balance();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -28,6 +28,7 @@ Item {
|
||||||
property string referrerURL: (Account.metaverseServerURL + "/marketplace?");
|
property string referrerURL: (Account.metaverseServerURL + "/marketplace?");
|
||||||
readonly property int additionalDropdownHeight: usernameDropdown.height - myUsernameButton.anchors.bottomMargin;
|
readonly property int additionalDropdownHeight: usernameDropdown.height - myUsernameButton.anchors.bottomMargin;
|
||||||
property alias usernameDropdownVisible: usernameDropdown.visible;
|
property alias usernameDropdownVisible: usernameDropdown.visible;
|
||||||
|
property bool messagesWaiting: false;
|
||||||
|
|
||||||
height: mainContainer.height + additionalDropdownHeight;
|
height: mainContainer.height + additionalDropdownHeight;
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ Item {
|
||||||
if (walletStatus === 0) {
|
if (walletStatus === 0) {
|
||||||
sendToParent({method: "needsLogIn"});
|
sendToParent({method: "needsLogIn"});
|
||||||
} else if (walletStatus === 5) {
|
} else if (walletStatus === 5) {
|
||||||
|
Commerce.getAvailableUpdates();
|
||||||
Commerce.getSecurityImage();
|
Commerce.getSecurityImage();
|
||||||
} else if (walletStatus > 5) {
|
} else if (walletStatus > 5) {
|
||||||
console.log("ERROR in EmulatedMarketplaceHeader.qml: Unknown wallet status: " + walletStatus);
|
console.log("ERROR in EmulatedMarketplaceHeader.qml: Unknown wallet status: " + walletStatus);
|
||||||
|
@ -58,6 +60,14 @@ Item {
|
||||||
securityImage.source = "image://security/securityImage";
|
securityImage.source = "image://security/securityImage";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAvailableUpdatesResult: {
|
||||||
|
if (result.status !== 'success') {
|
||||||
|
console.log("Failed to get Available Updates", result.data.message);
|
||||||
|
} else {
|
||||||
|
root.messagesWaiting = result.data.updates.length > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
@ -134,13 +144,25 @@ Item {
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
hoverEnabled: enabled;
|
hoverEnabled: enabled;
|
||||||
onClicked: {
|
onClicked: {
|
||||||
sendToParent({method: 'header_goToPurchases'});
|
sendToParent({ method: 'header_goToPurchases', hasUpdates: root.messagesWaiting });
|
||||||
}
|
}
|
||||||
onEntered: myPurchasesText.color = hifi.colors.blueHighlight;
|
onEntered: myPurchasesText.color = hifi.colors.blueHighlight;
|
||||||
onExited: myPurchasesText.color = hifi.colors.blueAccent;
|
onExited: myPurchasesText.color = hifi.colors.blueAccent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: messagesWaitingLight;
|
||||||
|
visible: root.messagesWaiting;
|
||||||
|
anchors.right: myPurchasesLink.left;
|
||||||
|
anchors.rightMargin: -2;
|
||||||
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
height: 10;
|
||||||
|
width: height;
|
||||||
|
radius: height/2;
|
||||||
|
color: "red";
|
||||||
|
}
|
||||||
|
|
||||||
TextMetrics {
|
TextMetrics {
|
||||||
id: textMetrics;
|
id: textMetrics;
|
||||||
font.family: "Raleway"
|
font.family: "Raleway"
|
||||||
|
|
|
@ -48,11 +48,14 @@ Item {
|
||||||
property bool hasPermissionToRezThis;
|
property bool hasPermissionToRezThis;
|
||||||
property bool permissionExplanationCardVisible;
|
property bool permissionExplanationCardVisible;
|
||||||
property bool isInstalled;
|
property bool isInstalled;
|
||||||
|
property string upgradeUrl;
|
||||||
|
property string upgradeTitle;
|
||||||
|
property bool isShowingMyItems;
|
||||||
|
|
||||||
property string originalStatusText;
|
property string originalStatusText;
|
||||||
property string originalStatusColor;
|
property string originalStatusColor;
|
||||||
|
|
||||||
height: 110;
|
height: (root.upgradeUrl === "" || root.isShowingMyItems) ? 110 : 150;
|
||||||
width: parent.width;
|
width: parent.width;
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
@ -137,6 +140,14 @@ Item {
|
||||||
anchors.verticalCenter: parent.verticalCenter;
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
height: root.height - 10;
|
height: root.height - 10;
|
||||||
|
|
||||||
|
// START "incorrect indentation to prevent insane diffs"
|
||||||
|
Item {
|
||||||
|
id: itemContainer;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
height: 100;
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: itemPreviewImage;
|
id: itemPreviewImage;
|
||||||
source: root.itemPreviewImageUrl;
|
source: root.itemPreviewImageUrl;
|
||||||
|
@ -357,7 +368,7 @@ Item {
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: statusContainer;
|
id: statusContainer;
|
||||||
visible: root.purchaseStatus === "pending" || root.purchaseStatus === "invalidated" || root.purchaseStatusChanged;
|
visible: root.purchaseStatus === "pending" || root.purchaseStatus === "invalidated" || root.purchaseStatusChanged || root.numberSold > -1;
|
||||||
anchors.left: itemName.left;
|
anchors.left: itemName.left;
|
||||||
anchors.top: certificateContainer.bottom;
|
anchors.top: certificateContainer.bottom;
|
||||||
anchors.topMargin: 8;
|
anchors.topMargin: 8;
|
||||||
|
@ -376,7 +387,7 @@ Item {
|
||||||
"PENDING..."
|
"PENDING..."
|
||||||
} else if (root.purchaseStatus === "invalidated") {
|
} else if (root.purchaseStatus === "invalidated") {
|
||||||
"INVALIDATED"
|
"INVALIDATED"
|
||||||
} else if (root.numberSold !== -1) {
|
} else if (root.numberSold > -1) {
|
||||||
("Sales: " + root.numberSold + "/" + (root.limitedRun === -1 ? "\u221e" : root.limitedRun))
|
("Sales: " + root.numberSold + "/" + (root.limitedRun === -1 ? "\u221e" : root.limitedRun))
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
|
@ -634,6 +645,48 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// END "incorrect indentation to prevent insane diffs"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: upgradeAvailableContainer;
|
||||||
|
visible: root.upgradeUrl !== "" && !root.isShowingMyItems;
|
||||||
|
anchors.top: itemContainer.bottom;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
color: "#B5EAFF";
|
||||||
|
|
||||||
|
RalewayRegular {
|
||||||
|
id: updateAvailableText;
|
||||||
|
text: "UPDATE AVAILABLE";
|
||||||
|
size: 13;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.leftMargin: 12;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
width: paintedWidth;
|
||||||
|
color: hifi.colors.black;
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: updateNowText;
|
||||||
|
text: "<font color='#0093C5'><a href='#'>Update this item now</a></font>";
|
||||||
|
size: 13;
|
||||||
|
anchors.left: updateAvailableText.right;
|
||||||
|
anchors.leftMargin: 16;
|
||||||
|
anchors.top: parent.top;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
width: paintedWidth;
|
||||||
|
color: hifi.colors.black;
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
|
||||||
|
onLinkActivated: {
|
||||||
|
sendToPurchases({method: 'updateItemClicked', itemId: root.itemId, itemEdition: root.itemEdition, upgradeUrl: root.upgradeUrl});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DropShadow {
|
DropShadow {
|
||||||
|
|
|
@ -37,6 +37,8 @@ Rectangle {
|
||||||
property bool isDebuggingFirstUseTutorial: false;
|
property bool isDebuggingFirstUseTutorial: false;
|
||||||
property int pendingItemCount: 0;
|
property int pendingItemCount: 0;
|
||||||
property string installedApps;
|
property string installedApps;
|
||||||
|
property bool keyboardRaised: false;
|
||||||
|
property int numUpdatesAvailable: 0;
|
||||||
// Style
|
// Style
|
||||||
color: hifi.colors.white;
|
color: hifi.colors.white;
|
||||||
Connections {
|
Connections {
|
||||||
|
@ -64,6 +66,7 @@ Rectangle {
|
||||||
root.activeView = "purchasesMain";
|
root.activeView = "purchasesMain";
|
||||||
root.installedApps = Commerce.getInstalledApps();
|
root.installedApps = Commerce.getInstalledApps();
|
||||||
Commerce.inventory();
|
Commerce.inventory();
|
||||||
|
Commerce.getAvailableUpdates();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log("ERROR in Purchases.qml: Unknown wallet status: " + walletStatus);
|
console.log("ERROR in Purchases.qml: Unknown wallet status: " + walletStatus);
|
||||||
|
@ -119,6 +122,15 @@ Rectangle {
|
||||||
|
|
||||||
root.pendingInventoryReply = false;
|
root.pendingInventoryReply = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAvailableUpdatesResult: {
|
||||||
|
if (result.status !== 'success') {
|
||||||
|
console.log("Failed to get Available Updates", result.data.message);
|
||||||
|
} else {
|
||||||
|
sendToScript({method: 'purchases_availableUpdatesReceived', numUpdates: result.data.updates.length });
|
||||||
|
root.numUpdatesAvailable = result.data.updates.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
|
@ -273,6 +285,7 @@ Rectangle {
|
||||||
root.activeView = "purchasesMain";
|
root.activeView = "purchasesMain";
|
||||||
root.installedApps = Commerce.getInstalledApps();
|
root.installedApps = Commerce.getInstalledApps();
|
||||||
Commerce.inventory();
|
Commerce.inventory();
|
||||||
|
Commerce.getAvailableUpdates();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,6 +309,7 @@ Rectangle {
|
||||||
// FILTER BAR START
|
// FILTER BAR START
|
||||||
//
|
//
|
||||||
Item {
|
Item {
|
||||||
|
z: 997;
|
||||||
id: filterBarContainer;
|
id: filterBarContainer;
|
||||||
// Size
|
// Size
|
||||||
height: 40;
|
height: 40;
|
||||||
|
@ -321,28 +335,61 @@ Rectangle {
|
||||||
size: 22;
|
size: 22;
|
||||||
}
|
}
|
||||||
|
|
||||||
HifiControlsUit.TextField {
|
HifiControlsUit.FilterBar {
|
||||||
id: filterBar;
|
id: filterBar;
|
||||||
property string previousText: "";
|
property string previousText: "";
|
||||||
|
property string previousPrimaryFilter: "";
|
||||||
colorScheme: hifi.colorSchemes.faintGray;
|
colorScheme: hifi.colorSchemes.faintGray;
|
||||||
hasClearButton: true;
|
anchors.top: parent.top;
|
||||||
hasRoundedBorder: true;
|
anchors.right: parent.right;
|
||||||
anchors.left: myText.right;
|
anchors.left: myText.right;
|
||||||
anchors.leftMargin: 16;
|
anchors.leftMargin: 16;
|
||||||
height: 39;
|
textFieldHeight: 39;
|
||||||
anchors.verticalCenter: parent.verticalCenter;
|
height: textFieldHeight + dropdownHeight;
|
||||||
anchors.right: parent.right;
|
|
||||||
placeholderText: "filter items";
|
placeholderText: "filter items";
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
var choices = [
|
||||||
|
{
|
||||||
|
"displayName": "App",
|
||||||
|
"filterName": "app"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"displayName": "Avatar",
|
||||||
|
"filterName": "avatar"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"displayName": "Content Set",
|
||||||
|
"filterName": "contentSet"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"displayName": "Entity",
|
||||||
|
"filterName": "entity"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"displayName": "Wearable",
|
||||||
|
"filterName": "wearable"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"displayName": "Updatable",
|
||||||
|
"filterName": "updatable"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
filterBar.primaryFilterChoices.clear();
|
||||||
|
filterBar.primaryFilterChoices.append(choices);
|
||||||
|
}
|
||||||
|
|
||||||
|
onPrimaryFilter_displayNameChanged: {
|
||||||
|
buildFilteredPurchasesModel();
|
||||||
|
purchasesContentsList.positionViewAtIndex(0, ListView.Beginning)
|
||||||
|
filterBar.previousPrimaryFilter = filterBar.primaryFilter_displayName;
|
||||||
|
}
|
||||||
|
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
buildFilteredPurchasesModel();
|
buildFilteredPurchasesModel();
|
||||||
purchasesContentsList.positionViewAtIndex(0, ListView.Beginning)
|
purchasesContentsList.positionViewAtIndex(0, ListView.Beginning)
|
||||||
filterBar.previousText = filterBar.text;
|
filterBar.previousText = filterBar.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
onAccepted: {
|
|
||||||
focus = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -350,6 +397,7 @@ Rectangle {
|
||||||
//
|
//
|
||||||
|
|
||||||
HifiControlsUit.Separator {
|
HifiControlsUit.Separator {
|
||||||
|
z: 996;
|
||||||
id: separator;
|
id: separator;
|
||||||
colorScheme: 2;
|
colorScheme: 2;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
|
@ -377,12 +425,11 @@ Rectangle {
|
||||||
clip: true;
|
clip: true;
|
||||||
model: filteredPurchasesModel;
|
model: filteredPurchasesModel;
|
||||||
snapMode: ListView.SnapToItem;
|
snapMode: ListView.SnapToItem;
|
||||||
highlightRangeMode: ListView.StrictlyEnforceRange;
|
|
||||||
// Anchors
|
// Anchors
|
||||||
anchors.top: separator.bottom;
|
anchors.top: separator.bottom;
|
||||||
anchors.topMargin: 12;
|
anchors.topMargin: 12;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.bottom: parent.bottom;
|
anchors.bottom: updatesAvailableBanner.visible ? updatesAvailableBanner.top : parent.bottom;
|
||||||
width: parent.width;
|
width: parent.width;
|
||||||
delegate: PurchasedItem {
|
delegate: PurchasedItem {
|
||||||
itemName: title;
|
itemName: title;
|
||||||
|
@ -398,21 +445,10 @@ Rectangle {
|
||||||
displayedItemCount: model.displayedItemCount;
|
displayedItemCount: model.displayedItemCount;
|
||||||
permissionExplanationCardVisible: model.permissionExplanationCardVisible;
|
permissionExplanationCardVisible: model.permissionExplanationCardVisible;
|
||||||
isInstalled: model.isInstalled;
|
isInstalled: model.isInstalled;
|
||||||
itemType: {
|
upgradeUrl: model.upgrade_url;
|
||||||
if (model.root_file_url.indexOf(".fst") > -1) {
|
upgradeTitle: model.upgrade_title;
|
||||||
"avatar";
|
itemType: model.itemType;
|
||||||
} else if (model.categories.indexOf("Wearables") > -1) {
|
isShowingMyItems: root.isShowingMyItems;
|
||||||
"wearable";
|
|
||||||
} else if (model.root_file_url.endsWith('.json.gz')) {
|
|
||||||
"contentSet";
|
|
||||||
} else if (model.root_file_url.endsWith('.app.json')) {
|
|
||||||
"app";
|
|
||||||
} else if (model.root_file_url.endsWith('.json')) {
|
|
||||||
"entity";
|
|
||||||
} else {
|
|
||||||
"unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
anchors.topMargin: 10;
|
anchors.topMargin: 10;
|
||||||
anchors.bottomMargin: 10;
|
anchors.bottomMargin: 10;
|
||||||
|
|
||||||
|
@ -485,15 +521,80 @@ Rectangle {
|
||||||
filteredPurchasesModel.setProperty(i, "permissionExplanationCardVisible", true);
|
filteredPurchasesModel.setProperty(i, "permissionExplanationCardVisible", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (msg.method === "updateItemClicked") {
|
||||||
|
sendToScript(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: updatesAvailableBanner;
|
||||||
|
visible: root.numUpdatesAvailable > 0 && !root.isShowingMyItems;
|
||||||
|
anchors.bottom: parent.bottom;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
height: 75;
|
||||||
|
color: "#B5EAFF";
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: updatesAvailableGlyph;
|
||||||
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.leftMargin: 16;
|
||||||
|
// Size
|
||||||
|
width: 10;
|
||||||
|
height: width;
|
||||||
|
radius: width/2;
|
||||||
|
// Style
|
||||||
|
color: "red";
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
text: "You have " + root.numUpdatesAvailable + " item updates available.";
|
||||||
|
// Text size
|
||||||
|
size: 18;
|
||||||
|
// Anchors
|
||||||
|
anchors.left: updatesAvailableGlyph.right;
|
||||||
|
anchors.leftMargin: 12;
|
||||||
|
height: parent.height;
|
||||||
|
width: paintedWidth;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.black;
|
||||||
|
// Alignment
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent;
|
||||||
|
hoverEnabled: true;
|
||||||
|
propagateComposedEvents: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HifiControlsUit.Button {
|
||||||
|
color: hifi.buttons.white;
|
||||||
|
colorScheme: hifi.colorSchemes.dark;
|
||||||
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
anchors.rightMargin: 12;
|
||||||
|
width: 100;
|
||||||
|
height: 40;
|
||||||
|
text: "SHOW ME";
|
||||||
|
onClicked: {
|
||||||
|
filterBar.text = "";
|
||||||
|
filterBar.changeFilterByDisplayName("Updatable");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: noItemsAlertContainer;
|
id: noItemsAlertContainer;
|
||||||
visible: !purchasesContentsList.visible && root.purchasesReceived && root.isShowingMyItems && filterBar.text === "";
|
visible: !purchasesContentsList.visible &&
|
||||||
|
root.purchasesReceived &&
|
||||||
|
root.isShowingMyItems &&
|
||||||
|
filterBar.text === "" &&
|
||||||
|
filterBar.primaryFilter_displayName === "";
|
||||||
anchors.top: filterBarContainer.bottom;
|
anchors.top: filterBarContainer.bottom;
|
||||||
anchors.topMargin: 12;
|
anchors.topMargin: 12;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
|
@ -539,7 +640,11 @@ Rectangle {
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: noPurchasesAlertContainer;
|
id: noPurchasesAlertContainer;
|
||||||
visible: !purchasesContentsList.visible && root.purchasesReceived && !root.isShowingMyItems && filterBar.text === "";
|
visible: !purchasesContentsList.visible &&
|
||||||
|
root.purchasesReceived &&
|
||||||
|
!root.isShowingMyItems &&
|
||||||
|
filterBar.text === "" &&
|
||||||
|
filterBar.primaryFilter_displayName === "";
|
||||||
anchors.top: filterBarContainer.bottom;
|
anchors.top: filterBarContainer.bottom;
|
||||||
anchors.topMargin: 12;
|
anchors.topMargin: 12;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
|
@ -589,7 +694,7 @@ Rectangle {
|
||||||
|
|
||||||
HifiControlsUit.Keyboard {
|
HifiControlsUit.Keyboard {
|
||||||
id: keyboard;
|
id: keyboard;
|
||||||
raised: HMD.mounted && filterBar.focus;
|
raised: HMD.mounted && parent.keyboardRaised;
|
||||||
numeric: parent.punctuationMode;
|
numeric: parent.punctuationMode;
|
||||||
anchors {
|
anchors {
|
||||||
bottom: parent.bottom;
|
bottom: parent.bottom;
|
||||||
|
@ -613,6 +718,7 @@ Rectangle {
|
||||||
console.log("Refreshing Purchases...");
|
console.log("Refreshing Purchases...");
|
||||||
root.pendingInventoryReply = true;
|
root.pendingInventoryReply = true;
|
||||||
Commerce.inventory();
|
Commerce.inventory();
|
||||||
|
Commerce.getAvailableUpdates();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -660,8 +766,13 @@ Rectangle {
|
||||||
var sameItemCount = 0;
|
var sameItemCount = 0;
|
||||||
|
|
||||||
tempPurchasesModel.clear();
|
tempPurchasesModel.clear();
|
||||||
|
|
||||||
for (var i = 0; i < purchasesModel.count; i++) {
|
for (var i = 0; i < purchasesModel.count; i++) {
|
||||||
if (purchasesModel.get(i).title.toLowerCase().indexOf(filterBar.text.toLowerCase()) !== -1) {
|
if (purchasesModel.get(i).title.toLowerCase().indexOf(filterBar.text.toLowerCase()) !== -1) {
|
||||||
|
if (!purchasesModel.get(i).valid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (purchasesModel.get(i).status !== "confirmed" && !root.isShowingMyItems) {
|
if (purchasesModel.get(i).status !== "confirmed" && !root.isShowingMyItems) {
|
||||||
tempPurchasesModel.insert(0, purchasesModel.get(i));
|
tempPurchasesModel.insert(0, purchasesModel.get(i));
|
||||||
} else if ((root.isShowingMyItems && purchasesModel.get(i).edition_number === "0") ||
|
} else if ((root.isShowingMyItems && purchasesModel.get(i).edition_number === "0") ||
|
||||||
|
@ -671,6 +782,35 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// primaryFilter filtering and adding of itemType property to model
|
||||||
|
var currentItemType, currentRootFileUrl, currentCategories;
|
||||||
|
for (var i = 0; i < tempPurchasesModel.count; i++) {
|
||||||
|
currentRootFileUrl = tempPurchasesModel.get(i).root_file_url;
|
||||||
|
currentCategories = tempPurchasesModel.get(i).categories;
|
||||||
|
|
||||||
|
if (currentRootFileUrl.indexOf(".fst") > -1) {
|
||||||
|
currentItemType = "avatar";
|
||||||
|
} else if (currentCategories.indexOf("Wearables") > -1) {
|
||||||
|
currentItemType = "wearable";
|
||||||
|
} else if (currentRootFileUrl.endsWith('.json.gz')) {
|
||||||
|
currentItemType = "contentSet";
|
||||||
|
} else if (currentRootFileUrl.endsWith('.app.json')) {
|
||||||
|
currentItemType = "app";
|
||||||
|
} else if (currentRootFileUrl.endsWith('.json')) {
|
||||||
|
currentItemType = "entity";
|
||||||
|
} else {
|
||||||
|
currentItemType = "unknown";
|
||||||
|
}
|
||||||
|
if (filterBar.primaryFilter_displayName !== "" &&
|
||||||
|
((filterBar.primaryFilter_displayName === "Updatable" && tempPurchasesModel.get(i).upgrade_url === "") ||
|
||||||
|
(filterBar.primaryFilter_displayName !== "Updatable" && filterBar.primaryFilter_filterName.toLowerCase() !== currentItemType.toLowerCase()))) {
|
||||||
|
tempPurchasesModel.remove(i);
|
||||||
|
i--;
|
||||||
|
} else {
|
||||||
|
tempPurchasesModel.setProperty(i, 'itemType', currentItemType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (var i = 0; i < tempPurchasesModel.count; i++) {
|
for (var i = 0; i < tempPurchasesModel.count; i++) {
|
||||||
if (!filteredPurchasesModel.get(i)) {
|
if (!filteredPurchasesModel.get(i)) {
|
||||||
sameItemCount = -1;
|
sameItemCount = -1;
|
||||||
|
@ -682,12 +822,17 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sameItemCount !== tempPurchasesModel.count || filterBar.text !== filterBar.previousText) {
|
if (sameItemCount !== tempPurchasesModel.count ||
|
||||||
|
filterBar.text !== filterBar.previousText ||
|
||||||
|
filterBar.primaryFilter !== filterBar.previousPrimaryFilter) {
|
||||||
filteredPurchasesModel.clear();
|
filteredPurchasesModel.clear();
|
||||||
var currentId;
|
var currentId;
|
||||||
for (var i = 0; i < tempPurchasesModel.count; i++) {
|
for (var i = 0; i < tempPurchasesModel.count; i++) {
|
||||||
currentId = tempPurchasesModel.get(i).id;
|
currentId = tempPurchasesModel.get(i).id;
|
||||||
|
|
||||||
|
if (!purchasesModel.get(i).valid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
filteredPurchasesModel.append(tempPurchasesModel.get(i));
|
filteredPurchasesModel.append(tempPurchasesModel.get(i));
|
||||||
filteredPurchasesModel.setProperty(i, 'permissionExplanationCardVisible', false);
|
filteredPurchasesModel.setProperty(i, 'permissionExplanationCardVisible', false);
|
||||||
filteredPurchasesModel.setProperty(i, 'isInstalled', ((root.installedApps).indexOf(currentId) > -1));
|
filteredPurchasesModel.setProperty(i, 'isInstalled', ((root.installedApps).indexOf(currentId) > -1));
|
||||||
|
@ -736,7 +881,7 @@ Rectangle {
|
||||||
function fromScript(message) {
|
function fromScript(message) {
|
||||||
switch (message.method) {
|
switch (message.method) {
|
||||||
case 'updatePurchases':
|
case 'updatePurchases':
|
||||||
referrerURL = message.referrerURL;
|
referrerURL = message.referrerURL || "";
|
||||||
titleBarContainer.referrerURL = message.referrerURL;
|
titleBarContainer.referrerURL = message.referrerURL;
|
||||||
filterBar.text = message.filterText ? message.filterText : "";
|
filterBar.text = message.filterText ? message.filterText : "";
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -39,6 +39,7 @@ Item {
|
||||||
root.noMoreHistoryData = false;
|
root.noMoreHistoryData = false;
|
||||||
root.historyRequestPending = true;
|
root.historyRequestPending = true;
|
||||||
Commerce.history(root.currentHistoryPage);
|
Commerce.history(root.currentHistoryPage);
|
||||||
|
Commerce.getAvailableUpdates();
|
||||||
} else {
|
} else {
|
||||||
refreshTimer.stop();
|
refreshTimer.stop();
|
||||||
}
|
}
|
||||||
|
@ -133,6 +134,14 @@ Item {
|
||||||
refreshTimer.start();
|
refreshTimer.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAvailableUpdatesResult: {
|
||||||
|
if (result.status !== 'success') {
|
||||||
|
console.log("Failed to get Available Updates", result.data.message);
|
||||||
|
} else {
|
||||||
|
sendToScript({method: 'wallet_availableUpdatesReceived', numUpdates: result.data.updates.length });
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
|
|
@ -52,6 +52,8 @@ Handler(inventory)
|
||||||
Handler(transferHfcToNode)
|
Handler(transferHfcToNode)
|
||||||
Handler(transferHfcToUsername)
|
Handler(transferHfcToUsername)
|
||||||
Handler(alreadyOwned)
|
Handler(alreadyOwned)
|
||||||
|
Handler(availableUpdates)
|
||||||
|
Handler(updateItem)
|
||||||
|
|
||||||
void Ledger::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, QJsonObject request) {
|
void Ledger::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, QJsonObject request) {
|
||||||
auto accountManager = DependencyManager::get<AccountManager>();
|
auto accountManager = DependencyManager::get<AccountManager>();
|
||||||
|
@ -376,3 +378,23 @@ void Ledger::alreadyOwned(const QString& marketplaceId) {
|
||||||
qDebug(commerce) << "User attempted to use the alreadyOwned endpoint, but cachedPublicKeys was empty!";
|
qDebug(commerce) << "User attempted to use the alreadyOwned endpoint, but cachedPublicKeys was empty!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Ledger::getAvailableUpdates(const QString& itemId) {
|
||||||
|
auto wallet = DependencyManager::get<Wallet>();
|
||||||
|
QString endpoint = "available_updates";
|
||||||
|
QJsonObject request;
|
||||||
|
request["public_keys"] = QJsonArray::fromStringList(wallet->listPublicKeys());
|
||||||
|
if (!itemId.isEmpty()) {
|
||||||
|
request["marketplace_item_id"] = itemId;
|
||||||
|
}
|
||||||
|
send(endpoint, "availableUpdatesSuccess", "availableUpdatesFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::Required, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ledger::updateItem(const QString& hfc_key, const QString& certificate_id) {
|
||||||
|
QJsonObject transaction;
|
||||||
|
transaction["public_key"] = hfc_key;
|
||||||
|
transaction["certificate_id"] = certificate_id;
|
||||||
|
QJsonDocument transactionDoc{ transaction };
|
||||||
|
auto transactionString = transactionDoc.toJson(QJsonDocument::Compact);
|
||||||
|
signedSend("transaction", transactionString, hfc_key, "update_item", "updateItemSuccess", "updateItemFailure");
|
||||||
|
}
|
||||||
|
|
|
@ -36,6 +36,8 @@ public:
|
||||||
void transferHfcToNode(const QString& hfc_key, const QString& nodeID, const int& amount, const QString& optionalMessage);
|
void transferHfcToNode(const QString& hfc_key, const QString& nodeID, const int& amount, const QString& optionalMessage);
|
||||||
void transferHfcToUsername(const QString& hfc_key, const QString& username, const int& amount, const QString& optionalMessage);
|
void transferHfcToUsername(const QString& hfc_key, const QString& username, const int& amount, const QString& optionalMessage);
|
||||||
void alreadyOwned(const QString& marketplaceId);
|
void alreadyOwned(const QString& marketplaceId);
|
||||||
|
void getAvailableUpdates(const QString& itemId = "");
|
||||||
|
void updateItem(const QString& hfc_key, const QString& certificate_id);
|
||||||
|
|
||||||
enum CertificateStatus {
|
enum CertificateStatus {
|
||||||
CERTIFICATE_STATUS_UNKNOWN = 0,
|
CERTIFICATE_STATUS_UNKNOWN = 0,
|
||||||
|
@ -57,6 +59,8 @@ signals:
|
||||||
void transferHfcToNodeResult(QJsonObject result);
|
void transferHfcToNodeResult(QJsonObject result);
|
||||||
void transferHfcToUsernameResult(QJsonObject result);
|
void transferHfcToUsernameResult(QJsonObject result);
|
||||||
void alreadyOwnedResult(QJsonObject result);
|
void alreadyOwnedResult(QJsonObject result);
|
||||||
|
void availableUpdatesResult(QJsonObject result);
|
||||||
|
void updateItemResult(QJsonObject result);
|
||||||
|
|
||||||
void updateCertificateStatus(const QString& certID, uint certStatus);
|
void updateCertificateStatus(const QString& certID, uint certStatus);
|
||||||
|
|
||||||
|
@ -83,6 +87,10 @@ public slots:
|
||||||
void transferHfcToUsernameFailure(QNetworkReply& reply);
|
void transferHfcToUsernameFailure(QNetworkReply& reply);
|
||||||
void alreadyOwnedSuccess(QNetworkReply& reply);
|
void alreadyOwnedSuccess(QNetworkReply& reply);
|
||||||
void alreadyOwnedFailure(QNetworkReply& reply);
|
void alreadyOwnedFailure(QNetworkReply& reply);
|
||||||
|
void availableUpdatesSuccess(QNetworkReply& reply);
|
||||||
|
void availableUpdatesFailure(QNetworkReply& reply);
|
||||||
|
void updateItemSuccess(QNetworkReply& reply);
|
||||||
|
void updateItemFailure(QNetworkReply& reply);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QJsonObject apiResponse(const QString& label, QNetworkReply& reply);
|
QJsonObject apiResponse(const QString& label, QNetworkReply& reply);
|
||||||
|
|
|
@ -38,7 +38,8 @@ QmlCommerce::QmlCommerce() {
|
||||||
connect(ledger.data(), &Ledger::updateCertificateStatus, this, &QmlCommerce::updateCertificateStatus);
|
connect(ledger.data(), &Ledger::updateCertificateStatus, this, &QmlCommerce::updateCertificateStatus);
|
||||||
connect(ledger.data(), &Ledger::transferHfcToNodeResult, this, &QmlCommerce::transferHfcToNodeResult);
|
connect(ledger.data(), &Ledger::transferHfcToNodeResult, this, &QmlCommerce::transferHfcToNodeResult);
|
||||||
connect(ledger.data(), &Ledger::transferHfcToUsernameResult, this, &QmlCommerce::transferHfcToUsernameResult);
|
connect(ledger.data(), &Ledger::transferHfcToUsernameResult, this, &QmlCommerce::transferHfcToUsernameResult);
|
||||||
connect(ledger.data(), &Ledger::transferHfcToUsernameResult, this, &QmlCommerce::transferHfcToUsernameResult);
|
connect(ledger.data(), &Ledger::availableUpdatesResult, this, &QmlCommerce::availableUpdatesResult);
|
||||||
|
connect(ledger.data(), &Ledger::updateItemResult, this, &QmlCommerce::updateItemResult);
|
||||||
|
|
||||||
auto accountManager = DependencyManager::get<AccountManager>();
|
auto accountManager = DependencyManager::get<AccountManager>();
|
||||||
connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() {
|
connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() {
|
||||||
|
@ -349,3 +350,20 @@ bool QmlCommerce::openApp(const QString& itemHref) {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QmlCommerce::getAvailableUpdates(const QString& itemId) {
|
||||||
|
auto ledger = DependencyManager::get<Ledger>();
|
||||||
|
ledger->getAvailableUpdates(itemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlCommerce::updateItem(const QString& certificateId) {
|
||||||
|
auto ledger = DependencyManager::get<Ledger>();
|
||||||
|
auto wallet = DependencyManager::get<Wallet>();
|
||||||
|
QStringList keys = wallet->listPublicKeys();
|
||||||
|
if (keys.count() == 0) {
|
||||||
|
QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } };
|
||||||
|
return emit updateItemResult(result);
|
||||||
|
}
|
||||||
|
QString key = keys[0];
|
||||||
|
ledger->updateItem(key, certificateId);
|
||||||
|
}
|
||||||
|
|
|
@ -43,6 +43,8 @@ signals:
|
||||||
void accountResult(QJsonObject result);
|
void accountResult(QJsonObject result);
|
||||||
void certificateInfoResult(QJsonObject result);
|
void certificateInfoResult(QJsonObject result);
|
||||||
void alreadyOwnedResult(QJsonObject result);
|
void alreadyOwnedResult(QJsonObject result);
|
||||||
|
void availableUpdatesResult(QJsonObject result);
|
||||||
|
void updateItemResult(QJsonObject result);
|
||||||
|
|
||||||
void updateCertificateStatus(const QString& certID, uint certStatus);
|
void updateCertificateStatus(const QString& certID, uint certStatus);
|
||||||
|
|
||||||
|
@ -89,6 +91,9 @@ protected:
|
||||||
Q_INVOKABLE bool uninstallApp(const QString& appHref);
|
Q_INVOKABLE bool uninstallApp(const QString& appHref);
|
||||||
Q_INVOKABLE bool openApp(const QString& appHref);
|
Q_INVOKABLE bool openApp(const QString& appHref);
|
||||||
|
|
||||||
|
Q_INVOKABLE void getAvailableUpdates(const QString& itemId = "");
|
||||||
|
Q_INVOKABLE void updateItem(const QString& certificateId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString _appsPath;
|
QString _appsPath;
|
||||||
};
|
};
|
||||||
|
|
|
@ -698,6 +698,9 @@
|
||||||
Window.location = "hifi://BankOfHighFidelity";
|
Window.location = "hifi://BankOfHighFidelity";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'wallet_availableUpdatesReceived':
|
||||||
|
// NOP
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
print('Unrecognized message from QML:', JSON.stringify(message));
|
print('Unrecognized message from QML:', JSON.stringify(message));
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
var userIsLoggedIn = false;
|
var userIsLoggedIn = false;
|
||||||
var walletNeedsSetup = false;
|
var walletNeedsSetup = false;
|
||||||
var marketplaceBaseURL = "https://highfidelity.com";
|
var marketplaceBaseURL = "https://highfidelity.com";
|
||||||
|
var messagesWaiting = false;
|
||||||
|
|
||||||
function injectCommonCode(isDirectoryPage) {
|
function injectCommonCode(isDirectoryPage) {
|
||||||
|
|
||||||
|
@ -205,16 +206,22 @@
|
||||||
|
|
||||||
purchasesElement.id = "purchasesButton";
|
purchasesElement.id = "purchasesButton";
|
||||||
purchasesElement.setAttribute('href', "#");
|
purchasesElement.setAttribute('href', "#");
|
||||||
purchasesElement.innerHTML = "My Purchases";
|
purchasesElement.innerHTML = "";
|
||||||
|
if (messagesWaiting) {
|
||||||
|
purchasesElement.innerHTML += "<span style='width:10px;height:10px;background-color:red;border-radius:50%;display:inline-block;'></span> ";
|
||||||
|
}
|
||||||
|
purchasesElement.innerHTML += "My Purchases";
|
||||||
// FRONTEND WEBDEV RANT: The username dropdown should REALLY not be programmed to be on the same
|
// FRONTEND WEBDEV RANT: The username dropdown should REALLY not be programmed to be on the same
|
||||||
// line as the search bar, overlaid on top of the search bar, floated right, and then relatively bumped up using "top:-50px".
|
// line as the search bar, overlaid on top of the search bar, floated right, and then relatively bumped up using "top:-50px".
|
||||||
|
$('.navbar-brand').css('margin-right', '10px');
|
||||||
purchasesElement.style = "height:100%;margin-top:18px;font-weight:bold;float:right;margin-right:" + (dropDownElement.offsetWidth + 30) +
|
purchasesElement.style = "height:100%;margin-top:18px;font-weight:bold;float:right;margin-right:" + (dropDownElement.offsetWidth + 30) +
|
||||||
"px;position:relative;z-index:999;";
|
"px;position:relative;z-index:999;";
|
||||||
navbarBrandElement.parentNode.insertAdjacentElement('beforeend', purchasesElement);
|
navbarBrandElement.parentNode.insertAdjacentElement('beforeend', purchasesElement);
|
||||||
$('#purchasesButton').on('click', function () {
|
$('#purchasesButton').on('click', function () {
|
||||||
EventBridge.emitWebEvent(JSON.stringify({
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
type: "PURCHASES",
|
type: "PURCHASES",
|
||||||
referrerURL: window.location.href
|
referrerURL: window.location.href,
|
||||||
|
hasUpdates: messagesWaiting
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -243,7 +250,7 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function buyButtonClicked(id, name, author, price, href, referrer) {
|
function buyButtonClicked(id, name, author, price, href, referrer, edition) {
|
||||||
EventBridge.emitWebEvent(JSON.stringify({
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
type: "CHECKOUT",
|
type: "CHECKOUT",
|
||||||
itemId: id,
|
itemId: id,
|
||||||
|
@ -251,7 +258,8 @@
|
||||||
itemPrice: price ? parseInt(price, 10) : 0,
|
itemPrice: price ? parseInt(price, 10) : 0,
|
||||||
itemHref: href,
|
itemHref: href,
|
||||||
referrer: referrer,
|
referrer: referrer,
|
||||||
itemAuthor: author
|
itemAuthor: author,
|
||||||
|
itemEdition: edition
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,7 +327,8 @@
|
||||||
$(this).closest('.grid-item').find('.creator').find('.value').text(),
|
$(this).closest('.grid-item').find('.creator').find('.value').text(),
|
||||||
$(this).closest('.grid-item').find('.item-cost').text(),
|
$(this).closest('.grid-item').find('.item-cost').text(),
|
||||||
$(this).attr('data-href'),
|
$(this).attr('data-href'),
|
||||||
"mainPage");
|
"mainPage",
|
||||||
|
-1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,7 +419,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
var cost = $('.item-cost').text();
|
var cost = $('.item-cost').text();
|
||||||
if (availability !== 'available') {
|
var isUpdating = window.location.href.indexOf('edition=') > -1;
|
||||||
|
var urlParams = new URLSearchParams(window.location.search);
|
||||||
|
if (isUpdating) {
|
||||||
|
purchaseButton.html('UPDATE FOR FREE');
|
||||||
|
} else if (availability !== 'available') {
|
||||||
purchaseButton.html('UNAVAILABLE (' + availability + ')');
|
purchaseButton.html('UNAVAILABLE (' + availability + ')');
|
||||||
} else if (parseInt(cost) > 0 && $('#side-info').find('#buyItemButton').size() === 0) {
|
} else if (parseInt(cost) > 0 && $('#side-info').find('#buyItemButton').size() === 0) {
|
||||||
purchaseButton.html('PURCHASE <span class="hifi-glyph hifi-glyph-hfc" style="filter:invert(1);background-size:20px;' +
|
purchaseButton.html('PURCHASE <span class="hifi-glyph hifi-glyph-hfc" style="filter:invert(1);background-size:20px;' +
|
||||||
|
@ -418,13 +431,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
purchaseButton.on('click', function () {
|
purchaseButton.on('click', function () {
|
||||||
if ('available' === availability) {
|
if ('available' === availability || isUpdating) {
|
||||||
buyButtonClicked(window.location.pathname.split("/")[3],
|
buyButtonClicked(window.location.pathname.split("/")[3],
|
||||||
$('#top-center').find('h1').text(),
|
$('#top-center').find('h1').text(),
|
||||||
$('#creator').find('.value').text(),
|
$('#creator').find('.value').text(),
|
||||||
cost,
|
cost,
|
||||||
href,
|
href,
|
||||||
"itemPage");
|
"itemPage",
|
||||||
|
urlParams.get('edition'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
maybeAddPurchasesButton();
|
maybeAddPurchasesButton();
|
||||||
|
@ -698,6 +712,7 @@
|
||||||
if (marketplaceBaseURL.indexOf('metaverse.') !== -1) {
|
if (marketplaceBaseURL.indexOf('metaverse.') !== -1) {
|
||||||
marketplaceBaseURL = marketplaceBaseURL.replace('metaverse.', '');
|
marketplaceBaseURL = marketplaceBaseURL.replace('metaverse.', '');
|
||||||
}
|
}
|
||||||
|
messagesWaiting = parsedJsonMessage.data.messagesWaiting;
|
||||||
injectCode();
|
injectCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,13 +87,24 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||||
|
var NORMAL_ICON = "icons/tablet-icons/market-i.svg";
|
||||||
|
var NORMAL_ACTIVE = "icons/tablet-icons/market-a.svg";
|
||||||
|
var WAITING_ICON = "icons/tablet-icons/market-i-msg.svg";
|
||||||
|
var WAITING_ACTIVE = "icons/tablet-icons/market-a-msg.svg";
|
||||||
var marketplaceButton = tablet.addButton({
|
var marketplaceButton = tablet.addButton({
|
||||||
icon: "icons/tablet-icons/market-i.svg",
|
icon: NORMAL_ICON,
|
||||||
activeIcon: "icons/tablet-icons/market-a.svg",
|
activeIcon: NORMAL_ACTIVE,
|
||||||
text: "MARKET",
|
text: "MARKET",
|
||||||
sortOrder: 9
|
sortOrder: 9
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function messagesWaiting(isWaiting) {
|
||||||
|
marketplaceButton.editProperties({
|
||||||
|
icon: (isWaiting ? WAITING_ICON : NORMAL_ICON),
|
||||||
|
activeIcon: (isWaiting ? WAITING_ACTIVE : NORMAL_ACTIVE)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function onCanWriteAssetsChanged() {
|
function onCanWriteAssetsChanged() {
|
||||||
var message = CAN_WRITE_ASSETS + " " + Entities.canWriteAssets();
|
var message = CAN_WRITE_ASSETS + " " + Entities.canWriteAssets();
|
||||||
tablet.emitScriptEvent(message);
|
tablet.emitScriptEvent(message);
|
||||||
|
@ -198,6 +209,7 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var userHasUpdates = false;
|
||||||
function sendCommerceSettings() {
|
function sendCommerceSettings() {
|
||||||
tablet.emitScriptEvent(JSON.stringify({
|
tablet.emitScriptEvent(JSON.stringify({
|
||||||
type: "marketplaces",
|
type: "marketplaces",
|
||||||
|
@ -206,7 +218,8 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
||||||
commerceMode: Settings.getValue("commerce", true),
|
commerceMode: Settings.getValue("commerce", true),
|
||||||
userIsLoggedIn: Account.loggedIn,
|
userIsLoggedIn: Account.loggedIn,
|
||||||
walletNeedsSetup: Wallet.walletStatus === 1,
|
walletNeedsSetup: Wallet.walletStatus === 1,
|
||||||
metaverseServerURL: Account.metaverseServerURL
|
metaverseServerURL: Account.metaverseServerURL,
|
||||||
|
messagesWaiting: userHasUpdates
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -583,6 +596,10 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
||||||
case 'purchases_goToMarketplaceClicked':
|
case 'purchases_goToMarketplaceClicked':
|
||||||
tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
|
tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||||
break;
|
break;
|
||||||
|
case 'updateItemClicked':
|
||||||
|
tablet.gotoWebScreen(message.upgradeUrl + "?edition=" + message.itemEdition,
|
||||||
|
MARKETPLACES_INJECT_SCRIPT_URL);
|
||||||
|
break;
|
||||||
case 'passphrasePopup_cancelClicked':
|
case 'passphrasePopup_cancelClicked':
|
||||||
case 'needsLogIn_cancelClicked':
|
case 'needsLogIn_cancelClicked':
|
||||||
tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
|
tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||||
|
@ -637,6 +654,11 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
||||||
case 'sendMoney_sendPublicly':
|
case 'sendMoney_sendPublicly':
|
||||||
// NOP
|
// NOP
|
||||||
break;
|
break;
|
||||||
|
case 'wallet_availableUpdatesReceived':
|
||||||
|
case 'purchases_availableUpdatesReceived':
|
||||||
|
userHasUpdates = message.numUpdates > 0;
|
||||||
|
messagesWaiting(userHasUpdates);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
print('Unrecognized message from Checkout.qml or Purchases.qml: ' + JSON.stringify(message));
|
print('Unrecognized message from Checkout.qml or Purchases.qml: ' + JSON.stringify(message));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue