Commerce: Gifts
|
@ -25,7 +25,6 @@
|
|||
<glyph glyph-name="web" unicode="q" d="M438 390c0 8-6 15-14 15l-333 0c-8 0-15-7-15-15l0-298c0-8 7-14 15-14l333 0c8 0 14 6 14 14z m-219-8l172 0c8 0 15-7 15-16 0-9-7-16-15-16l-172 0c-8 0-15 7-15 16 0 9 7 16 15 16z m-47 1c9 0 16-7 16-16 0-10-7-17-16-17-10 0-17 7-17 17 0 9 7 16 17 16z m-51 0c9 0 17-7 17-16 0-10-8-17-17-17-9 0-17 7-17 17 0 9 8 16 17 16z m291-276l-308 0 0 219 308 0z m-250 84l-15 0-20 60 13 0 14-45 15 45 13 0 15-45 14 45 13 0-20-60-14 0-14 41z m137 25l-46 0c0-5 2-8 6-11 3-2 8-4 12-4 8 0 13 3 17 7l7-8c-6-6-14-9-25-9-8 0-15 2-21 8-6 5-9 13-9 22 0 9 3 17 9 22 6 6 13 9 21 9 8 0 15-3 21-8 6-5 8-11 8-20z m-46 9l34 0c0 5-2 9-5 12-3 3-7 4-11 4-5 0-9-1-13-4-3-3-5-7-5-12z m101 27c8 0 14-3 20-9 6-5 9-12 9-22 0-9-3-16-9-22-5-6-12-8-19-8-8 0-15 3-21 9l0-9-12 0 0 83 12 0 0-34c5 8 12 12 20 12z m-20-31c0-6 2-10 5-14 4-4 8-5 13-5 5 0 9 1 13 5 3 4 5 8 5 14 0 6-2 10-5 14-4 4-8 6-13 6-5 0-9-2-13-6-3-4-5-8-5-14z"/>
|
||||
<glyph glyph-name="web-2" unicode="r" d="M438 390c0 8-6 15-14 15l-333 0c-8 0-15-7-15-15l0-298c0-8 7-14 15-14l333 0c8 0 14 6 14 14z m-219-8l172 0c8 0 15-7 15-16 0-9-7-16-15-16l-172 0c-8 0-15 7-15 16 0 9 7 16 15 16z m-47 1c9 0 16-7 16-16 0-10-7-17-16-17-10 0-17 7-17 17 0 9 7 16 17 16z m-51 0c9 0 17-7 17-16 0-10-8-17-17-17-9 0-17 7-17 17 0 9 8 16 17 16z m291-276l-308 0 0 219 308 0z"/>
|
||||
<glyph glyph-name="edit" unicode="s" d="M196 214c-27-27-54-54-81-81-6 6-13 13-19 19 27 27 54 54 81 81l-22 21c-31-31-61-62-92-92-7-7-11-13-12-22-3-25-7-50-11-76 3 0 4 0 6 0 24 5 48 10 72 15 5 1 10 4 13 7 32 32 64 64 96 96z m126 207c10 10 21 21 33 32 4 4 10 4 14 0 19-19 38-38 57-57 4-5 4-10 0-15-11-11-22-22-34-33-23 24-46 48-70 73z m23-181c-5-1-8 0-11 3-8 8-15 15-23 23 18 18 37 37 55 55 2 2 4 4 4 4-24 25-47 49-71 74-2-2-3-4-5-6-18-18-37-37-55-55-34 34-67 67-101 101-2 2-5 5-8 7-18 14-42 12-57-5-15-17-14-42 2-58 50-51 101-101 151-151 17-16 33-33 50-49 2-3 3-5 2-8-2-8-4-15-4-23-4-48 27-90 73-102 20-5 39-4 58 4-1 2-3 3-5 4-14 14-28 28-42 42-10 11-11 26-2 36 8 8 16 16 24 24 11 10 24 10 35 0 2-1 4-4 6-6 15-14 29-28 43-42 0 0 1 0 2 1 1 8 3 16 4 24 7 69-59 123-125 103z m-243 162c-7 0-14 6-14 14 0 8 6 14 14 14 8 0 15-6 15-14 0-7-7-14-15-14z m198-46c6-6 13-12 19-19-13-13-26-26-39-39-7 6-13 12-20 19 14 13 27 26 40 39z"/>
|
||||
<glyph glyph-name="market" unicode="t" d="M88 370c3 0 7 0 10 0 6 0 11-1 15-2 9-2 16-8 20-16 3-5 4-10 6-15 2-6 3-13 5-19 3-10 5-19 8-27 2-6 3-13 5-19 3-7 5-15 7-23 3-9 6-19 9-30 0-2 1-4 1-6 2-8 5-17 9-24 3-7 8-12 13-15 6-3 13-5 22-6 2 0 5 0 7 0l21 0 57 0c25 0 50 0 75 0 12 0 25 0 37 0 1 0 1 0 2 0 6 0 13 0 17 2 5 3 7 9 9 16l3 10c0 0 0 0 0 0 0 2 1 3 1 3 5 20 11 40 17 60 1 4 2 9 4 13 2 8 4 16 7 24 2 7 4 16 0 22-3 4-9 5-14 5-6 0-188-2-284-4l-4 0-5 22c0 3-1 6-2 9 0 3-1 5-1 7-1 2-1 3-1 4-1 4-2 7-3 11-2 6-6 12-11 17-5 5-11 8-17 9-3 1-6 1-10 1-5 1-9 1-14 1-19 0-38 0-59 0-1 0-3 0-4 0-3 0-7 0-10-1-3 0-6-2-8-4-3-5-4-11-2-17 2-5 6-6 9-7 4-1 8-1 13-1 5 0 10 0 16 0l16 0c3 0 5 0 8 0z m353-78l-26-92-6-4-2 0c-2 0-21 0-55 0-50 0-118-1-125-1l-1-1 0 0c-6 0-12 2-16 6-4 4-6 10-8 16-3 12-6 25-10 39-1 4-2 8-3 12-2 4-3 8-4 13l-4 12z m-194-164c-9 0-15-2-20-7-5-5-8-11-8-20 0-8 3-16 8-21 5-5 13-8 20-8 17 0 30 12 30 28 0 8-3 15-9 20-5 6-12 8-21 8z m139 0c-9 0-16-2-21-6-5-6-8-13-8-21 0-9 3-16 8-21 5-6 12-8 21-8 16 0 29 13 29 29 0 8-3 14-8 20-5 5-13 7-21 7z"/>
|
||||
<glyph glyph-name="directory" unicode="u" d="M432 451l-99-38c-2 0-3-1-4-1-3 1-5 2-8 2l-116 38c-8 3-15 6-30-1l-91-35c-17-5-32-16-32-31l0-303c0-15 14-27 32-27l99 38c3 1 6 2 9 4 1-1 3-2 4-2 3-1 5-2 7-3 0 0 1 0 1-1 0 0 1 0 1 0l116-38 0 0c8-1 12-1 21 3l90 34c13 6 32 16 32 31l0 304c0 14-14 26-32 26z m-351-371c-1 0-1 1-1 2l0 303c0 2 5 6 14 9l1 0 1 1 89 34c1-1 0-1 0-2l0-303c0-1-3-4-16-10z m356 42c-1-2-5-5-17-11l-90-34c0 1-1 1-1 2l0 304c0 1 5 5 14 8l1 0 1 1 91 34c0 0 1-1 1-1z"/>
|
||||
<glyph glyph-name="menu" unicode="v" d="M257 22c-60 0-119 22-164 67-44 44-68 102-68 164 0 62 24 120 68 163 90 91 237 91 327 0 44-43 68-101 68-163 0-62-24-120-68-164-45-45-104-67-163-67z m0 431c-52 0-103-20-142-59-38-38-58-88-58-141 0-54 20-104 58-142 78-78 205-78 283 0 38 38 59 88 59 142 0 53-21 103-59 141-39 39-90 59-141 59z m101-133l-203 0c-8 0-15 7-15 15 0 8 7 15 15 15l203 0c8 0 14-7 14-15 0-8-6-15-14-15z m0-84l-203 0c-8 0-15 7-15 15 0 8 7 15 15 15l203 0c8 0 14-7 14-15 0-8-6-15-14-15z m0-81l-203 0c-8 0-15 7-15 15 0 8 7 14 15 14l203 0c8 0 14-6 14-14 0-8-6-15-14-15z"/>
|
||||
<glyph glyph-name="close" unicode="w" d="M258 19c-59 0-118 23-163 68-44 43-68 101-68 163 0 62 24 120 68 164 90 90 237 90 327 0 44-44 68-102 68-164 0-62-24-120-68-163-45-45-104-68-164-68z m0 431c-51 0-102-19-141-58-38-38-59-88-59-142 0-53 21-103 59-141 78-78 205-78 283 0 38 38 58 88 58 141 0 54-20 104-58 142-39 39-90 58-142 58z m25-200l67 67c7 7 7 18 0 25-7 7-18 7-25 0l-67-67-66 67c-7 7-18 7-25 0-7-7-7-18 0-25l66-67-66-66c-7-7-7-18 0-25 7-7 18-7 25 0l66 66 67-66c7-7 18-7 25 0 7 7 7 18 0 25z"/>
|
||||
|
@ -145,4 +144,14 @@
|
|||
<glyph glyph-name="rez" unicode="" d="M373 321c-2 5-6 8-11 8l-49 8 55 61c4 4 5 9 3 14-2 5-7 8-12 8 0 0 0 0 0 0l-114-1c-5-1-10-4-12-9l-54-136c-1-4-1-8 1-11 2-4 6-6 9-7l38-5-54-136c-2-6 0-13 6-16 2-1 4-2 7-2 3 0 7 2 10 5l175 206c3 4 3 9 2 13z"/>
|
||||
<glyph glyph-name="keyboard-collapse" unicode="" d="M373 249l-26 0 0 25 26 0z m-35 0l-27 0 0 25 27 0z m-36 0l-27 0 0 25 27 0z m-36 0l-26 0 0 25 26 0z m-35 0l-27 0 0 25 27 0z m-36 0l-27 0 0 25 27 0z m-36 0l-26 0 0 25 26 0z m224-1l18 0c7 0 13 6 13 13 0 7-6 13-13 13l-18 0m-262 0l-17 0c-7 0-13-6-13-13 0-7 6-13 13-13l17 0m252 39l-31 0 0 25 31 0z m-42 0l-31 0 0 25 31 0z m-41 0l-32 0 0 25 32 0z m-42 0l-32 0 0 25 32 0z m-42 0l-32 0 0 25 32 0z m-41 0l-32 0 0 25 32 0z m218-1l18 0c7 0 13 6 13 13 0 8-6 14-13 14l-18 0m-262 0l-17 0c-7 0-13-6-13-14 0-7 6-13 13-13l17 0m288-124l-315 0c-33 0-59 28-59 61l0 76c0 34 26 61 59 61l315 0c33 0 59-27 59-61l0-76c1-33-26-61-59-61z m-315 172c-18 0-33-16-33-34l0-77c0-19 15-34 33-34l315 0c18 0 33 15 33 34l0 77c0 19-15 34-33 34z m248-99l32 0 0-25-32 0z m-41 0l31 0 0-25-31 0z m-42 0l31 0 0-25-31 0z m-43 0l32 0 0-25-32 0z m-42 0l32 0 0-25-32 0z m-41 0l31 0 0-25-31 0z m250-26l18 0c7 0 13 6 13 14 0 7-6 13-13 13l-18 0m-262 0l-17 0c-7 0-13-6-13-13 0-8 6-13 13-13l17 0m81-82l50-50 53 54-107 0"/>
|
||||
<glyph glyph-name="image" unicode="" d="M257 428c52 0 104 0 156 0 24 0 37-13 37-37 1-90 1-179 0-269 0-25-13-38-39-38-103 0-207 0-311 0-26 0-39 13-39 40 0 88 0 176 0 263 0 28 13 41 41 41 51 0 103 0 155 0z m167-263c0 7 0 10 0 14 0 69 0 138 0 206 0 17 0 17-17 17-101 0-202 0-303 0-16 0-17-1-17-17 0-58 0-115 0-173 0-3 0-7 0-12 8 3 14 6 19 9 17 8 30 7 44-6 5-5 10-10 15-15 5-7 11-8 19-4 40 21 81 41 121 61 19 10 31 8 46-7 9-9 18-18 27-27 15-15 29-29 46-46z m-328-54c7 0 11-1 15-1 98 0 197 0 296 0 6 0 14 2 16 6 5 7 0 14-6 20-27 26-54 53-80 80-8 9-15 9-26 4-67-35-135-68-203-102-3-2-6-4-12-7z m-8 26c21 10 40 20 63 31-8 7-14 12-20 17-2 2-7 3-10 3-30-9-36-17-34-48 0 0 0-1 1-3z m134 169c1-25-21-46-46-46-25-1-46 20-47 46 0 25 21 46 47 47 25 0 46-21 46-47z m-46 22c-12 0-22-9-22-21 0-13 9-22 21-23 13 0 23 9 23 22 0 13-10 22-22 22z"/>
|
||||
<glyph glyph-name="environments" unicode="" d="M256 454c-110 0-199-89-199-199 0-110 89-199 199-199 0 0 0 0 0 0l2-1 0 1c109 1 197 90 197 199 0 110-89 199-199 199z m114-204l0 0 0 5c0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 2l0 4 0 0c-1 22-4 43-10 63 21 5 36 11 46 15 15-26 24-56 24-87 0-30-8-59-23-85-8 4-23 11-47 16 6 21 9 42 10 64z m-19 102c-13 30-30 53-46 69 34-10 64-30 86-57-9-4-22-8-40-12z m-6-95c0-23-4-45-11-66-20 4-42 6-65 6l0 120c23 1 45 3 66 6 6-21 10-43 10-66z m-46-170c17 17 37 41 52 75 20-5 34-10 42-13-24-31-57-53-94-62z m-30 256l0 77c17-14 40-37 56-73-17-2-36-4-56-4z m0-248l0 77c20-1 39-3 56-5-16-35-40-59-56-72z m-83 252c17 35 40 59 56 73l0-77c-19 0-38 1-56 4z m-19-90c0 23 4 45 10 65 20-3 42-5 65-5l0-120c-23 0-45-1-65-4-6 20-10 42-10 64z m-47 106c22 28 52 48 86 58-15-16-33-39-46-70-18 4-31 8-40 12z m40-199c15-36 37-61 53-77-38 10-72 32-96 64 9 4 24 9 43 13z m82 8l0-77c-16 13-39 37-56 73 18 2 37 3 56 4z m-100 92l-1 0 0-4c0-1 0-1 0-2 0 0 0 0 0-1 0 0 0 0 0-1 0 0 0-1 0-1l0-5 1 0c0-21 4-42 10-62-23-5-39-10-49-15-14 25-21 53-21 82 0 30 8 60 23 86 10-4 25-10 47-14-6-20-10-41-10-63z"/>
|
||||
<glyph glyph-name="wand" unicode="" d="M438 107l-80 78c-5 5-12 7-18 6l-77 78c-5 5-14 5-19 0-5-5-6-14 0-19l77-79c0-6 2-12 7-17l80-78c5-4 10-6 15-6 6 0 12 2 16 6 8 9 8 22-1 31z m-185 209l-28 0 0 27c0 6-5 11-12 11-6 0-11-5-11-11l0-27-27 0c-6 0-11-5-11-12 0-6 5-11 11-11l27 0 0-28c0-6 5-11 11-11 7 0 12 5 12 11l0 28 28 0c6 0 11 5 11 11 0 7-5 12-11 12z m51-22c-6 0-10 4-10 10 0 5 4 10 10 10 15 0 31 0 45 0 6 0 10-5 10-10 0-6-4-10-10-10-14 0-30 0-45 0 0 0 0 0 0 0z m-184 0c0 0 0 0 0 0-12 0-26 0-40 0 0 0 0 0 0 0-5 0-10 4-10 10 0 5 5 10 10 10 14 0 28 0 41 0 5 0 10-5 10-10-1-6-5-10-11-10z m94-129c-5 0-10 4-10 9 0 14 0 26 0 40 0 5 5 9 10 9 0 0 0 0 0 0 6 0 10-5 10-10 0-13 0-25 0-38 0-6-4-10-10-10 0 0 0 0 0 0z m0 223c-5 0-10 4-10 9 0 14 0 26 0 40 0 5 5 9 10 9 6 0 10-5 10-10 0-13 0-25 0-38 0-6-4-10-10-10 0 0 0 0 0 0z m-68-26c-2 0-4 0-6 2-6 5-11 10-16 15-4 5-8 9-12 13-4 4-5 10-1 14 4 4 10 4 14 1 5-5 9-9 14-14 4-5 9-10 14-14 4-4 4-10 1-14-2-2-5-3-8-3z m-24-159c-3 0-5 1-7 3-4 3-4 10-1 14 5 5 9 10 14 14 5 4 9 8 12 12 4 4 10 5 14 1 4-4 5-10 1-14-4-5-9-10-13-14-5-4-9-8-13-12-2-2-4-4-7-4z m157 157c-3 0-5 1-6 2-5 3-6 10-2 14 4 6 10 11 15 16 5 4 10 8 13 12 3 5 10 6 14 2 4-3 5-9 2-14-5-6-10-10-15-15-5-4-10-8-13-13-2-2-5-4-8-4z"/>
|
||||
<glyph glyph-name="market" unicode="t" d="M428 332c-2 4-7 7-12 7-5 1-10 1-14 1-5 0-10 1-15 1-27 1-51 2-75 3-23 1-47 2-74 3-10 0-18 1-27 1-9 0-18 1-27 1l-1 0 0 1c-2 8-8 26-12 39-2 5-3 9-4 12-2 8-7 12-16 12l-48 0c-9 0-16-6-16-15 0-8 7-14 16-14l32 0c5 0 7-3 8-7l0 0c6-25 13-51 19-76 7-24 13-50 19-75 2-9 3-16 0-24-1-4-2-9-3-14-1-4-2-9-3-14-2-8-2-14 1-17 3-4 8-6 16-6l190 0c4 1 7 3 9 6 3 3 4 8 3 12-1 8-7 12-17 12l-170 0 1 1c0 1 1 4 1 6 2 7 5 17 4 20l0 1c1 6 5 10 12 10 8 0 16 0 24 0 43 2 87 3 128 5 8 1 12 4 15 10 8 15 29 65 36 86l0 0c3 4 3 8 0 12z m-45-224c0-16-13-30-29-30-16 0-29 13-29 30 0 15 13 30 29 30 16-1 29-15 29-30z m-177 1c0-16-14-29-29-29-16 0-29 14-29 29 0 17 13 30 29 30 16-1 29-14 29-30z"/>
|
||||
<glyph glyph-name="wear" unicode="" d="M451 180c3 1 5 4 6 7 1 3 1 7-1 10-2 3-4 5-8 6-3 1-6 1-10-1-6-4-13-5-19-6-3-1-6-1-7-1-1 0-1 0-1 0l-1 0-26 0 0 66c0 9-3 43-27 73-24 29-58 44-101 44-54 0-84-24-100-44-24-30-26-64-27-73l0-66-17 0c-2 0-4 0-8 1-8 1-17 3-27 7-7 3-14-1-17-7-2-7 1-14 8-17 14-6 27-8 33-9 3 0 6 0 8-1 1 0 1 0 2 0l299 0c1 0 2 0 3 0l0 0c2 1 6 1 10 2 6 1 18 3 28 9z m-295 80c0 15 6 39 20 58 18 22 45 34 80 34 35 0 62-12 80-34 15-19 21-43 22-58l0-6-202 0z m202-65l-202 0 0 33 202 0z"/>
|
||||
<glyph glyph-name="certificate" unicode="" d="M168 320l172 0c7 0 14 6 14 14 0 7-7 13-14 13l-172 0c-8 0-14-6-14-13 0-8 6-14 14-14z m0-55l63 0c7 0 13 6 13 13 0 8-6 13-13 13l-63 0c-8 0-14-5-14-13 0-7 6-13 14-13z m0-57l46 0c8 0 14 6 14 14 0 7-6 14-14 14l-46 0c-8 0-14-7-14-14 0-8 6-14 14-14z m-65 210l0-283 139 0c7 0 12 6 12 13 0 6-5 12-12 12l-114 0 0 233 256 0 0-83c0-7 6-12 13-12 6 0 12 5 12 12l0 108z m304-200c0 43-35 78-78 78-43 0-78-35-78-78 0-27 14-52 37-66l-3-69c0-5 2-9 6-11 5-3 10-2 13 1l27 20 26-21c2-2 5-3 8-3 2 0 4 0 5 1 4 2 7 7 7 12l-4 72c21 14 34 38 34 64z m-68-101c-4 4-10 4-14 1l-15-11 1 36c6-2 12-2 18-2 7 0 14 1 20 2l2-36z"/>
|
||||
<glyph glyph-name="gift" unicode="" d="M342 330c1 1 3 2 4 3 19 17 21 47 4 66-9 10-22 16-35 16-6 0-12-1-17-3-6 19-24 33-45 33-22 0-41-15-46-35-5 2-11 3-17 3-13 0-26-6-35-16-17-20-15-50 5-66 0 0 0 0 0-1l-82 0 0-84 27 0 0-166 298 0 0 166 27 0 0 84z m-45 50l0 1c1 1 2 2 4 3 5 5 10 6 14 6 6 0 12-3 16-8 4-4 6-9 5-15 0-6-3-11-7-15-2-2-3-3-4-3l0 0 0 0c-5-1-27-10-52-18 10 22 22 44 24 49z m-44 40c12 0 21-9 21-21 0-3 0-4 0-5l0 0 0 0c-2-5-11-24-21-48-10 23-19 42-21 47l0 1c0 1-1 3-1 5 0 12 10 21 22 21z m-79-40c4 5 10 8 16 8 4 0 9-1 14-5 2-2 3-3 4-4l0 0 0 0c2-5 11-23 22-47-24 7-44 13-49 15l-1 0c-1 1-2 2-4 3-9 8-10 21-2 30z m67-274l-110 0 0 140 110 0z m0 166l-137 0 0 32 137 0z m136-166l-111 0 0 140 111 0z m27 166l-138 0 0 32 138 0z"/>
|
||||
<glyph glyph-name="update" unicode="" d="M380 170c-7 0-13-6-13-13l0-12c0-5-4-9-9-9l-203 0c-5 0-9 4-9 9l0 114 33-27c6-4 14-4 19 2 4 5 4 13-2 18l-54 47c-3 2-5 3-8 3-4 0-7-1-9-3l-54-47c-6-5-6-13-1-18 4-6 13-6 18-1l32 26 0-114c0-19 16-35 35-35l203 0c19 0 35 16 35 35l0 12c0 7-6 13-13 13z m-248 153c7 0 13 5 13 13l0 12c0 5 4 8 9 8l203 0c5 0 9-4 9-8l0-115-33 27c-5 5-14 4-18-1-5-6-5-14 1-19l54-47c3-2 5-3 9-3 3 0 6 1 8 3l54 47c6 5 6 13 2 19-5 5-13 6-19 1l-32-27 0 115c0 19-16 34-35 34l-203 0c-19 0-35-15-35-34l0-12c0-8 6-13 13-13z"/>
|
||||
<glyph glyph-name="uninstall" unicode="" d="M83 227c-7 0-13-6-13-13l0-78c0-19 16-35 35-35l297 0c19 0 35 16 35 35l0 78c0 7-6 13-13 13-7 0-13-6-13-13l0-78c0-5-4-9-9-9l-297 0c-5 0-9 4-9 9l0 78c0 7-6 13-13 13z m191 47l50 50c5 5 5 14 0 19-5 5-13 5-19 0l-50-50-50 50c-5 5-13 5-19 0-5-5-5-14 0-19l50-50-50-50c-5-5-5-14 0-19 5-5 14-5 19 0l50 50 50-50c5-5 14-5 19 0 5 5 5 14 0 19z"/>
|
||||
<glyph glyph-name="install" unicode="" d="M83 227c-7 0-13-6-13-13l0-78c0-19 16-35 35-35l297 0c19 0 35 16 35 35l0 78c0 7-6 13-13 13-7 0-13-6-13-13l0-78c0-5-4-9-9-9l-297 0c-5 0-9 4-9 9l0 78c0 7-6 13-13 13z m170 171l0-155-33 27c-6 5-14 5-19-1-4-5-4-14 2-18l54-48c3-2 5-3 8-3 3 0 7 1 9 3l54 48c5 4 6 13 1 18-4 5-13 6-18 1l-32-27 0 154c0 8-6 13-13 13-7 0-13-5-13-12z"/>
|
||||
<glyph glyph-name="ellipsis-vertical" unicode="" d="M276 178c0-14-11-24-24-24-14 0-25 10-25 24 0 13 11 24 25 24 13 0 24-11 24-24z m0 78c0-14-11-24-24-24-14 0-25 10-25 24 0 13 11 24 25 24 13 0 24-11 24-24z m0 78c0-14-11-24-24-24-14 0-25 10-25 24 0 13 11 24 25 24 13 0 24-11 24-24z"/>
|
||||
</font></defs></svg>
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 83 KiB |
|
@ -12,7 +12,7 @@
|
|||
<body>
|
||||
<div class="container">
|
||||
<h1>HiFi Glyphs</h1>
|
||||
<p class="small">This font was created for use in<a href="http://highfidelity.io/">High Fidelity</a></p>
|
||||
<p class="small">This font was created for use in <a href="http://highfidelity.io/">High Fidelity</a></p>
|
||||
<h2>CSS mapping</h2>
|
||||
<ul class="glyphs css-mapping">
|
||||
<li>
|
||||
|
@ -87,10 +87,6 @@
|
|||
<div class="icon icon-edit"></div>
|
||||
<input type="text" readonly="readonly" value="edit">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-market"></div>
|
||||
<input type="text" readonly="readonly" value="market">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-directory"></div>
|
||||
<input type="text" readonly="readonly" value="directory">
|
||||
|
@ -567,6 +563,46 @@
|
|||
<div class="icon icon-image"></div>
|
||||
<input type="text" readonly="readonly" value="image">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-environments"></div>
|
||||
<input type="text" readonly="readonly" value="environments">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-wand"></div>
|
||||
<input type="text" readonly="readonly" value="wand">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-market"></div>
|
||||
<input type="text" readonly="readonly" value="market">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-wear"></div>
|
||||
<input type="text" readonly="readonly" value="wear">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-certificate"></div>
|
||||
<input type="text" readonly="readonly" value="certificate">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-gift"></div>
|
||||
<input type="text" readonly="readonly" value="gift">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-update"></div>
|
||||
<input type="text" readonly="readonly" value="update">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-uninstall"></div>
|
||||
<input type="text" readonly="readonly" value="uninstall">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-install"></div>
|
||||
<input type="text" readonly="readonly" value="install">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-ellipsis-vertical"></div>
|
||||
<input type="text" readonly="readonly" value="ellipsis-vertical">
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Character mapping</h2>
|
||||
<ul class="glyphs character-mapping">
|
||||
|
@ -642,10 +678,6 @@
|
|||
<div data-icon="s" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="s">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="t" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="t">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="u" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="u">
|
||||
|
@ -1122,6 +1154,46 @@
|
|||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe02a;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe02c;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe02d;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="t" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="t">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe02e;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe030;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe031;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe032;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe033;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe02f;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe034;">
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<script>(function() {
|
|
@ -92,9 +92,6 @@
|
|||
.icon-edit:before {
|
||||
content: "\73";
|
||||
}
|
||||
.icon-market:before {
|
||||
content: "\74";
|
||||
}
|
||||
.icon-directory:before {
|
||||
content: "\75";
|
||||
}
|
||||
|
@ -452,3 +449,33 @@
|
|||
.icon-image:before {
|
||||
content: "\e02a";
|
||||
}
|
||||
.icon-environments:before {
|
||||
content: "\e02c";
|
||||
}
|
||||
.icon-wand:before {
|
||||
content: "\e02d";
|
||||
}
|
||||
.icon-market:before {
|
||||
content: "\74";
|
||||
}
|
||||
.icon-wear:before {
|
||||
content: "\e02e";
|
||||
}
|
||||
.icon-certificate:before {
|
||||
content: "\e030";
|
||||
}
|
||||
.icon-gift:before {
|
||||
content: "\e031";
|
||||
}
|
||||
.icon-update:before {
|
||||
content: "\e032";
|
||||
}
|
||||
.icon-uninstall:before {
|
||||
content: "\e033";
|
||||
}
|
||||
.icon-install:before {
|
||||
content: "\e02f";
|
||||
}
|
||||
.icon-ellipsis-vertical:before {
|
||||
content: "\e034";
|
||||
}
|
|
@ -257,9 +257,14 @@ Rectangle {
|
|||
lightboxPopup.bodyImageSource = msg.securityImageSource;
|
||||
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "GO TO WALLET";
|
||||
lightboxPopup.button2method = "sendToParent({method: 'checkout_openWallet'});";
|
||||
lightboxPopup.button2method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
sendToScript({method: 'checkout_openWallet'});
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
|
@ -623,10 +628,16 @@ Rectangle {
|
|||
lightboxPopup.bodyText = "You will not be able to replace this domain's content with <b>" + root.itemName +
|
||||
" </b>until the server owner gives you 'Replace Content' permissions.<br><br>Are you sure you want to purchase this content set?";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "CONFIRM";
|
||||
lightboxPopup.button2method = "Commerce.buy('" + root.itemId + "', " + root.itemPrice + ");" +
|
||||
"root.visible = false; buyButton.enabled = false; loading.visible = true;";
|
||||
lightboxPopup.button2method = function() {
|
||||
Commerce.buy(root.itemId, root.itemPrice);
|
||||
lightboxPopup.visible = false;
|
||||
buyButton.enabled = false;
|
||||
loading.visible = true;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else {
|
||||
buyButton.enabled = false;
|
||||
|
@ -771,19 +782,30 @@ Rectangle {
|
|||
"<a href='https://docs.highfidelity.com/create-and-explore/start-working-in-your-sandbox/restoring-sandbox-content'>" +
|
||||
"click here to open info on your desktop browser.";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "CONFIRM";
|
||||
lightboxPopup.button2method = "Commerce.replaceContentSet('" + root.itemHref + "', '" + root.certificateId + "');" +
|
||||
"root.visible = false;rezzedNotifContainer.visible = true; rezzedNotifContainerTimer.start();" +
|
||||
"UserActivityLogger.commerceEntityRezzed('" + root.itemId + "', 'checkout', '" + root.itemType + "');";
|
||||
lightboxPopup.button2method = function() {
|
||||
Commerce.replaceContentSet(root.itemHref);
|
||||
lightboxPopup.visible = false;
|
||||
rezzedNotifContainer.visible = true;
|
||||
rezzedNotifContainerTimer.start();
|
||||
UserActivityLogger.commerceEntityRezzed(root.itemId, 'checkout', root.itemType);
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else if (root.itemType === "avatar") {
|
||||
lightboxPopup.titleText = "Change Avatar";
|
||||
lightboxPopup.bodyText = "This will change your current avatar to " + root.itemName + " while retaining your wearables.";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "CONFIRM";
|
||||
lightboxPopup.button2method = "MyAvatar.useFullAvatarURL('" + root.itemHref + "'); root.visible = false;";
|
||||
lightboxPopup.button2method = function() {
|
||||
MyAvatar.useFullAvatarURL(root.itemHref);
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else if (root.itemType === "app") {
|
||||
if (root.isInstalled) {
|
||||
|
@ -822,9 +844,14 @@ Rectangle {
|
|||
lightboxPopup.bodyText = "You don't have permission to rez certified items in this domain.<br><br>" +
|
||||
"Use the <b>GOTO app</b> to visit another domain or <b>go to your own sandbox.</b>";
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "OPEN GOTO";
|
||||
lightboxPopup.button2method = "sendToParent({method: 'purchases_openGoTo'});";
|
||||
lightboxPopup.button2method = function() {
|
||||
sendToScript({method: 'purchases_openGoTo'});
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
|
@ -918,7 +945,9 @@ Rectangle {
|
|||
lightboxPopup.bodyText = 'Your item is marked "pending" while your purchase is being confirmed.<br><br>' +
|
||||
'Confirmations usually take about 90 seconds.';
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,10 @@ Rectangle {
|
|||
property string bodyText;
|
||||
property string button1color: hifi.buttons.noneBorderlessGray;
|
||||
property string button1text;
|
||||
property string button1method;
|
||||
property string button2color: hifi.buttons.noneBorderless;
|
||||
property var button1method;
|
||||
property string button2color: hifi.buttons.blue;
|
||||
property string button2text;
|
||||
property string button2method;
|
||||
property var button2method;
|
||||
property string buttonLayout: "leftright";
|
||||
|
||||
readonly property string securityPicBodyText: "When you see your Security Pic, your actions and data are securely making use of your " +
|
||||
|
@ -73,7 +73,7 @@ Rectangle {
|
|||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 30;
|
||||
height: paintedHeight;
|
||||
color: hifi.colors.baseGray;
|
||||
color: hifi.colors.black;
|
||||
size: 24;
|
||||
verticalAlignment: Text.AlignTop;
|
||||
wrapMode: Text.WordWrap;
|
||||
|
@ -105,7 +105,7 @@ Rectangle {
|
|||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 30;
|
||||
height: paintedHeight;
|
||||
color: hifi.colors.baseGray;
|
||||
color: hifi.colors.black;
|
||||
size: 20;
|
||||
verticalAlignment: Text.AlignTop;
|
||||
wrapMode: Text.WordWrap;
|
||||
|
@ -130,15 +130,15 @@ Rectangle {
|
|||
colorScheme: hifi.colorSchemes.light;
|
||||
anchors.top: root.buttonLayout === "leftright" ? parent.top : parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 10;
|
||||
anchors.leftMargin: root.buttonLayout === "leftright" ? 30 : 10;
|
||||
anchors.right: root.buttonLayout === "leftright" ? undefined : parent.right;
|
||||
anchors.rightMargin: root.buttonLayout === "leftright" ? undefined : 10;
|
||||
width: root.buttonLayout === "leftright" ? (root.button2text ? parent.width/2 - anchors.leftMargin*2 : parent.width - anchors.leftMargin * 2) :
|
||||
(undefined);
|
||||
height: 50;
|
||||
height: 40;
|
||||
text: root.button1text;
|
||||
onClicked: {
|
||||
eval(button1method);
|
||||
button1method();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,12 +153,12 @@ Rectangle {
|
|||
anchors.left: root.buttonLayout === "leftright" ? undefined : parent.left;
|
||||
anchors.leftMargin: root.buttonLayout === "leftright" ? undefined : 10;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 10;
|
||||
anchors.rightMargin: root.buttonLayout === "leftright" ? 30 : 10;
|
||||
width: root.buttonLayout === "leftright" ? parent.width/2 - anchors.rightMargin*2 : undefined;
|
||||
height: 50;
|
||||
height: 40;
|
||||
text: root.button2text;
|
||||
onClicked: {
|
||||
eval(button2method);
|
||||
button2method();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,10 +175,10 @@ Rectangle {
|
|||
root.bodyText = "";
|
||||
root.button1color = hifi.buttons.noneBorderlessGray;
|
||||
root.button1text = "";
|
||||
root.button1method = "";
|
||||
root.button2color = hifi.buttons.noneBorderless;
|
||||
root.button1method = function() {};
|
||||
root.button2color = hifi.buttons.blue;
|
||||
root.button2text = "";
|
||||
root.button2method = "";
|
||||
root.button2method = function() {};
|
||||
root.buttonLayout = "leftright";
|
||||
}
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// ConnectionItem.qml
|
||||
// qml/hifi/commerce/wallet/sendMoney
|
||||
// qml/hifi/commerce/common/sendAsset
|
||||
//
|
||||
// ConnectionItem
|
||||
//
|
||||
|
@ -113,7 +113,7 @@ Item {
|
|||
text: "CHOOSE";
|
||||
onClicked: {
|
||||
var msg = { method: 'chooseConnection', userName: root.userName, profilePicUrl: root.profilePicUrl };
|
||||
sendToSendMoney(msg);
|
||||
sendToParent(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ Item {
|
|||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
signal sendToSendMoney(var msg);
|
||||
signal sendToParent(var msg);
|
||||
//
|
||||
// FUNCTION DEFINITIONS END
|
||||
//
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// RecipientDisplay.qml
|
||||
// qml/hifi/commerce/wallet/sendMoney
|
||||
// qml/hifi/commerce/common/sendAsset
|
||||
//
|
||||
// RecipientDisplay
|
||||
//
|
||||
|
@ -18,7 +18,7 @@ import QtGraphicalEffects 1.0
|
|||
import "../../../../styles-uit"
|
||||
import "../../../../controls-uit" as HifiControlsUit
|
||||
import "../../../../controls" as HifiControls
|
||||
import "../../common" as HifiCommerceCommon
|
||||
import "../" as HifiCommerceCommon
|
||||
|
||||
Item {
|
||||
HifiConstants { id: hifi; }
|
Before Width: | Height: | Size: 921 B After Width: | Height: | Size: 921 B |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
@ -13,7 +13,6 @@
|
|||
|
||||
import Hifi 1.0 as Hifi
|
||||
import QtQuick 2.5
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import "../../../styles-uit"
|
||||
|
@ -22,14 +21,11 @@ import "../../../controls" as HifiControls
|
|||
import "../wallet" as HifiWallet
|
||||
import TabletScriptingInterface 1.0
|
||||
|
||||
// references XXX from root context
|
||||
|
||||
Item {
|
||||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string purchaseStatus;
|
||||
property bool purchaseStatusChanged;
|
||||
property string itemName;
|
||||
property string itemId;
|
||||
property string itemPreviewImageUrl;
|
||||
|
@ -46,16 +42,18 @@ Item {
|
|||
property var buttonGlyph: [hifi.glyphs.wand, hifi.glyphs.hat, hifi.glyphs.globe, hifi.glyphs.install, hifi.glyphs.avatar];
|
||||
property bool showConfirmation: false;
|
||||
property bool hasPermissionToRezThis;
|
||||
property bool permissionExplanationCardVisible;
|
||||
property bool cardBackVisible;
|
||||
property bool isInstalled;
|
||||
property string wornEntityID;
|
||||
property string upgradeUrl;
|
||||
property string upgradeTitle;
|
||||
property bool updateAvailable: root.upgradeUrl !== "" && !root.isShowingMyItems;
|
||||
property bool isShowingMyItems;
|
||||
|
||||
property string originalStatusText;
|
||||
property string originalStatusColor;
|
||||
|
||||
height: (root.upgradeUrl === "" || root.isShowingMyItems) ? 110 : 150;
|
||||
height: 102;
|
||||
width: parent.width;
|
||||
|
||||
Connections {
|
||||
|
@ -99,16 +97,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
onPurchaseStatusChangedChanged: {
|
||||
if (root.purchaseStatusChanged === true && root.purchaseStatus === "confirmed") {
|
||||
root.originalStatusText = statusText.text;
|
||||
root.originalStatusColor = statusText.color;
|
||||
statusText.text = "CONFIRMED!";
|
||||
statusText.color = hifi.colors.blueAccent;
|
||||
confirmedTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
onShowConfirmationChanged: {
|
||||
if (root.showConfirmation) {
|
||||
rezzedNotifContainer.visible = true;
|
||||
|
@ -118,35 +106,307 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: confirmedTimer;
|
||||
interval: 3000;
|
||||
onTriggered: {
|
||||
statusText.text = root.originalStatusText;
|
||||
statusText.color = root.originalStatusColor;
|
||||
root.purchaseStatusChanged = false;
|
||||
Rectangle {
|
||||
id: background;
|
||||
z: 10;
|
||||
color: Qt.rgba(0, 0, 0, 0.25);
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
Flipable {
|
||||
id: flipable;
|
||||
z: 50;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.top: parent.top;
|
||||
height: root.height - 2;
|
||||
|
||||
front: mainContainer;
|
||||
back: Rectangle {
|
||||
anchors.fill: parent;
|
||||
color: hifi.colors.white;
|
||||
|
||||
Item {
|
||||
id: closeContextMenuContainer;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 8;
|
||||
width: 30;
|
||||
height: width;
|
||||
|
||||
HiFiGlyphs {
|
||||
id: closeContextMenuGlyph;
|
||||
text: hifi.glyphs.close;
|
||||
anchors.fill: parent;
|
||||
size: 26;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
color: hifi.colors.black;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
root.sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
}
|
||||
onEntered: {
|
||||
closeContextMenuGlyph.text = hifi.glyphs.closeInverted;
|
||||
}
|
||||
onExited: {
|
||||
closeContextMenuGlyph.text = hifi.glyphs.close;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: contextCard;
|
||||
z: 2;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: closeContextMenuContainer.left;
|
||||
anchors.rightMargin: 8;
|
||||
color: hifi.colors.white;
|
||||
|
||||
Component {
|
||||
id: contextCardButton;
|
||||
|
||||
Item {
|
||||
property alias buttonGlyphText: buttonGlyph.text;
|
||||
property alias buttonText: buttonText.text;
|
||||
property string buttonColor: hifi.colors.black;
|
||||
property string buttonColor_hover: hifi.colors.blueHighlight;
|
||||
property alias enabled: buttonMouseArea.enabled;
|
||||
property var buttonClicked;
|
||||
|
||||
HiFiGlyphs {
|
||||
id: buttonGlyph;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 4;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
anchors.bottom: parent.verticalCenter;
|
||||
width: parent.width;
|
||||
size: 40;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
color: buttonMouseArea.enabled ? buttonColor : hifi.colors.lightGrayText;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
id: buttonText;
|
||||
anchors.top: parent.verticalCenter;
|
||||
anchors.topMargin: 4;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 12;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
width: parent.width;
|
||||
color: buttonMouseArea.enabled ? buttonColor : hifi.colors.lightGrayText;
|
||||
size: 16;
|
||||
wrapMode: Text.Wrap;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: buttonMouseArea;
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
parent.buttonClicked();
|
||||
}
|
||||
onEntered: {
|
||||
buttonGlyph.color = buttonColor_hover;
|
||||
buttonText.color = buttonColor_hover;
|
||||
}
|
||||
onExited: {
|
||||
buttonGlyph.color = buttonColor;
|
||||
buttonText.color = buttonColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: giftButton;
|
||||
visible: !root.isShowingMyItems;
|
||||
sourceComponent: contextCardButton;
|
||||
anchors.right: parent.right;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: 62;
|
||||
|
||||
onLoaded: {
|
||||
item.enabled = (root.purchaseStatus === "confirmed");
|
||||
item.buttonGlyphText = hifi.glyphs.gift;
|
||||
item.buttonText = "Gift";
|
||||
item.buttonClicked = function() {
|
||||
sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
sendToPurchases({
|
||||
method: 'giftAsset',
|
||||
itemName: root.itemName,
|
||||
certId: root.certificateId,
|
||||
itemType: root.itemType,
|
||||
itemHref: root.itemHref,
|
||||
isInstalled: root.isInstalled,
|
||||
wornEntityID: root.wornEntityID,
|
||||
effectImage: root.itemPreviewImageUrl
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: marketplaceButton;
|
||||
sourceComponent: contextCardButton;
|
||||
anchors.right: giftButton.visible ? giftButton.left : parent.right;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: 100;
|
||||
|
||||
onLoaded: {
|
||||
item.buttonGlyphText = hifi.glyphs.market;
|
||||
item.buttonText = "View in Marketplace";
|
||||
item.buttonClicked = function() {
|
||||
sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
sendToPurchases({method: 'purchases_itemInfoClicked', itemId: root.itemId});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: certificateButton;
|
||||
sourceComponent: contextCardButton;
|
||||
anchors.right: marketplaceButton.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: 100;
|
||||
|
||||
onLoaded: {
|
||||
item.buttonGlyphText = hifi.glyphs.certificate;
|
||||
item.buttonText = "View Certificate";
|
||||
item.buttonClicked = function() {
|
||||
sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
sendToPurchases({method: 'purchases_itemCertificateClicked', itemCertificateId: root.certificateId});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: uninstallButton;
|
||||
visible: root.isInstalled;
|
||||
sourceComponent: contextCardButton;
|
||||
anchors.right: certificateButton.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: 78;
|
||||
|
||||
onLoaded: {
|
||||
item.buttonGlyphText = hifi.glyphs.uninstall;
|
||||
item.buttonText = "Uninstall";
|
||||
item.buttonClicked = function() {
|
||||
sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
Commerce.uninstallApp(root.itemHref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: updateButton;
|
||||
visible: root.updateAvailable;
|
||||
sourceComponent: contextCardButton;
|
||||
anchors.right: uninstallButton.visible ? uninstallButton.left : certificateButton.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: 84;
|
||||
|
||||
onLoaded: {
|
||||
item.buttonGlyphText = hifi.glyphs.update;
|
||||
item.buttonText = "Update";
|
||||
item.buttonColor = "#E2334D";
|
||||
item.buttonClicked = function() {
|
||||
sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
sendToPurchases({method: 'updateItemClicked', itemId: root.itemId, itemEdition: root.itemEdition, upgradeUrl: root.upgradeUrl});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: permissionExplanationCard;
|
||||
z: 1;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: closeContextMenuContainer.left;
|
||||
anchors.rightMargin: 8;
|
||||
color: hifi.colors.white;
|
||||
|
||||
RalewayRegular {
|
||||
id: permissionExplanationText;
|
||||
anchors.fill: parent;
|
||||
text: {
|
||||
if (root.itemType === "contentSet") {
|
||||
"You do not have 'Replace Content' permissions in this domain. <a href='#replaceContentPermission'>Learn more</a>";
|
||||
} else if (root.itemType === "entity") {
|
||||
"You do not have 'Rez Certified' permissions in this domain. <a href='#rezCertifiedPermission'>Learn more</a>";
|
||||
} else {
|
||||
"Hey! You're not supposed to see this. How is it even possible that you're here? Are you a developer???"
|
||||
}
|
||||
}
|
||||
size: 16;
|
||||
color: hifi.colors.baseGray;
|
||||
wrapMode: Text.Wrap;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
onLinkActivated: {
|
||||
sendToPurchases({method: 'showPermissionsExplanation', itemType: root.itemType});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
transform: Rotation {
|
||||
id: rotation;
|
||||
origin.x: flipable.width/2;
|
||||
origin.y: flipable.height/2;
|
||||
axis.x: 1;
|
||||
axis.y: 0;
|
||||
axis.z: 0;
|
||||
angle: 0;
|
||||
}
|
||||
|
||||
states: State {
|
||||
name: "back";
|
||||
PropertyChanges {
|
||||
target: rotation;
|
||||
angle: 180;
|
||||
}
|
||||
when: root.cardBackVisible;
|
||||
}
|
||||
|
||||
transitions: Transition {
|
||||
SmoothedAnimation {
|
||||
target: rotation;
|
||||
property: "angle";
|
||||
velocity: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: mainContainer;
|
||||
z: 51;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
// Size
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
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;
|
||||
height: root.height - 2;
|
||||
|
||||
Image {
|
||||
id: itemPreviewImage;
|
||||
|
@ -154,8 +414,9 @@ Item {
|
|||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: height;
|
||||
width: height * 1.78;
|
||||
fillMode: Image.PreserveAspectCrop;
|
||||
mipmap: true;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
|
@ -165,218 +426,53 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
TextMetrics {
|
||||
id: itemNameTextMetrics;
|
||||
font: itemName.font;
|
||||
text: itemName.text;
|
||||
}
|
||||
RalewaySemiBold {
|
||||
RalewayRegular {
|
||||
id: itemName;
|
||||
anchors.top: itemPreviewImage.top;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: itemPreviewImage.right;
|
||||
anchors.leftMargin: 8;
|
||||
width: !noPermissionGlyph.visible ? (buttonContainer.x - itemPreviewImage.x - itemPreviewImage.width - anchors.leftMargin) :
|
||||
Math.min(itemNameTextMetrics.tightBoundingRect.width + 2,
|
||||
buttonContainer.x - itemPreviewImage.x - itemPreviewImage.width - anchors.leftMargin - noPermissionGlyph.width + 2);
|
||||
anchors.leftMargin: 10;
|
||||
anchors.right: contextMenuButtonContainer.left;
|
||||
anchors.rightMargin: 4;
|
||||
height: paintedHeight;
|
||||
// Text size
|
||||
size: 24;
|
||||
size: 20;
|
||||
// Style
|
||||
color: hifi.colors.blueAccent;
|
||||
color: hifi.colors.black;
|
||||
text: root.itemName;
|
||||
elide: Text.ElideRight;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
sendToPurchases({method: 'purchases_itemInfoClicked', itemId: root.itemId});
|
||||
}
|
||||
onEntered: {
|
||||
itemName.color = hifi.colors.blueHighlight;
|
||||
}
|
||||
onExited: {
|
||||
itemName.color = hifi.colors.blueAccent;
|
||||
}
|
||||
}
|
||||
}
|
||||
HiFiGlyphs {
|
||||
id: noPermissionGlyph;
|
||||
visible: !root.hasPermissionToRezThis;
|
||||
anchors.verticalCenter: itemName.verticalCenter;
|
||||
anchors.left: itemName.right;
|
||||
anchors.leftMargin: itemName.truncated ? -10 : -2;
|
||||
text: hifi.glyphs.info;
|
||||
// Size
|
||||
size: 40;
|
||||
width: 32;
|
||||
// Style
|
||||
color: hifi.colors.redAccent;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: true;
|
||||
|
||||
onEntered: {
|
||||
noPermissionGlyph.color = hifi.colors.redHighlight;
|
||||
}
|
||||
onExited: {
|
||||
noPermissionGlyph.color = hifi.colors.redAccent;
|
||||
}
|
||||
onClicked: {
|
||||
root.sendToPurchases({ method: 'openPermissionExplanationCard' });
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id: permissionExplanationCard;
|
||||
z: 995;
|
||||
visible: root.permissionExplanationCardVisible;
|
||||
anchors.fill: parent;
|
||||
color: hifi.colors.white;
|
||||
|
||||
RalewayRegular {
|
||||
id: permissionExplanationText;
|
||||
text: {
|
||||
if (root.itemType === "contentSet") {
|
||||
"You do not have 'Replace Content' permissions in this domain. <a href='#replaceContentPermission'>Learn more</a>";
|
||||
} else if (root.itemType === "entity") {
|
||||
"You do not have 'Rez Certified' permissions in this domain. <a href='#rezCertifiedPermission'>Learn more</a>";
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
size: 16;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: permissionExplanationGlyph.left;
|
||||
color: hifi.colors.baseGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
onLinkActivated: {
|
||||
sendToPurchases({method: 'showPermissionsExplanation', itemType: root.itemType});
|
||||
}
|
||||
}
|
||||
// "Close" button
|
||||
HiFiGlyphs {
|
||||
id: permissionExplanationGlyph;
|
||||
text: hifi.glyphs.close;
|
||||
color: hifi.colors.baseGray;
|
||||
size: 26;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
width: 77;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: true;
|
||||
onEntered: {
|
||||
parent.text = hifi.glyphs.closeInverted;
|
||||
}
|
||||
onExited: {
|
||||
parent.text = hifi.glyphs.close;
|
||||
}
|
||||
onClicked: {
|
||||
root.sendToPurchases({ method: 'openPermissionExplanationCard', closeAll: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: certificateContainer;
|
||||
anchors.top: itemName.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: itemName.left;
|
||||
anchors.right: buttonContainer.left;
|
||||
anchors.rightMargin: 2;
|
||||
height: 24;
|
||||
|
||||
HiFiGlyphs {
|
||||
id: certificateIcon;
|
||||
text: hifi.glyphs.scriptNew;
|
||||
// Size
|
||||
size: 30;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: 32;
|
||||
// Style
|
||||
color: hifi.colors.black;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
id: viewCertificateText;
|
||||
text: "VIEW CERTIFICATE";
|
||||
size: 13;
|
||||
anchors.left: certificateIcon.right;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
color: hifi.colors.black;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
sendToPurchases({method: 'purchases_itemCertificateClicked', itemCertificateId: root.certificateId});
|
||||
}
|
||||
onEntered: {
|
||||
certificateIcon.color = hifi.colors.lightGray;
|
||||
viewCertificateText.color = hifi.colors.lightGray;
|
||||
}
|
||||
onExited: {
|
||||
certificateIcon.color = hifi.colors.black;
|
||||
viewCertificateText.color = hifi.colors.black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: editionContainer;
|
||||
RalewayRegular {
|
||||
id: editionNumberText;
|
||||
visible: root.displayedItemCount > 1 && !statusContainer.visible;
|
||||
anchors.left: itemName.left;
|
||||
anchors.top: certificateContainer.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: buttonContainer.left;
|
||||
anchors.rightMargin: 2;
|
||||
|
||||
RalewayRegular {
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
text: "#" + root.itemEdition;
|
||||
size: 13;
|
||||
color: hifi.colors.black;
|
||||
verticalAlignment: Text.AlignTop;
|
||||
}
|
||||
anchors.right: itemName.right;
|
||||
anchors.top: itemName.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.bottom: buttonContainer.top;
|
||||
anchors.bottomMargin: 4;
|
||||
width: itemName.width;
|
||||
text: "Edition #" + root.itemEdition;
|
||||
size: 13;
|
||||
color: hifi.colors.black;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: statusContainer;
|
||||
visible: root.purchaseStatus === "pending" || root.purchaseStatus === "invalidated" || root.purchaseStatusChanged || root.numberSold > -1;
|
||||
visible: root.purchaseStatus === "pending" || root.purchaseStatus === "invalidated" || root.numberSold > -1;
|
||||
anchors.left: itemName.left;
|
||||
anchors.top: certificateContainer.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: buttonContainer.left;
|
||||
anchors.rightMargin: 2;
|
||||
anchors.right: itemName.right;
|
||||
anchors.top: itemName.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.bottom: buttonContainer.top;
|
||||
anchors.bottomMargin: 4;
|
||||
|
||||
RalewaySemiBold {
|
||||
RalewayRegular {
|
||||
id: statusText;
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
|
@ -393,7 +489,7 @@ Item {
|
|||
""
|
||||
}
|
||||
}
|
||||
size: 18;
|
||||
size: 13;
|
||||
color: {
|
||||
if (root.purchaseStatus === "pending") {
|
||||
hifi.colors.blueAccent
|
||||
|
@ -418,10 +514,10 @@ Item {
|
|||
}
|
||||
}
|
||||
// Size
|
||||
size: 36;
|
||||
size: 34;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: -8;
|
||||
anchors.topMargin: -10;
|
||||
anchors.left: statusText.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
// Style
|
||||
|
@ -468,6 +564,50 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contextMenuButtonContainer;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 8;
|
||||
width: 30;
|
||||
height: width;
|
||||
|
||||
Rectangle {
|
||||
visible: root.updateAvailable;
|
||||
anchors.fill: parent;
|
||||
radius: height;
|
||||
border.width: 1;
|
||||
border.color: "#E2334D";
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
id: contextMenuGlyph;
|
||||
text: hifi.glyphs.verticalEllipsis;
|
||||
anchors.fill: parent;
|
||||
size: 46;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
color: root.updateAvailable ? "#E2334D" : hifi.colors.black;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
contextCard.z = 1;
|
||||
permissionExplanationCard.z = 0;
|
||||
root.sendToPurchases({ method: 'flipCard' });
|
||||
}
|
||||
onEntered: {
|
||||
contextMenuGlyph.color = root.updateAvailable ? hifi.colors.redHighlight : hifi.colors.blueHighlight;
|
||||
}
|
||||
onExited: {
|
||||
contextMenuGlyph.color = root.updateAvailable ? "#E2334D" : hifi.colors.black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rezzedNotifContainer;
|
||||
z: 998;
|
||||
|
@ -489,62 +629,22 @@ Item {
|
|||
horizontalAlignment: Text.AlignHCenter;
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: rezzedNotifContainerTimer;
|
||||
interval: 2000;
|
||||
onTriggered: rezzedNotifContainer.visible = false
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: appButtonContainer;
|
||||
color: hifi.colors.white;
|
||||
z: 994;
|
||||
visible: root.isInstalled;
|
||||
anchors.fill: buttonContainer;
|
||||
|
||||
HifiControlsUit.Button {
|
||||
id: openAppButton;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.light;
|
||||
anchors.top: parent.top;
|
||||
anchors.right: parent.right;
|
||||
anchors.left: parent.left;
|
||||
width: 92;
|
||||
height: 44;
|
||||
text: "OPEN"
|
||||
onClicked: {
|
||||
Commerce.openApp(root.itemHref);
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Button {
|
||||
id: uninstallAppButton;
|
||||
color: hifi.buttons.noneBorderless;
|
||||
colorScheme: hifi.colorSchemes.light;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
anchors.left: parent.left;
|
||||
height: 44;
|
||||
text: "UNINSTALL"
|
||||
onClicked: {
|
||||
Commerce.uninstallApp(root.itemHref);
|
||||
}
|
||||
Timer {
|
||||
id: rezzedNotifContainerTimer;
|
||||
interval: 2000;
|
||||
onTriggered: rezzedNotifContainer.visible = false
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: buttonContainer;
|
||||
property int color: hifi.buttons.blue;
|
||||
property int colorScheme: hifi.colorSchemes.light;
|
||||
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: itemName.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 4;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 4;
|
||||
width: height;
|
||||
anchors.bottomMargin: 8;
|
||||
width: 160;
|
||||
height: 40;
|
||||
enabled: root.hasPermissionToRezThis &&
|
||||
root.purchaseStatus !== "invalidated" &&
|
||||
MyAvatar.skeletonModelURL !== root.itemHref;
|
||||
|
@ -568,8 +668,12 @@ Item {
|
|||
} else if (root.itemType === "avatar") {
|
||||
sendToPurchases({method: 'showChangeAvatarLightbox', itemName: root.itemName, itemHref: root.itemHref});
|
||||
} else if (root.itemType === "app") {
|
||||
// "Run" and "Uninstall" buttons are separate.
|
||||
Commerce.installApp(root.itemHref);
|
||||
if (root.isInstalled) {
|
||||
Commerce.openApp(root.itemHref);
|
||||
} else {
|
||||
// "Run" and "Uninstall" buttons are separate.
|
||||
Commerce.installApp(root.itemHref);
|
||||
}
|
||||
} else {
|
||||
sendToPurchases({method: 'purchases_rezClicked', itemHref: root.itemHref, itemType: root.itemType});
|
||||
root.showConfirmation = true;
|
||||
|
@ -612,93 +716,76 @@ Item {
|
|||
}
|
||||
|
||||
label: Item {
|
||||
TextMetrics {
|
||||
id: rezIconTextMetrics;
|
||||
font: rezIcon.font;
|
||||
text: rezIcon.text;
|
||||
}
|
||||
HiFiGlyphs {
|
||||
id: rezIcon;
|
||||
text: (root.buttonGlyph)[itemTypesArray.indexOf(root.itemType)];
|
||||
// Size
|
||||
size: 60;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 0;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.right: rezIconLabel.left;
|
||||
anchors.rightMargin: 2;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
size: 36;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
// Style
|
||||
color: enabled ? hifi.buttons.textColor[control.color]
|
||||
: hifi.buttons.disabledTextColor[control.colorScheme]
|
||||
: hifi.buttons.disabledTextColor[control.colorScheme]
|
||||
}
|
||||
TextMetrics {
|
||||
id: rezIconLabelTextMetrics;
|
||||
font: rezIconLabel.font;
|
||||
text: rezIconLabel.text;
|
||||
}
|
||||
RalewayBold {
|
||||
id: rezIconLabel;
|
||||
anchors.top: rezIcon.bottom;
|
||||
anchors.topMargin: -4;
|
||||
anchors.right: parent.right;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
font.capitalization: Font.AllUppercase
|
||||
color: enabled ? hifi.buttons.textColor[control.color]
|
||||
: hifi.buttons.disabledTextColor[control.colorScheme]
|
||||
text: root.isInstalled ? "OPEN" : (MyAvatar.skeletonModelURL === root.itemHref ? "CURRENT" : (root.buttonTextNormal)[itemTypesArray.indexOf(root.itemType)]);
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
width: rezIconLabelTextMetrics.width;
|
||||
x: parent.width/2 - rezIconLabelTextMetrics.width/2 + rezIconTextMetrics.width/2;
|
||||
size: 15;
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: MyAvatar.skeletonModelURL === root.itemHref ? "CURRENT" : (root.buttonTextNormal)[itemTypesArray.indexOf(root.itemType)];
|
||||
font.capitalization: Font.AllUppercase;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
color: enabled ? hifi.buttons.textColor[control.color]
|
||||
: hifi.buttons.disabledTextColor[control.colorScheme]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// END "incorrect indentation to prevent insane diffs"
|
||||
HiFiGlyphs {
|
||||
id: noPermissionGlyph;
|
||||
visible: !root.hasPermissionToRezThis;
|
||||
anchors.verticalCenter: buttonContainer.verticalCenter;
|
||||
anchors.left: buttonContainer.left;
|
||||
anchors.right: buttonContainer.right;
|
||||
anchors.rightMargin: -40;
|
||||
text: hifi.glyphs.info;
|
||||
// Size
|
||||
size: 44;
|
||||
// Style
|
||||
color: hifi.colors.redAccent;
|
||||
horizontalAlignment: Text.AlignRight;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: true;
|
||||
|
||||
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});
|
||||
onEntered: {
|
||||
noPermissionGlyph.color = hifi.colors.redHighlight;
|
||||
}
|
||||
onExited: {
|
||||
noPermissionGlyph.color = hifi.colors.redAccent;
|
||||
}
|
||||
onClicked: {
|
||||
contextCard.z = 0;
|
||||
permissionExplanationCard.z = 1;
|
||||
root.sendToPurchases({ method: 'flipCard' });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
anchors.fill: mainContainer;
|
||||
horizontalOffset: 0;
|
||||
verticalOffset: 4;
|
||||
radius: 4.0;
|
||||
samples: 9
|
||||
color: Qt.rgba(0, 0, 0, 0.25);
|
||||
source: mainContainer;
|
||||
}
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
|
|
|
@ -20,6 +20,7 @@ import "../../../controls" as HifiControls
|
|||
import "../wallet" as HifiWallet
|
||||
import "../common" as HifiCommerceCommon
|
||||
import "../inspectionCertificate" as HifiInspectionCertificate
|
||||
import "../common/sendAsset" as HifiSendAsset
|
||||
|
||||
// references XXX from root context
|
||||
|
||||
|
@ -32,7 +33,6 @@ Rectangle {
|
|||
property bool securityImageResultReceived: false;
|
||||
property bool purchasesReceived: false;
|
||||
property bool punctuationMode: false;
|
||||
property bool pendingInventoryReply: true;
|
||||
property bool isShowingMyItems: false;
|
||||
property bool isDebuggingFirstUseTutorial: false;
|
||||
property int pendingItemCount: 0;
|
||||
|
@ -115,12 +115,6 @@ Rectangle {
|
|||
|
||||
purchasesContentsList.positionViewAtIndex(currentIndex, ListView.Beginning);
|
||||
}
|
||||
|
||||
if (root.pendingInventoryReply && root.pendingItemCount > 0) {
|
||||
inventoryTimer.start();
|
||||
}
|
||||
|
||||
root.pendingInventoryReply = false;
|
||||
}
|
||||
|
||||
onAvailableUpdatesResult: {
|
||||
|
@ -143,7 +137,7 @@ Rectangle {
|
|||
|
||||
HifiInspectionCertificate.InspectionCertificate {
|
||||
id: inspectionCertificate;
|
||||
z: 999;
|
||||
z: 998;
|
||||
visible: false;
|
||||
anchors.fill: parent;
|
||||
|
||||
|
@ -156,6 +150,7 @@ Rectangle {
|
|||
|
||||
HifiCommerceCommon.CommerceLightbox {
|
||||
id: lightboxPopup;
|
||||
z: 999;
|
||||
visible: false;
|
||||
anchors.fill: parent;
|
||||
|
||||
|
@ -170,12 +165,33 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
HifiSendAsset.SendAsset {
|
||||
id: sendAsset;
|
||||
z: 998;
|
||||
visible: root.activeView === "giftAsset";
|
||||
anchors.fill: parent;
|
||||
parentAppTitleBarHeight: 70;
|
||||
parentAppNavBarHeight: 0;
|
||||
|
||||
Connections {
|
||||
onSendSignalToParent: {
|
||||
if (msg.method === 'sendAssetHome_back' || msg.method === 'closeSendAsset') {
|
||||
root.activeView = "purchasesMain";
|
||||
Commerce.inventory();
|
||||
Commerce.getAvailableUpdates();
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TITLE BAR START
|
||||
//
|
||||
HifiCommerceCommon.EmulatedMarketplaceHeader {
|
||||
id: titleBarContainer;
|
||||
z: 998;
|
||||
z: 997;
|
||||
visible: !needsLogIn.visible;
|
||||
// Size
|
||||
width: parent.width;
|
||||
|
@ -192,9 +208,14 @@ Rectangle {
|
|||
lightboxPopup.bodyImageSource = msg.securityImageSource;
|
||||
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "GO TO WALLET";
|
||||
lightboxPopup.button2method = "sendToParent({method: 'purchases_openWallet'});";
|
||||
lightboxPopup.button2method = function() {
|
||||
sendToScript({method: 'purchases_openWallet'});
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
|
@ -309,7 +330,7 @@ Rectangle {
|
|||
// FILTER BAR START
|
||||
//
|
||||
Item {
|
||||
z: 997;
|
||||
z: 996;
|
||||
id: filterBarContainer;
|
||||
// Size
|
||||
height: 40;
|
||||
|
@ -317,7 +338,7 @@ Rectangle {
|
|||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
anchors.rightMargin: 8;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 4;
|
||||
|
||||
|
@ -342,6 +363,7 @@ Rectangle {
|
|||
colorScheme: hifi.colorSchemes.faintGray;
|
||||
anchors.top: parent.top;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
anchors.left: myText.right;
|
||||
anchors.leftMargin: 16;
|
||||
textFieldHeight: 39;
|
||||
|
@ -397,7 +419,7 @@ Rectangle {
|
|||
//
|
||||
|
||||
HifiControlsUit.Separator {
|
||||
z: 996;
|
||||
z: 995;
|
||||
id: separator;
|
||||
colorScheme: 2;
|
||||
anchors.left: parent.left;
|
||||
|
@ -427,7 +449,6 @@ Rectangle {
|
|||
snapMode: ListView.SnapToItem;
|
||||
// Anchors
|
||||
anchors.top: separator.bottom;
|
||||
anchors.topMargin: 12;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: updatesAvailableBanner.visible ? updatesAvailableBanner.top : parent.bottom;
|
||||
width: parent.width;
|
||||
|
@ -438,13 +459,13 @@ Rectangle {
|
|||
itemHref: download_url;
|
||||
certificateId: certificate_id;
|
||||
purchaseStatus: status;
|
||||
purchaseStatusChanged: statusChanged;
|
||||
itemEdition: model.edition_number;
|
||||
numberSold: model.number_sold;
|
||||
limitedRun: model.limited_run;
|
||||
displayedItemCount: model.displayedItemCount;
|
||||
permissionExplanationCardVisible: model.permissionExplanationCardVisible;
|
||||
cardBackVisible: model.cardBackVisible;
|
||||
isInstalled: model.isInstalled;
|
||||
wornEntityID: model.wornEntityID;
|
||||
upgradeUrl: model.upgrade_url;
|
||||
upgradeTitle: model.upgrade_title;
|
||||
itemType: model.itemType;
|
||||
|
@ -458,6 +479,11 @@ Rectangle {
|
|||
sendToScript({method: 'purchases_itemInfoClicked', itemId: itemId});
|
||||
} else if (msg.method === "purchases_rezClicked") {
|
||||
sendToScript({method: 'purchases_rezClicked', itemHref: itemHref, itemType: itemType});
|
||||
|
||||
// Race condition - Wearable might not be rezzed by the time the "currently worn wearbles" model is created
|
||||
if (itemType === "wearable") {
|
||||
sendToScript({ method: 'purchases_updateWearables' });
|
||||
}
|
||||
} else if (msg.method === 'purchases_itemCertificateClicked') {
|
||||
inspectionCertificate.visible = true;
|
||||
inspectionCertificate.isLightbox = true;
|
||||
|
@ -467,14 +493,18 @@ Rectangle {
|
|||
lightboxPopup.bodyText = 'Your item is marked "invalidated" because this item has been suspended ' +
|
||||
"from the Marketplace due to a claim against its author.";
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
} else if (msg.method === "showPendingLightbox") {
|
||||
lightboxPopup.titleText = "Item Pending";
|
||||
lightboxPopup.bodyText = 'Your item is marked "pending" while your purchase is being confirmed. ' +
|
||||
"Usually, purchases take about 90 seconds to confirm.";
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
} else if (msg.method === "showReplaceContentLightbox") {
|
||||
lightboxPopup.titleText = "Replace Content";
|
||||
|
@ -484,17 +514,27 @@ Rectangle {
|
|||
"<a href='https://docs.highfidelity.com/create-and-explore/start-working-in-your-sandbox/restoring-sandbox-content'>" +
|
||||
"click here to open info on your desktop browser.";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "CONFIRM";
|
||||
lightboxPopup.button2method = "Commerce.replaceContentSet('" + msg.itemHref + "', '" + msg.certID + "'); root.visible = false;";
|
||||
lightboxPopup.button2method = function() {
|
||||
Commerce.replaceContentSet(msg.itemHref, msg.certID);
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else if (msg.method === "showChangeAvatarLightbox") {
|
||||
lightboxPopup.titleText = "Change Avatar";
|
||||
lightboxPopup.bodyText = "This will change your current avatar to " + msg.itemName + " while retaining your wearables.";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "CONFIRM";
|
||||
lightboxPopup.button2method = "MyAvatar.useFullAvatarURL('" + msg.itemHref + "'); root.visible = false;";
|
||||
lightboxPopup.button2method = function() {
|
||||
MyAvatar.useFullAvatarURL(msg.itemHref);
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else if (msg.method === "showPermissionsExplanation") {
|
||||
if (msg.itemType === "entity") {
|
||||
|
@ -502,27 +542,86 @@ Rectangle {
|
|||
lightboxPopup.bodyText = "You don't have permission to rez certified items in this domain.<br><br>" +
|
||||
"Use the <b>GOTO app</b> to visit another domain or <b>go to your own sandbox.</b>";
|
||||
lightboxPopup.button2text = "OPEN GOTO";
|
||||
lightboxPopup.button2method = "sendToParent({method: 'purchases_openGoTo'});";
|
||||
lightboxPopup.button2method = function() {
|
||||
sendToScript({method: 'purchases_openGoTo'});
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
} else if (msg.itemType === "contentSet") {
|
||||
lightboxPopup.titleText = "Replace Content Permission";
|
||||
lightboxPopup.bodyText = "You do not have the permission 'Replace Content' in this <b>domain's server settings</b>. The domain owner " +
|
||||
"must enable it for you before you can replace content sets in this domain.";
|
||||
}
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
} else if (msg.method === "setFilterText") {
|
||||
filterBar.text = msg.filterText;
|
||||
} else if (msg.method === "openPermissionExplanationCard") {
|
||||
} else if (msg.method === "flipCard") {
|
||||
for (var i = 0; i < filteredPurchasesModel.count; i++) {
|
||||
if (i !== index || msg.closeAll) {
|
||||
filteredPurchasesModel.setProperty(i, "permissionExplanationCardVisible", false);
|
||||
filteredPurchasesModel.setProperty(i, "cardBackVisible", false);
|
||||
} else {
|
||||
filteredPurchasesModel.setProperty(i, "permissionExplanationCardVisible", true);
|
||||
filteredPurchasesModel.setProperty(i, "cardBackVisible", true);
|
||||
}
|
||||
}
|
||||
} else if (msg.method === "updateItemClicked") {
|
||||
sendToScript(msg);
|
||||
} else if (msg.method === "giftAsset") {
|
||||
sendAsset.assetName = msg.itemName;
|
||||
sendAsset.assetCertID = msg.certId;
|
||||
sendAsset.sendingPubliclyEffectImage = msg.effectImage;
|
||||
|
||||
if (msg.itemType === "avatar" && MyAvatar.skeletonModelURL === msg.itemHref) {
|
||||
lightboxPopup.titleText = "Change Avatar to Default";
|
||||
lightboxPopup.bodyText = "You are currently wearing the avatar that you are trying to gift.<br><br>" +
|
||||
"If you proceed, your avatar will be changed to the default avatar.";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "CONFIRM";
|
||||
lightboxPopup.button2method = function() {
|
||||
MyAvatar.skeletonModelURL = '';
|
||||
root.activeView = "giftAsset";
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else if (msg.itemType === "app" && msg.isInstalled) {
|
||||
lightboxPopup.titleText = "Uninstall App";
|
||||
lightboxPopup.bodyText = "You are currently using the app that you are trying to gift.<br><br>" +
|
||||
"If you proceed, the app will be uninstalled.";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "CONFIRM";
|
||||
lightboxPopup.button2method = function() {
|
||||
Commerce.uninstallApp(msg.itemHref);
|
||||
root.activeView = "giftAsset";
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else if (msg.itemType === "wearable" && msg.wornEntityID !== '') {
|
||||
lightboxPopup.titleText = "Remove Wearable";
|
||||
lightboxPopup.bodyText = "You are currently wearing the wearable that you are trying to send.<br><br>" +
|
||||
"If you proceed, this wearable will be removed.";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "CONFIRM";
|
||||
lightboxPopup.button2method = function() {
|
||||
Entities.deleteEntity(msg.wornEntityID);
|
||||
filteredPurchasesModel.setProperty(index, 'wornEntityID', '');
|
||||
root.activeView = "giftAsset";
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else {
|
||||
root.activeView = "giftAsset";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -703,26 +802,6 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (!visible) {
|
||||
inventoryTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: inventoryTimer;
|
||||
interval: 4000; // Change this back to 90000 after demo
|
||||
//interval: 90000;
|
||||
onTriggered: {
|
||||
if (root.activeView === "purchasesMain" && !root.pendingInventoryReply) {
|
||||
console.log("Refreshing Purchases...");
|
||||
root.pendingInventoryReply = true;
|
||||
Commerce.inventory();
|
||||
Commerce.getAvailableUpdates();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
|
@ -834,10 +913,12 @@ Rectangle {
|
|||
continue;
|
||||
}
|
||||
filteredPurchasesModel.append(tempPurchasesModel.get(i));
|
||||
filteredPurchasesModel.setProperty(i, 'permissionExplanationCardVisible', false);
|
||||
filteredPurchasesModel.setProperty(i, 'cardBackVisible', false);
|
||||
filteredPurchasesModel.setProperty(i, 'isInstalled', ((root.installedApps).indexOf(currentId) > -1));
|
||||
filteredPurchasesModel.setProperty(i, 'wornEntityID', '');
|
||||
}
|
||||
|
||||
|
||||
sendToScript({ method: 'purchases_updateWearables' });
|
||||
populateDisplayedItemCounts();
|
||||
sortByDate();
|
||||
}
|
||||
|
@ -864,6 +945,19 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateCurrentlyWornWearables(wearables) {
|
||||
for (var i = 0; i < filteredPurchasesModel.count; i++) {
|
||||
for (var j = 0; j < wearables.length; j++) {
|
||||
if (filteredPurchasesModel.get(i).itemType === "wearable" &&
|
||||
wearables[j].entityCertID === filteredPurchasesModel.get(i).certificate_id &&
|
||||
wearables[j].entityEdition.toString() === filteredPurchasesModel.get(i).edition_number) {
|
||||
filteredPurchasesModel.setProperty(i, 'wornEntityID', wearables[j].entityID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Function Name: fromScript()
|
||||
|
@ -891,6 +985,16 @@ Rectangle {
|
|||
case 'purchases_showMyItems':
|
||||
root.isShowingMyItems = true;
|
||||
break;
|
||||
case 'updateConnections':
|
||||
sendAsset.updateConnections(message.connections);
|
||||
break;
|
||||
case 'selectRecipient':
|
||||
case 'updateSelectedRecipientUsername':
|
||||
sendAsset.fromScript(message);
|
||||
break;
|
||||
case 'updateWearables':
|
||||
updateCurrentlyWornWearables(message.wornWearables);
|
||||
break;
|
||||
default:
|
||||
console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
|
||||
}
|
||||
|
|
|
@ -144,7 +144,9 @@ Item {
|
|||
lightboxPopup.bodyImageSource = titleBarSecurityImage.source;
|
||||
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import "../../../styles-uit"
|
|||
import "../../../controls-uit" as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
import "../common" as HifiCommerceCommon
|
||||
import "./sendMoney"
|
||||
import "../common/sendAsset"
|
||||
|
||||
Rectangle {
|
||||
HifiConstants { id: hifi; }
|
||||
|
@ -161,7 +161,9 @@ Rectangle {
|
|||
lightboxPopup.bodyImageSource = titleBarSecurityImage.source;
|
||||
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
|
@ -342,7 +344,7 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
SendMoney {
|
||||
SendAsset {
|
||||
id: sendMoney;
|
||||
z: 997;
|
||||
visible: root.activeView === "sendMoney";
|
||||
|
@ -351,7 +353,7 @@ Rectangle {
|
|||
parentAppNavBarHeight: tabButtonsContainer.height;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
onSendSignalToParent: {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
|
@ -406,7 +408,7 @@ Rectangle {
|
|||
//
|
||||
Item {
|
||||
id: tabButtonsContainer;
|
||||
visible: !needsLogIn.visible && root.activeView !== "passphraseChange" && root.activeView !== "securityImageChange" && sendMoney.currentActiveView !== "sendMoneyStep";
|
||||
visible: !needsLogIn.visible && root.activeView !== "passphraseChange" && root.activeView !== "securityImageChange" && sendMoney.currentActiveView !== "sendAssetStep";
|
||||
property int numTabs: 5;
|
||||
// Size
|
||||
width: root.width;
|
||||
|
|
|
@ -206,9 +206,14 @@ Item {
|
|||
"This step cannot be undone.";
|
||||
lightboxPopup.button1color = hifi.buttons.red;
|
||||
lightboxPopup.button1text = "YES, CREATE NEW WALLET";
|
||||
lightboxPopup.button1method = "root.visible = false;proceed(true);";
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
proceed(true);
|
||||
}
|
||||
lightboxPopup.button2text = "CANCEL";
|
||||
lightboxPopup.button2method = "root.visible = false;"
|
||||
lightboxPopup.button2method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.buttonLayout = "topbottom";
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
|
@ -241,7 +246,9 @@ Item {
|
|||
"If you'd prefer to create a new wallet (not recommended - you will lose your money and past " +
|
||||
"purchases), click 'Create New Wallet'.";
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
} else {
|
||||
lightboxPopup.titleText = "You may have set up more than one wallet";
|
||||
|
@ -251,7 +258,9 @@ Item {
|
|||
"If you would prefer to use another wallet, click 'Locate Other Keys' to show us where " +
|
||||
"you've stored the private keys for that wallet.";
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,7 +151,9 @@ Item {
|
|||
lightboxPopup.bodyImageSource = titleBarSecurityImage.source;
|
||||
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -344,5 +344,10 @@ QtObject {
|
|||
readonly property string wand: "\ue02d"
|
||||
readonly property string hat: "\ue02e"
|
||||
readonly property string install: "\ue02f"
|
||||
readonly property string certificate: "\ue030"
|
||||
readonly property string gift: "\ue031"
|
||||
readonly property string update: "\ue032"
|
||||
readonly property string uninstall: "\ue033"
|
||||
readonly property string verticalEllipsis: "\ue034"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2567,6 +2567,7 @@ void Application::initializeUi() {
|
|||
QUrl{ "hifi/commerce/common/EmulatedMarketplaceHeader.qml" },
|
||||
QUrl{ "hifi/commerce/common/FirstUseTutorial.qml" },
|
||||
QUrl{ "hifi/commerce/common/SortableListModel.qml" },
|
||||
QUrl{ "hifi/commerce/common/sendAsset/SendAsset.qml" },
|
||||
QUrl{ "hifi/commerce/inspectionCertificate/InspectionCertificate.qml" },
|
||||
QUrl{ "hifi/commerce/purchases/PurchasedItem.qml" },
|
||||
QUrl{ "hifi/commerce/purchases/Purchases.qml" },
|
||||
|
@ -2579,7 +2580,6 @@ void Application::initializeUi() {
|
|||
QUrl{ "hifi/commerce/wallet/SecurityImageChange.qml" },
|
||||
QUrl{ "hifi/commerce/wallet/SecurityImageModel.qml" },
|
||||
QUrl{ "hifi/commerce/wallet/SecurityImageSelection.qml" },
|
||||
QUrl{ "hifi/commerce/wallet/sendMoney/SendMoney.qml" },
|
||||
QUrl{ "hifi/commerce/wallet/Wallet.qml" },
|
||||
QUrl{ "hifi/commerce/wallet/WalletHome.qml" },
|
||||
QUrl{ "hifi/commerce/wallet/WalletSetup.qml" },
|
||||
|
|
|
@ -56,8 +56,8 @@ Handler(buy)
|
|||
Handler(receiveAt)
|
||||
Handler(balance)
|
||||
Handler(inventory)
|
||||
Handler(transferHfcToNode)
|
||||
Handler(transferHfcToUsername)
|
||||
Handler(transferAssetToNode)
|
||||
Handler(transferAssetToUsername)
|
||||
Handler(alreadyOwned)
|
||||
Handler(availableUpdates)
|
||||
Handler(updateItem)
|
||||
|
@ -354,27 +354,41 @@ void Ledger::certificateInfo(const QString& certificateId) {
|
|||
send(endpoint, "certificateInfoSuccess", "certificateInfoFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::None, request);
|
||||
}
|
||||
|
||||
void Ledger::transferHfcToNode(const QString& hfc_key, const QString& nodeID, const int& amount, const QString& optionalMessage) {
|
||||
void Ledger::transferAssetToNode(const QString& hfc_key, const QString& nodeID, const QString& certificateID, const int& amount, const QString& optionalMessage) {
|
||||
QJsonObject transaction;
|
||||
transaction["public_key"] = hfc_key;
|
||||
transaction["node_id"] = nodeID;
|
||||
transaction["quantity"] = amount;
|
||||
transaction["message"] = optionalMessage;
|
||||
transaction["place_name"] = DependencyManager::get<AddressManager>()->getPlaceName();
|
||||
if (!certificateID.isEmpty()) {
|
||||
transaction["certificate_id"] = certificateID;
|
||||
}
|
||||
QJsonDocument transactionDoc{ transaction };
|
||||
auto transactionString = transactionDoc.toJson(QJsonDocument::Compact);
|
||||
signedSend("transaction", transactionString, hfc_key, "transfer_hfc_to_node", "transferHfcToNodeSuccess", "transferHfcToNodeFailure");
|
||||
if (certificateID.isEmpty()) {
|
||||
signedSend("transaction", transactionString, hfc_key, "transfer_hfc_to_node", "transferAssetToNodeSuccess", "transferAssetToNodeFailure");
|
||||
} else {
|
||||
signedSend("transaction", transactionString, hfc_key, "transfer_asset_to_node", "transferAssetToNodeSuccess", "transferAssetToNodeFailure");
|
||||
}
|
||||
}
|
||||
|
||||
void Ledger::transferHfcToUsername(const QString& hfc_key, const QString& username, const int& amount, const QString& optionalMessage) {
|
||||
void Ledger::transferAssetToUsername(const QString& hfc_key, const QString& username, const QString& certificateID, const int& amount, const QString& optionalMessage) {
|
||||
QJsonObject transaction;
|
||||
transaction["public_key"] = hfc_key;
|
||||
transaction["username"] = username;
|
||||
transaction["quantity"] = amount;
|
||||
transaction["message"] = optionalMessage;
|
||||
if (!certificateID.isEmpty()) {
|
||||
transaction["certificate_id"] = certificateID;
|
||||
}
|
||||
QJsonDocument transactionDoc{ transaction };
|
||||
auto transactionString = transactionDoc.toJson(QJsonDocument::Compact);
|
||||
signedSend("transaction", transactionString, hfc_key, "transfer_hfc_to_user", "transferHfcToUsernameSuccess", "transferHfcToUsernameFailure");
|
||||
if (certificateID.isEmpty()) {
|
||||
signedSend("transaction", transactionString, hfc_key, "transfer_hfc_to_user", "transferAssetToUsernameSuccess", "transferAssetToUsernameFailure");
|
||||
} else {
|
||||
signedSend("transaction", transactionString, hfc_key, "transfer_asset_to_user", "transferAssetToUsernameSuccess", "transferAssetToUsernameFailure");
|
||||
}
|
||||
}
|
||||
|
||||
void Ledger::alreadyOwned(const QString& marketplaceId) {
|
||||
|
|
|
@ -33,8 +33,8 @@ public:
|
|||
void account();
|
||||
void updateLocation(const QString& asset_id, const QString& location, const bool& alsoUpdateSiblings = false, const bool controlledFailure = false);
|
||||
void certificateInfo(const QString& certificateId);
|
||||
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 transferAssetToNode(const QString& hfc_key, const QString& nodeID, const QString& certificateID, const int& amount, const QString& optionalMessage);
|
||||
void transferAssetToUsername(const QString& hfc_key, const QString& username, const QString& certificateID, const int& amount, const QString& optionalMessage);
|
||||
void alreadyOwned(const QString& marketplaceId);
|
||||
void getAvailableUpdates(const QString& itemId = "");
|
||||
void updateItem(const QString& hfc_key, const QString& certificate_id);
|
||||
|
@ -56,8 +56,8 @@ signals:
|
|||
void accountResult(QJsonObject result);
|
||||
void locationUpdateResult(QJsonObject result);
|
||||
void certificateInfoResult(QJsonObject result);
|
||||
void transferHfcToNodeResult(QJsonObject result);
|
||||
void transferHfcToUsernameResult(QJsonObject result);
|
||||
void transferAssetToNodeResult(QJsonObject result);
|
||||
void transferAssetToUsernameResult(QJsonObject result);
|
||||
void alreadyOwnedResult(QJsonObject result);
|
||||
void availableUpdatesResult(QJsonObject result);
|
||||
void updateItemResult(QJsonObject result);
|
||||
|
@ -81,10 +81,10 @@ public slots:
|
|||
void updateLocationFailure(QNetworkReply& reply);
|
||||
void certificateInfoSuccess(QNetworkReply& reply);
|
||||
void certificateInfoFailure(QNetworkReply& reply);
|
||||
void transferHfcToNodeSuccess(QNetworkReply& reply);
|
||||
void transferHfcToNodeFailure(QNetworkReply& reply);
|
||||
void transferHfcToUsernameSuccess(QNetworkReply& reply);
|
||||
void transferHfcToUsernameFailure(QNetworkReply& reply);
|
||||
void transferAssetToNodeSuccess(QNetworkReply& reply);
|
||||
void transferAssetToNodeFailure(QNetworkReply& reply);
|
||||
void transferAssetToUsernameSuccess(QNetworkReply& reply);
|
||||
void transferAssetToUsernameFailure(QNetworkReply& reply);
|
||||
void alreadyOwnedSuccess(QNetworkReply& reply);
|
||||
void alreadyOwnedFailure(QNetworkReply& reply);
|
||||
void availableUpdatesSuccess(QNetworkReply& reply);
|
||||
|
|
|
@ -36,8 +36,8 @@ QmlCommerce::QmlCommerce() {
|
|||
connect(ledger.data(), &Ledger::certificateInfoResult, this, &QmlCommerce::certificateInfoResult);
|
||||
connect(ledger.data(), &Ledger::alreadyOwnedResult, this, &QmlCommerce::alreadyOwnedResult);
|
||||
connect(ledger.data(), &Ledger::updateCertificateStatus, this, &QmlCommerce::updateCertificateStatus);
|
||||
connect(ledger.data(), &Ledger::transferHfcToNodeResult, this, &QmlCommerce::transferHfcToNodeResult);
|
||||
connect(ledger.data(), &Ledger::transferHfcToUsernameResult, this, &QmlCommerce::transferHfcToUsernameResult);
|
||||
connect(ledger.data(), &Ledger::transferAssetToNodeResult, this, &QmlCommerce::transferAssetToNodeResult);
|
||||
connect(ledger.data(), &Ledger::transferAssetToUsernameResult, this, &QmlCommerce::transferAssetToUsernameResult);
|
||||
connect(ledger.data(), &Ledger::availableUpdatesResult, this, &QmlCommerce::availableUpdatesResult);
|
||||
connect(ledger.data(), &Ledger::updateItemResult, this, &QmlCommerce::updateItemResult);
|
||||
|
||||
|
@ -166,28 +166,28 @@ void QmlCommerce::certificateInfo(const QString& certificateId) {
|
|||
ledger->certificateInfo(certificateId);
|
||||
}
|
||||
|
||||
void QmlCommerce::transferHfcToNode(const QString& nodeID, const int& amount, const QString& optionalMessage) {
|
||||
void QmlCommerce::transferAssetToNode(const QString& nodeID, const QString& certificateID, const int& amount, const QString& optionalMessage) {
|
||||
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 buyResult(result);
|
||||
return emit transferAssetToNodeResult(result);
|
||||
}
|
||||
QString key = keys[0];
|
||||
ledger->transferHfcToNode(key, nodeID, amount, optionalMessage);
|
||||
ledger->transferAssetToNode(key, nodeID, certificateID, amount, optionalMessage);
|
||||
}
|
||||
|
||||
void QmlCommerce::transferHfcToUsername(const QString& username, const int& amount, const QString& optionalMessage) {
|
||||
void QmlCommerce::transferAssetToUsername(const QString& username, const QString& certificateID, const int& amount, const QString& optionalMessage) {
|
||||
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 buyResult(result);
|
||||
return emit transferAssetToUsernameResult(result);
|
||||
}
|
||||
QString key = keys[0];
|
||||
ledger->transferHfcToUsername(key, username, amount, optionalMessage);
|
||||
ledger->transferAssetToUsername(key, username, certificateID, amount, optionalMessage);
|
||||
}
|
||||
|
||||
void QmlCommerce::replaceContentSet(const QString& itemHref, const QString& certificateID) {
|
||||
|
|
|
@ -48,8 +48,8 @@ signals:
|
|||
|
||||
void updateCertificateStatus(const QString& certID, uint certStatus);
|
||||
|
||||
void transferHfcToNodeResult(QJsonObject result);
|
||||
void transferHfcToUsernameResult(QJsonObject result);
|
||||
void transferAssetToNodeResult(QJsonObject result);
|
||||
void transferAssetToUsernameResult(QJsonObject result);
|
||||
|
||||
void contentSetChanged(const QString& contentSetHref);
|
||||
|
||||
|
@ -81,8 +81,8 @@ protected:
|
|||
Q_INVOKABLE void certificateInfo(const QString& certificateId);
|
||||
Q_INVOKABLE void alreadyOwned(const QString& marketplaceId);
|
||||
|
||||
Q_INVOKABLE void transferHfcToNode(const QString& nodeID, const int& amount, const QString& optionalMessage);
|
||||
Q_INVOKABLE void transferHfcToUsername(const QString& username, const int& amount, const QString& optionalMessage);
|
||||
Q_INVOKABLE void transferAssetToNode(const QString& nodeID, const QString& certificateID, const int& amount, const QString& optionalMessage);
|
||||
Q_INVOKABLE void transferAssetToUsername(const QString& username, const QString& certificateID, const int& amount, const QString& optionalMessage);
|
||||
|
||||
Q_INVOKABLE void replaceContentSet(const QString& itemHref, const QString& certificateID);
|
||||
|
||||
|
|
|
@ -727,7 +727,7 @@ QVector<QUuid> EntityScriptingInterface::findEntitiesByType(const QString entity
|
|||
|
||||
foreach(EntityItemPointer entity, entities) {
|
||||
if (entity->getType() == type) {
|
||||
result << entity->getEntityItemID();
|
||||
result << entity->getEntityItemID().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,140 +11,16 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
/*global XXX */
|
||||
/* global getConnectionData */
|
||||
|
||||
(function () { // BEGIN LOCAL_SCOPE
|
||||
Script.include("/~/system/libraries/accountUtils.js");
|
||||
var request = Script.require('request').request;
|
||||
Script.include("/~/system/libraries/connectionUtils.js");
|
||||
|
||||
var MARKETPLACE_URL = Account.metaverseServerURL + "/marketplace";
|
||||
|
||||
// Function Name: onButtonClicked()
|
||||
//
|
||||
// Description:
|
||||
// -Fired when the app button is pressed.
|
||||
//
|
||||
// Relevant Variables:
|
||||
// -WALLET_QML_SOURCE: The path to the Wallet QML
|
||||
// -onWalletScreen: true/false depending on whether we're looking at the app.
|
||||
var WALLET_QML_SOURCE = "hifi/commerce/wallet/Wallet.qml";
|
||||
var MARKETPLACE_PURCHASES_QML_PATH = "hifi/commerce/purchases/Purchases.qml";
|
||||
var onWalletScreen = false;
|
||||
function onButtonClicked() {
|
||||
if (!tablet) {
|
||||
print("Warning in buttonClicked(): 'tablet' undefined!");
|
||||
return;
|
||||
}
|
||||
if (onWalletScreen) {
|
||||
// for toolbar-mode: go back to home screen, this will close the window.
|
||||
tablet.gotoHomeScreen();
|
||||
} else {
|
||||
tablet.loadQMLSource(WALLET_QML_SOURCE);
|
||||
}
|
||||
}
|
||||
|
||||
// Function Name: sendToQml()
|
||||
//
|
||||
// Description:
|
||||
// -Use this function to send a message to the QML (i.e. to change appearances). The "message" argument is what is sent to
|
||||
// the QML in the format "{method, params}", like json-rpc. See also fromQml().
|
||||
function sendToQml(message) {
|
||||
tablet.sendToQml(message);
|
||||
}
|
||||
|
||||
//***********************************************
|
||||
//
|
||||
// BEGIN Connection logic
|
||||
//
|
||||
//***********************************************
|
||||
// Function Names:
|
||||
// - requestJSON
|
||||
// - getAvailableConnections
|
||||
// - getInfoAboutUser
|
||||
// - getConnectionData
|
||||
//
|
||||
// Description:
|
||||
// - Update all the usernames that I am entitled to see, using my login but not dependent on canKick.
|
||||
var METAVERSE_BASE = Account.metaverseServerURL;
|
||||
function requestJSON(url, callback) { // callback(data) if successfull. Logs otherwise.
|
||||
request({
|
||||
uri: url
|
||||
}, function (error, response) {
|
||||
if (error || (response.status !== 'success')) {
|
||||
print("Error: unable to get", url, error || response.status);
|
||||
return;
|
||||
}
|
||||
callback(response.data);
|
||||
});
|
||||
}
|
||||
function getAvailableConnections(domain, callback) { // callback([{usename, location}...]) if successful. (Logs otherwise)
|
||||
url = METAVERSE_BASE + '/api/v1/users?per_page=400&'
|
||||
if (domain) {
|
||||
url += 'status=' + domain.slice(1, -1); // without curly braces
|
||||
} else {
|
||||
url += 'filter=connections'; // regardless of whether online
|
||||
}
|
||||
requestJSON(url, function (connectionsData) {
|
||||
callback(connectionsData.users);
|
||||
});
|
||||
}
|
||||
function getInfoAboutUser(specificUsername, callback) {
|
||||
url = METAVERSE_BASE + '/api/v1/users?filter=connections'
|
||||
requestJSON(url, function (connectionsData) {
|
||||
for (user in connectionsData.users) {
|
||||
if (connectionsData.users[user].username === specificUsername) {
|
||||
callback(connectionsData.users[user]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
callback(false);
|
||||
});
|
||||
}
|
||||
function getConnectionData(specificUsername, domain) {
|
||||
function frob(user) { // get into the right format
|
||||
var formattedSessionId = user.location.node_id || '';
|
||||
if (formattedSessionId !== '' && formattedSessionId.indexOf("{") != 0) {
|
||||
formattedSessionId = "{" + formattedSessionId + "}";
|
||||
}
|
||||
return {
|
||||
sessionId: formattedSessionId,
|
||||
userName: user.username,
|
||||
connection: user.connection,
|
||||
profileUrl: user.images.thumbnail,
|
||||
placeName: (user.location.root || user.location.domain || {}).name || ''
|
||||
};
|
||||
}
|
||||
if (specificUsername) {
|
||||
getInfoAboutUser(specificUsername, function (user) {
|
||||
if (user) {
|
||||
updateUser(frob(user));
|
||||
} else {
|
||||
print('Error: Unable to find information about ' + specificUsername + ' in connectionsData!');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
getAvailableConnections(domain, function (users) {
|
||||
if (domain) {
|
||||
users.forEach(function (user) {
|
||||
updateUser(frob(user));
|
||||
});
|
||||
} else {
|
||||
sendToQml({ method: 'updateConnections', connections: users.map(frob) });
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
//***********************************************
|
||||
//
|
||||
// END Connection logic
|
||||
//
|
||||
//***********************************************
|
||||
|
||||
//***********************************************
|
||||
//
|
||||
// BEGIN Avatar Selector logic
|
||||
//
|
||||
//***********************************************
|
||||
// BEGIN AVATAR SELECTOR LOGIC
|
||||
var UNSELECTED_TEXTURES = {
|
||||
"idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-idle.png"),
|
||||
"idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-idle.png")
|
||||
|
@ -415,7 +291,7 @@
|
|||
userName: ''
|
||||
};
|
||||
sendToQml(message);
|
||||
|
||||
|
||||
ExtendedOverlay.some(function (overlay) {
|
||||
var id = overlay.key;
|
||||
var selected = ExtendedOverlay.isSelected(id);
|
||||
|
@ -521,11 +397,40 @@
|
|||
triggerMapping.from(Controller.Standard.LTClick).peek().to(makeClickHandler(Controller.Standard.LeftHand));
|
||||
triggerPressMapping.from(Controller.Standard.RT).peek().to(makePressHandler(Controller.Standard.RightHand));
|
||||
triggerPressMapping.from(Controller.Standard.LT).peek().to(makePressHandler(Controller.Standard.LeftHand));
|
||||
//***********************************************
|
||||
// END AVATAR SELECTOR LOGIC
|
||||
|
||||
// Function Name: onButtonClicked()
|
||||
//
|
||||
// END Avatar Selector logic
|
||||
// Description:
|
||||
// -Fired when the app button is pressed.
|
||||
//
|
||||
//***********************************************
|
||||
// Relevant Variables:
|
||||
// -WALLET_QML_SOURCE: The path to the Wallet QML
|
||||
// -onWalletScreen: true/false depending on whether we're looking at the app.
|
||||
var WALLET_QML_SOURCE = "hifi/commerce/wallet/Wallet.qml";
|
||||
var MARKETPLACE_PURCHASES_QML_PATH = "hifi/commerce/purchases/Purchases.qml";
|
||||
var onWalletScreen = false;
|
||||
function onButtonClicked() {
|
||||
if (!tablet) {
|
||||
print("Warning in buttonClicked(): 'tablet' undefined!");
|
||||
return;
|
||||
}
|
||||
if (onWalletScreen) {
|
||||
// for toolbar-mode: go back to home screen, this will close the window.
|
||||
tablet.gotoHomeScreen();
|
||||
} else {
|
||||
tablet.loadQMLSource(WALLET_QML_SOURCE);
|
||||
}
|
||||
}
|
||||
|
||||
// Function Name: sendToQml()
|
||||
//
|
||||
// Description:
|
||||
// -Use this function to send a message to the QML (i.e. to change appearances). The "message" argument is what is sent to
|
||||
// the QML in the format "{method, params}", like json-rpc. See also fromQml().
|
||||
function sendToQml(message) {
|
||||
tablet.sendToQml(message);
|
||||
}
|
||||
|
||||
var sendMoneyRecipient;
|
||||
var sendMoneyParticleEffectUpdateTimer;
|
||||
|
@ -678,18 +583,23 @@
|
|||
}
|
||||
removeOverlays();
|
||||
break;
|
||||
case 'sendMoney_sendPublicly':
|
||||
deleteSendMoneyParticleEffect();
|
||||
sendMoneyRecipient = message.recipient;
|
||||
var amount = message.amount;
|
||||
var props = SEND_MONEY_PARTICLE_PROPERTIES;
|
||||
props.parentID = MyAvatar.sessionUUID;
|
||||
props.position = MyAvatar.position;
|
||||
props.position.y += 0.2;
|
||||
sendMoneyParticleEffect = Entities.addEntity(props, true);
|
||||
particleEffectTimestamp = Date.now();
|
||||
updateSendMoneyParticleEffect();
|
||||
sendMoneyParticleEffectUpdateTimer = Script.setInterval(updateSendMoneyParticleEffect, SEND_MONEY_PARTICLE_TIMER_UPDATE);
|
||||
case 'sendAsset_sendPublicly':
|
||||
if (message.assetName === "") {
|
||||
deleteSendMoneyParticleEffect();
|
||||
sendMoneyRecipient = message.recipient;
|
||||
var amount = message.amount;
|
||||
var props = SEND_MONEY_PARTICLE_PROPERTIES;
|
||||
props.parentID = MyAvatar.sessionUUID;
|
||||
props.position = MyAvatar.position;
|
||||
props.position.y += 0.2;
|
||||
if (message.effectImage) {
|
||||
props.textures = message.effectImage;
|
||||
}
|
||||
sendMoneyParticleEffect = Entities.addEntity(props, true);
|
||||
particleEffectTimestamp = Date.now();
|
||||
updateSendMoneyParticleEffect();
|
||||
sendMoneyParticleEffectUpdateTimer = Script.setInterval(updateSendMoneyParticleEffect, SEND_MONEY_PARTICLE_TIMER_UPDATE);
|
||||
}
|
||||
break;
|
||||
case 'transactionHistory_goToBank':
|
||||
if (Account.metaverseServerURL.indexOf("staging") >= 0) {
|
||||
|
|
94
scripts/system/libraries/connectionUtils.js
Normal file
|
@ -0,0 +1,94 @@
|
|||
//
|
||||
// connectionUtils.js
|
||||
// scripts/system/libraries
|
||||
//
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
|
||||
// Function Names:
|
||||
// - requestJSON
|
||||
// - getAvailableConnections
|
||||
// - getInfoAboutUser
|
||||
// - getConnectionData
|
||||
//
|
||||
// Description:
|
||||
// - Update all the usernames that I am entitled to see, using my login but not dependent on canKick.
|
||||
var request = Script.require('request').request;
|
||||
var METAVERSE_BASE = Account.metaverseServerURL;
|
||||
function requestJSON(url, callback) { // callback(data) if successfull. Logs otherwise.
|
||||
request({
|
||||
uri: url
|
||||
}, function (error, response) {
|
||||
if (error || (response.status !== 'success')) {
|
||||
print("Error: unable to get", url, error || response.status);
|
||||
return;
|
||||
}
|
||||
callback(response.data);
|
||||
});
|
||||
}
|
||||
function getAvailableConnections(domain, callback) { // callback([{usename, location}...]) if successful. (Logs otherwise)
|
||||
url = METAVERSE_BASE + '/api/v1/users?per_page=400&'
|
||||
if (domain) {
|
||||
url += 'status=' + domain.slice(1, -1); // without curly braces
|
||||
} else {
|
||||
url += 'filter=connections'; // regardless of whether online
|
||||
}
|
||||
requestJSON(url, function (connectionsData) {
|
||||
callback(connectionsData.users);
|
||||
});
|
||||
}
|
||||
function getInfoAboutUser(specificUsername, callback) {
|
||||
url = METAVERSE_BASE + '/api/v1/users?filter=connections'
|
||||
requestJSON(url, function (connectionsData) {
|
||||
for (user in connectionsData.users) {
|
||||
if (connectionsData.users[user].username === specificUsername) {
|
||||
callback(connectionsData.users[user]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
callback(false);
|
||||
});
|
||||
}
|
||||
getConnectionData = function getConnectionData(specificUsername, domain) {
|
||||
function frob(user) { // get into the right format
|
||||
var formattedSessionId = user.location.node_id || '';
|
||||
if (formattedSessionId !== '' && formattedSessionId.indexOf("{") != 0) {
|
||||
formattedSessionId = "{" + formattedSessionId + "}";
|
||||
}
|
||||
return {
|
||||
sessionId: formattedSessionId,
|
||||
userName: user.username,
|
||||
connection: user.connection,
|
||||
profileUrl: user.images.thumbnail,
|
||||
placeName: (user.location.root || user.location.domain || {}).name || ''
|
||||
};
|
||||
}
|
||||
if (specificUsername) {
|
||||
getInfoAboutUser(specificUsername, function (user) {
|
||||
if (user) {
|
||||
updateUser(frob(user));
|
||||
} else {
|
||||
print('Error: Unable to find information about ' + specificUsername + ' in connectionsData!');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
getAvailableConnections(domain, function (users) {
|
||||
if (domain) {
|
||||
users.forEach(function (user) {
|
||||
updateUser(frob(user));
|
||||
});
|
||||
} else {
|
||||
sendToQml({ method: 'updateConnections', connections: users.map(frob) });
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Function Name: sendToQml()
|
||||
//
|
||||
// Description:
|
||||
// -Use this function to send a message to the QML (i.e. to change appearances). The "message" argument is what is sent to
|
||||
// the QML in the format "{method, params}", like json-rpc. See also fromQml().
|
||||
function sendToQml(message) {
|
||||
Tablet.getTablet("com.highfidelity.interface.tablet.system").sendToQml(message);
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
//
|
||||
|
||||
/* global Tablet, Script, HMD, UserActivityLogger, Entities, Account, Wallet, ContextOverlay, Settings, Camera, Vec3,
|
||||
Quat, MyAvatar, Clipboard, Menu, Grid, Uuid, GlobalServices, openLoginWindow, Overlays, SoundCache,
|
||||
Quat, MyAvatar, Clipboard, Menu, Grid, Uuid, GlobalServices, openLoginWindow, getConnectionData, Overlays, SoundCache,
|
||||
DesktopPreviewProvider */
|
||||
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
|
||||
|
||||
|
@ -61,8 +61,6 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
}
|
||||
}
|
||||
|
||||
Window.messageBoxClosed.connect(onMessageBoxClosed);
|
||||
|
||||
var onMarketplaceScreen = false;
|
||||
var onCommerceScreen = false;
|
||||
|
||||
|
@ -74,7 +72,7 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
} else {
|
||||
tablet.pushOntoStack(MARKETPLACE_CHECKOUT_QML_PATH);
|
||||
tablet.sendToQml({
|
||||
sendToQml({
|
||||
method: 'updateCheckoutQML', params: {
|
||||
itemId: '424611a2-73d0-4c03-9087-26a6a279257b',
|
||||
itemName: '2018-02-15 Finnegon',
|
||||
|
@ -86,23 +84,13 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
}
|
||||
}
|
||||
|
||||
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({
|
||||
icon: NORMAL_ICON,
|
||||
activeIcon: NORMAL_ACTIVE,
|
||||
text: "MARKET",
|
||||
sortOrder: 9
|
||||
});
|
||||
|
||||
function messagesWaiting(isWaiting) {
|
||||
marketplaceButton.editProperties({
|
||||
icon: (isWaiting ? WAITING_ICON : NORMAL_ICON),
|
||||
activeIcon: (isWaiting ? WAITING_ACTIVE : NORMAL_ACTIVE)
|
||||
});
|
||||
if (marketplaceButton) {
|
||||
marketplaceButton.editProperties({
|
||||
icon: (isWaiting ? WAITING_ICON : NORMAL_ICON),
|
||||
activeIcon: (isWaiting ? WAITING_ACTIVE : NORMAL_ACTIVE)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onCanWriteAssetsChanged() {
|
||||
|
@ -110,26 +98,8 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
tablet.emitScriptEvent(message);
|
||||
}
|
||||
|
||||
function onClick() {
|
||||
if (onMarketplaceScreen || onCommerceScreen) {
|
||||
// for toolbar-mode: go back to home screen, this will close the window.
|
||||
tablet.gotoHomeScreen();
|
||||
} else {
|
||||
Wallet.refreshWalletStatus();
|
||||
if (HMD.tabletID) {
|
||||
Entities.editEntity(HMD.tabletID, { textures: JSON.stringify({ "tex.close": HOME_BUTTON_TEXTURE }) });
|
||||
}
|
||||
showMarketplace();
|
||||
}
|
||||
}
|
||||
|
||||
var referrerURL; // Used for updating Purchases QML
|
||||
var filterText; // Used for updating Purchases QML
|
||||
|
||||
var onWalletScreen = false;
|
||||
var onCommerceScreen = false;
|
||||
var tabletShouldBeVisibleInSecondaryCamera = false;
|
||||
|
||||
function setTabletVisibleInSecondaryCamera(visibleInSecondaryCam) {
|
||||
if (visibleInSecondaryCam) {
|
||||
// if we're potentially showing the tablet, only do so if it was visible before
|
||||
|
@ -147,48 +117,6 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
Overlays.editOverlay(HMD.tabletScreenID, { isVisibleInSecondaryCamera : visibleInSecondaryCam });
|
||||
}
|
||||
|
||||
function onScreenChanged(type, url) {
|
||||
onMarketplaceScreen = type === "Web" && url.indexOf(MARKETPLACE_URL) !== -1;
|
||||
var onWalletScreenNow = url.indexOf(MARKETPLACE_WALLET_QML_PATH) !== -1;
|
||||
var onCommerceScreenNow = type === "QML" && (url.indexOf(MARKETPLACE_CHECKOUT_QML_PATH) !== -1 || url === MARKETPLACE_PURCHASES_QML_PATH
|
||||
|| url.indexOf(MARKETPLACE_INSPECTIONCERTIFICATE_QML_PATH) !== -1);
|
||||
|
||||
if ((!onWalletScreenNow && onWalletScreen) || (!onCommerceScreenNow && onCommerceScreen)) { // exiting wallet or commerce screen
|
||||
if (isHmdPreviewDisabledBySecurity) {
|
||||
DesktopPreviewProvider.setPreviewDisabledReason("USER");
|
||||
Menu.setIsOptionChecked("Disable Preview", false);
|
||||
setTabletVisibleInSecondaryCamera(true);
|
||||
isHmdPreviewDisabledBySecurity = false;
|
||||
}
|
||||
}
|
||||
|
||||
onCommerceScreen = onCommerceScreenNow;
|
||||
onWalletScreen = onWalletScreenNow;
|
||||
wireEventBridge(onMarketplaceScreen || onCommerceScreen || onWalletScreen);
|
||||
|
||||
if (url === MARKETPLACE_PURCHASES_QML_PATH) {
|
||||
tablet.sendToQml({
|
||||
method: 'updatePurchases',
|
||||
referrerURL: referrerURL,
|
||||
filterText: filterText
|
||||
});
|
||||
}
|
||||
|
||||
// for toolbar mode: change button to active when window is first openend, false otherwise.
|
||||
marketplaceButton.editProperties({ isActive: (onMarketplaceScreen || onCommerceScreen) && !onWalletScreen });
|
||||
if (type === "Web" && url.indexOf(MARKETPLACE_URL) !== -1) {
|
||||
ContextOverlay.isInMarketplaceInspectionMode = true;
|
||||
} else {
|
||||
ContextOverlay.isInMarketplaceInspectionMode = false;
|
||||
}
|
||||
|
||||
if (!onCommerceScreen) {
|
||||
tablet.sendToQml({
|
||||
method: 'inspectionCertificate_resetCert'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function openWallet() {
|
||||
tablet.pushOntoStack(MARKETPLACE_WALLET_QML_PATH);
|
||||
}
|
||||
|
@ -196,7 +124,7 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
function setCertificateInfo(currentEntityWithContextOverlay, itemCertificateId) {
|
||||
wireEventBridge(true);
|
||||
var certificateId = itemCertificateId || (Entities.getEntityProperties(currentEntityWithContextOverlay, ['certificateID']).certificateID);
|
||||
tablet.sendToQml({
|
||||
sendToQml({
|
||||
method: 'inspectionCertificate_setCertificateId',
|
||||
entityId: currentEntityWithContextOverlay,
|
||||
certificateId: certificateId
|
||||
|
@ -224,6 +152,385 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
}));
|
||||
}
|
||||
|
||||
// BEGIN AVATAR SELECTOR LOGIC
|
||||
var UNSELECTED_TEXTURES = {
|
||||
"idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-idle.png"),
|
||||
"idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-idle.png")
|
||||
};
|
||||
var SELECTED_TEXTURES = {
|
||||
"idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-selected.png"),
|
||||
"idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-selected.png")
|
||||
};
|
||||
var HOVER_TEXTURES = {
|
||||
"idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-hover.png"),
|
||||
"idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-hover.png")
|
||||
};
|
||||
|
||||
var UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6 };
|
||||
var SELECTED_COLOR = { red: 0xF3, green: 0x91, blue: 0x29 };
|
||||
var HOVER_COLOR = { red: 0xD0, green: 0xD0, blue: 0xD0 };
|
||||
var conserveResources = true;
|
||||
|
||||
var overlays = {}; // Keeps track of all our extended overlay data objects, keyed by target identifier.
|
||||
|
||||
function ExtendedOverlay(key, type, properties, selected, hasModel) { // A wrapper around overlays to store the key it is associated with.
|
||||
overlays[key] = this;
|
||||
if (hasModel) {
|
||||
var modelKey = key + "-m";
|
||||
this.model = new ExtendedOverlay(modelKey, "model", {
|
||||
url: Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx"),
|
||||
textures: textures(selected),
|
||||
ignoreRayIntersection: true
|
||||
}, false, false);
|
||||
} else {
|
||||
this.model = undefined;
|
||||
}
|
||||
this.key = key;
|
||||
this.selected = selected || false; // not undefined
|
||||
this.hovering = false;
|
||||
this.activeOverlay = Overlays.addOverlay(type, properties); // We could use different overlays for (un)selected...
|
||||
}
|
||||
// Instance methods:
|
||||
ExtendedOverlay.prototype.deleteOverlay = function () { // remove display and data of this overlay
|
||||
Overlays.deleteOverlay(this.activeOverlay);
|
||||
delete overlays[this.key];
|
||||
};
|
||||
|
||||
ExtendedOverlay.prototype.editOverlay = function (properties) { // change display of this overlay
|
||||
Overlays.editOverlay(this.activeOverlay, properties);
|
||||
};
|
||||
|
||||
function color(selected, hovering) {
|
||||
var base = hovering ? HOVER_COLOR : selected ? SELECTED_COLOR : UNSELECTED_COLOR;
|
||||
function scale(component) {
|
||||
var delta = 0xFF - component;
|
||||
return component;
|
||||
}
|
||||
return { red: scale(base.red), green: scale(base.green), blue: scale(base.blue) };
|
||||
}
|
||||
|
||||
function textures(selected, hovering) {
|
||||
return hovering ? HOVER_TEXTURES : selected ? SELECTED_TEXTURES : UNSELECTED_TEXTURES;
|
||||
}
|
||||
// so we don't have to traverse the overlays to get the last one
|
||||
var lastHoveringId = 0;
|
||||
ExtendedOverlay.prototype.hover = function (hovering) {
|
||||
this.hovering = hovering;
|
||||
if (this.key === lastHoveringId) {
|
||||
if (hovering) {
|
||||
return;
|
||||
}
|
||||
lastHoveringId = 0;
|
||||
}
|
||||
this.editOverlay({ color: color(this.selected, hovering) });
|
||||
if (this.model) {
|
||||
this.model.editOverlay({ textures: textures(this.selected, hovering) });
|
||||
}
|
||||
if (hovering) {
|
||||
// un-hover the last hovering overlay
|
||||
if (lastHoveringId && lastHoveringId !== this.key) {
|
||||
ExtendedOverlay.get(lastHoveringId).hover(false);
|
||||
}
|
||||
lastHoveringId = this.key;
|
||||
}
|
||||
};
|
||||
ExtendedOverlay.prototype.select = function (selected) {
|
||||
if (this.selected === selected) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.editOverlay({ color: color(selected, this.hovering) });
|
||||
if (this.model) {
|
||||
this.model.editOverlay({ textures: textures(selected) });
|
||||
}
|
||||
this.selected = selected;
|
||||
};
|
||||
// Class methods:
|
||||
var selectedIds = [];
|
||||
ExtendedOverlay.isSelected = function (id) {
|
||||
return -1 !== selectedIds.indexOf(id);
|
||||
};
|
||||
ExtendedOverlay.get = function (key) { // answer the extended overlay data object associated with the given avatar identifier
|
||||
return overlays[key];
|
||||
};
|
||||
ExtendedOverlay.some = function (iterator) { // Bails early as soon as iterator returns truthy.
|
||||
var key;
|
||||
for (key in overlays) {
|
||||
if (iterator(ExtendedOverlay.get(key))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
ExtendedOverlay.unHover = function () { // calls hover(false) on lastHoveringId (if any)
|
||||
if (lastHoveringId) {
|
||||
ExtendedOverlay.get(lastHoveringId).hover(false);
|
||||
}
|
||||
};
|
||||
|
||||
// hit(overlay) on the one overlay intersected by pickRay, if any.
|
||||
// noHit() if no ExtendedOverlay was intersected (helps with hover)
|
||||
ExtendedOverlay.applyPickRay = function (pickRay, hit, noHit) {
|
||||
var pickedOverlay = Overlays.findRayIntersection(pickRay); // Depends on nearer coverOverlays to extend closer to us than farther ones.
|
||||
if (!pickedOverlay.intersects) {
|
||||
if (noHit) {
|
||||
return noHit();
|
||||
}
|
||||
return;
|
||||
}
|
||||
ExtendedOverlay.some(function (overlay) { // See if pickedOverlay is one of ours.
|
||||
if ((overlay.activeOverlay) === pickedOverlay.overlayID) {
|
||||
hit(overlay);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function HighlightedEntity(id, entityProperties) {
|
||||
this.id = id;
|
||||
this.overlay = Overlays.addOverlay('cube', {
|
||||
position: entityProperties.position,
|
||||
rotation: entityProperties.rotation,
|
||||
dimensions: entityProperties.dimensions,
|
||||
solid: false,
|
||||
color: {
|
||||
red: 0xF3,
|
||||
green: 0x91,
|
||||
blue: 0x29
|
||||
},
|
||||
ignoreRayIntersection: true,
|
||||
drawInFront: false // Arguable. For now, let's not distract with mysterious wires around the scene.
|
||||
});
|
||||
HighlightedEntity.overlays.push(this);
|
||||
}
|
||||
HighlightedEntity.overlays = [];
|
||||
HighlightedEntity.clearOverlays = function clearHighlightedEntities() {
|
||||
HighlightedEntity.overlays.forEach(function (highlighted) {
|
||||
Overlays.deleteOverlay(highlighted.overlay);
|
||||
});
|
||||
HighlightedEntity.overlays = [];
|
||||
};
|
||||
HighlightedEntity.updateOverlays = function updateHighlightedEntities() {
|
||||
HighlightedEntity.overlays.forEach(function (highlighted) {
|
||||
var properties = Entities.getEntityProperties(highlighted.id, ['position', 'rotation', 'dimensions']);
|
||||
Overlays.editOverlay(highlighted.overlay, {
|
||||
position: properties.position,
|
||||
rotation: properties.rotation,
|
||||
dimensions: properties.dimensions
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
function addAvatarNode(id) {
|
||||
var selected = ExtendedOverlay.isSelected(id);
|
||||
return new ExtendedOverlay(id, "sphere", {
|
||||
drawInFront: true,
|
||||
solid: true,
|
||||
alpha: 0.8,
|
||||
color: color(selected, false),
|
||||
ignoreRayIntersection: false
|
||||
}, selected, !conserveResources);
|
||||
}
|
||||
|
||||
var pingPong = true;
|
||||
function updateOverlays() {
|
||||
var eye = Camera.position;
|
||||
AvatarList.getAvatarIdentifiers().forEach(function (id) {
|
||||
if (!id) {
|
||||
return; // don't update ourself, or avatars we're not interested in
|
||||
}
|
||||
var avatar = AvatarList.getAvatar(id);
|
||||
if (!avatar) {
|
||||
return; // will be deleted below if there had been an overlay.
|
||||
}
|
||||
var overlay = ExtendedOverlay.get(id);
|
||||
if (!overlay) { // For now, we're treating this as a temporary loss, as from the personal space bubble. Add it back.
|
||||
overlay = addAvatarNode(id);
|
||||
}
|
||||
var target = avatar.position;
|
||||
var distance = Vec3.distance(target, eye);
|
||||
var offset = 0.2;
|
||||
var diff = Vec3.subtract(target, eye); // get diff between target and eye (a vector pointing to the eye from avatar position)
|
||||
var headIndex = avatar.getJointIndex("Head"); // base offset on 1/2 distance from hips to head if we can
|
||||
if (headIndex > 0) {
|
||||
offset = avatar.getAbsoluteJointTranslationInObjectFrame(headIndex).y / 2;
|
||||
}
|
||||
|
||||
// move a bit in front, towards the camera
|
||||
target = Vec3.subtract(target, Vec3.multiply(Vec3.normalize(diff), offset));
|
||||
|
||||
// now bump it up a bit
|
||||
target.y = target.y + offset;
|
||||
|
||||
overlay.ping = pingPong;
|
||||
overlay.editOverlay({
|
||||
color: color(ExtendedOverlay.isSelected(id), overlay.hovering),
|
||||
position: target,
|
||||
dimensions: 0.032 * distance
|
||||
});
|
||||
if (overlay.model) {
|
||||
overlay.model.ping = pingPong;
|
||||
overlay.model.editOverlay({
|
||||
position: target,
|
||||
scale: 0.2 * distance, // constant apparent size
|
||||
rotation: Camera.orientation
|
||||
});
|
||||
}
|
||||
});
|
||||
pingPong = !pingPong;
|
||||
ExtendedOverlay.some(function (overlay) { // Remove any that weren't updated. (User is gone.)
|
||||
if (overlay.ping === pingPong) {
|
||||
overlay.deleteOverlay();
|
||||
}
|
||||
});
|
||||
// We could re-populateNearbyUserList if anything added or removed, but not for now.
|
||||
HighlightedEntity.updateOverlays();
|
||||
}
|
||||
function removeOverlays() {
|
||||
selectedIds = [];
|
||||
lastHoveringId = 0;
|
||||
HighlightedEntity.clearOverlays();
|
||||
ExtendedOverlay.some(function (overlay) {
|
||||
overlay.deleteOverlay();
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// Clicks.
|
||||
//
|
||||
function usernameFromIDReply(id, username, machineFingerprint, isAdmin) {
|
||||
if (selectedIds[0] === id) {
|
||||
var message = {
|
||||
method: 'updateSelectedRecipientUsername',
|
||||
userName: username === "" ? "unknown username" : username
|
||||
};
|
||||
sendToQml(message);
|
||||
}
|
||||
}
|
||||
function handleClick(pickRay) {
|
||||
ExtendedOverlay.applyPickRay(pickRay, function (overlay) {
|
||||
var nextSelectedStatus = !overlay.selected;
|
||||
var avatarId = overlay.key;
|
||||
selectedIds = nextSelectedStatus ? [avatarId] : [];
|
||||
if (nextSelectedStatus) {
|
||||
Users.requestUsernameFromID(avatarId);
|
||||
}
|
||||
var message = {
|
||||
method: 'selectRecipient',
|
||||
id: [avatarId],
|
||||
isSelected: nextSelectedStatus,
|
||||
displayName: '"' + AvatarList.getAvatar(avatarId).sessionDisplayName + '"',
|
||||
userName: ''
|
||||
};
|
||||
sendToQml(message);
|
||||
|
||||
ExtendedOverlay.some(function (overlay) {
|
||||
var id = overlay.key;
|
||||
var selected = ExtendedOverlay.isSelected(id);
|
||||
overlay.select(selected);
|
||||
});
|
||||
|
||||
HighlightedEntity.clearOverlays();
|
||||
if (selectedIds.length) {
|
||||
Entities.findEntitiesInFrustum(Camera.frustum).forEach(function (id) {
|
||||
// Because lastEditedBy is per session, the vast majority of entities won't match,
|
||||
// so it would probably be worth reducing marshalling costs by asking for just we need.
|
||||
// However, providing property name(s) is advisory and some additional properties are
|
||||
// included anyway. As it turns out, asking for 'lastEditedBy' gives 'position', 'rotation',
|
||||
// and 'dimensions', too, so we might as well make use of them instead of making a second
|
||||
// getEntityProperties call.
|
||||
// It would be nice if we could harden this against future changes by specifying all
|
||||
// and only these four in an array, but see
|
||||
// https://highfidelity.fogbugz.com/f/cases/2728/Entities-getEntityProperties-id-lastEditedBy-name-lastEditedBy-doesn-t-work
|
||||
var properties = Entities.getEntityProperties(id, 'lastEditedBy');
|
||||
if (ExtendedOverlay.isSelected(properties.lastEditedBy)) {
|
||||
new HighlightedEntity(id, properties);
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
function handleMouseEvent(mousePressEvent) { // handleClick if we get one.
|
||||
if (!mousePressEvent.isLeftButton) {
|
||||
return;
|
||||
}
|
||||
handleClick(Camera.computePickRay(mousePressEvent.x, mousePressEvent.y));
|
||||
}
|
||||
function handleMouseMove(pickRay) { // given the pickRay, just do the hover logic
|
||||
ExtendedOverlay.applyPickRay(pickRay, function (overlay) {
|
||||
overlay.hover(true);
|
||||
}, function () {
|
||||
ExtendedOverlay.unHover();
|
||||
});
|
||||
}
|
||||
|
||||
// handy global to keep track of which hand is the mouse (if any)
|
||||
var currentHandPressed = 0;
|
||||
var TRIGGER_CLICK_THRESHOLD = 0.85;
|
||||
var TRIGGER_PRESS_THRESHOLD = 0.05;
|
||||
|
||||
function handleMouseMoveEvent(event) { // find out which overlay (if any) is over the mouse position
|
||||
var pickRay;
|
||||
if (HMD.active) {
|
||||
if (currentHandPressed !== 0) {
|
||||
pickRay = controllerComputePickRay(currentHandPressed);
|
||||
} else {
|
||||
// nothing should hover, so
|
||||
ExtendedOverlay.unHover();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
pickRay = Camera.computePickRay(event.x, event.y);
|
||||
}
|
||||
handleMouseMove(pickRay);
|
||||
}
|
||||
function handleTriggerPressed(hand, value) {
|
||||
// The idea is if you press one trigger, it is the one
|
||||
// we will consider the mouse. Even if the other is pressed,
|
||||
// we ignore it until this one is no longer pressed.
|
||||
var isPressed = value > TRIGGER_PRESS_THRESHOLD;
|
||||
if (currentHandPressed === 0) {
|
||||
currentHandPressed = isPressed ? hand : 0;
|
||||
return;
|
||||
}
|
||||
if (currentHandPressed === hand) {
|
||||
currentHandPressed = isPressed ? hand : 0;
|
||||
return;
|
||||
}
|
||||
// otherwise, the other hand is still triggered
|
||||
// so do nothing.
|
||||
}
|
||||
|
||||
// We get mouseMoveEvents from the handControllers, via handControllerPointer.
|
||||
// But we don't get mousePressEvents.
|
||||
var triggerMapping = Controller.newMapping(Script.resolvePath('') + '-click');
|
||||
var triggerPressMapping = Controller.newMapping(Script.resolvePath('') + '-press');
|
||||
function controllerComputePickRay(hand) {
|
||||
var controllerPose = getControllerWorldLocation(hand, true);
|
||||
if (controllerPose.valid) {
|
||||
return { origin: controllerPose.position, direction: Quat.getUp(controllerPose.orientation) };
|
||||
}
|
||||
}
|
||||
function makeClickHandler(hand) {
|
||||
return function (clicked) {
|
||||
if (clicked > TRIGGER_CLICK_THRESHOLD) {
|
||||
var pickRay = controllerComputePickRay(hand);
|
||||
handleClick(pickRay);
|
||||
}
|
||||
};
|
||||
}
|
||||
function makePressHandler(hand) {
|
||||
return function (value) {
|
||||
handleTriggerPressed(hand, value);
|
||||
};
|
||||
}
|
||||
triggerMapping.from(Controller.Standard.RTClick).peek().to(makeClickHandler(Controller.Standard.RightHand));
|
||||
triggerMapping.from(Controller.Standard.LTClick).peek().to(makeClickHandler(Controller.Standard.LeftHand));
|
||||
triggerPressMapping.from(Controller.Standard.RT).peek().to(makePressHandler(Controller.Standard.RightHand));
|
||||
triggerPressMapping.from(Controller.Standard.LT).peek().to(makePressHandler(Controller.Standard.LeftHand));
|
||||
// END AVATAR SELECTOR LOGIC
|
||||
|
||||
var grid = new Grid();
|
||||
function adjustPositionPerBoundingBox(position, direction, registration, dimensions, orientation) {
|
||||
// Adjust the position such that the bounding box (registration, dimenions, and orientation) lies behind the original
|
||||
|
@ -415,16 +722,9 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
}
|
||||
}
|
||||
|
||||
marketplaceButton.clicked.connect(onClick);
|
||||
tablet.screenChanged.connect(onScreenChanged);
|
||||
Entities.canWriteAssetsChanged.connect(onCanWriteAssetsChanged);
|
||||
ContextOverlay.contextOverlayClicked.connect(setCertificateInfo);
|
||||
GlobalServices.myUsernameChanged.connect(onUsernameChanged);
|
||||
Wallet.walletStatusChanged.connect(sendCommerceSettings);
|
||||
Wallet.refreshWalletStatus();
|
||||
|
||||
var referrerURL; // Used for updating Purchases QML
|
||||
var filterText; // Used for updating Purchases QML
|
||||
function onMessage(message) {
|
||||
|
||||
if (message === GOTO_DIRECTORY) {
|
||||
tablet.gotoWebScreen(MARKETPLACES_URL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
} else if (message === QUERY_CAN_WRITE_ASSETS) {
|
||||
|
@ -456,7 +756,7 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
if (parsedJsonMessage.type === "CHECKOUT") {
|
||||
wireEventBridge(true);
|
||||
tablet.pushOntoStack(MARKETPLACE_CHECKOUT_QML_PATH);
|
||||
tablet.sendToQml({
|
||||
sendToQml({
|
||||
method: 'updateCheckoutQML',
|
||||
params: parsedJsonMessage
|
||||
});
|
||||
|
@ -470,7 +770,7 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
openLoginWindow();
|
||||
} else if (parsedJsonMessage.type === "WALLET_SETUP") {
|
||||
wireEventBridge(true);
|
||||
tablet.sendToQml({
|
||||
sendToQml({
|
||||
method: 'updateWalletReferrer',
|
||||
referrer: "marketplace cta"
|
||||
});
|
||||
|
@ -480,57 +780,112 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
filterText = "";
|
||||
tablet.pushOntoStack(MARKETPLACE_PURCHASES_QML_PATH);
|
||||
wireEventBridge(true);
|
||||
tablet.sendToQml({
|
||||
sendToQml({
|
||||
method: 'purchases_showMyItems'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tablet.webEventReceived.connect(onMessage);
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
if (onMarketplaceScreen || onCommerceScreen) {
|
||||
tablet.gotoHomeScreen();
|
||||
}
|
||||
tablet.removeButton(marketplaceButton);
|
||||
tablet.screenChanged.disconnect(onScreenChanged);
|
||||
ContextOverlay.contextOverlayClicked.disconnect(setCertificateInfo);
|
||||
tablet.webEventReceived.disconnect(onMessage);
|
||||
Entities.canWriteAssetsChanged.disconnect(onCanWriteAssetsChanged);
|
||||
GlobalServices.myUsernameChanged.disconnect(onUsernameChanged);
|
||||
Wallet.walletStatusChanged.disconnect(sendCommerceSettings);
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Function Name: wireEventBridge()
|
||||
//
|
||||
// Description:
|
||||
// -Used to connect/disconnect the script's response to the tablet's "fromQml" signal. Set the "on" argument to enable or
|
||||
// disable to event bridge.
|
||||
//
|
||||
// Relevant Variables:
|
||||
// -hasEventBridge: true/false depending on whether we've already connected the event bridge.
|
||||
var hasEventBridge = false;
|
||||
function wireEventBridge(on) {
|
||||
function onButtonClicked() {
|
||||
if (!tablet) {
|
||||
print("Warning in wireEventBridge(): 'tablet' undefined!");
|
||||
print("Warning in buttonClicked(): 'tablet' undefined!");
|
||||
return;
|
||||
}
|
||||
if (on) {
|
||||
if (!hasEventBridge) {
|
||||
tablet.fromQml.connect(fromQml);
|
||||
hasEventBridge = true;
|
||||
}
|
||||
if (onMarketplaceScreen || onCommerceScreen) {
|
||||
// for toolbar-mode: go back to home screen, this will close the window.
|
||||
tablet.gotoHomeScreen();
|
||||
} else {
|
||||
if (hasEventBridge) {
|
||||
tablet.fromQml.disconnect(fromQml);
|
||||
hasEventBridge = false;
|
||||
if (HMD.tabletID) {
|
||||
Entities.editEntity(HMD.tabletID, { textures: JSON.stringify({ "tex.close": HOME_BUTTON_TEXTURE }) });
|
||||
}
|
||||
showMarketplace();
|
||||
}
|
||||
}
|
||||
|
||||
// Function Name: sendToQml()
|
||||
//
|
||||
// Description:
|
||||
// -Use this function to send a message to the QML (i.e. to change appearances). The "message" argument is what is sent to
|
||||
// the QML in the format "{method, params}", like json-rpc. See also fromQml().
|
||||
function sendToQml(message) {
|
||||
tablet.sendToQml(message);
|
||||
}
|
||||
|
||||
var sendAssetRecipient;
|
||||
var sendAssetParticleEffectUpdateTimer;
|
||||
var particleEffectTimestamp;
|
||||
var sendAssetParticleEffect;
|
||||
var SEND_ASSET_PARTICLE_TIMER_UPDATE = 250;
|
||||
var SEND_ASSET_PARTICLE_EMITTING_DURATION = 3000;
|
||||
var SEND_ASSET_PARTICLE_LIFETIME_SECONDS = 8;
|
||||
var SEND_ASSET_PARTICLE_PROPERTIES = {
|
||||
accelerationSpread: { x: 0, y: 0, z: 0 },
|
||||
alpha: 1,
|
||||
alphaFinish: 1,
|
||||
alphaSpread: 0,
|
||||
alphaStart: 1,
|
||||
azimuthFinish: 0,
|
||||
azimuthStart: -6,
|
||||
color: { red: 255, green: 222, blue: 255 },
|
||||
colorFinish: { red: 255, green: 229, blue: 225 },
|
||||
colorSpread: { red: 0, green: 0, blue: 0 },
|
||||
colorStart: { red: 243, green: 255, blue: 255 },
|
||||
emitAcceleration: { x: 0, y: 0, z: 0 }, // Immediately gets updated to be accurate
|
||||
emitDimensions: { x: 0, y: 0, z: 0 },
|
||||
emitOrientation: { x: 0, y: 0, z: 0 },
|
||||
emitRate: 4,
|
||||
emitSpeed: 2.1,
|
||||
emitterShouldTrail: true,
|
||||
isEmitting: 1,
|
||||
lifespan: SEND_ASSET_PARTICLE_LIFETIME_SECONDS + 1, // Immediately gets updated to be accurate
|
||||
lifetime: SEND_ASSET_PARTICLE_LIFETIME_SECONDS + 1,
|
||||
maxParticles: 20,
|
||||
name: 'asset-particles',
|
||||
particleRadius: 0.2,
|
||||
polarFinish: 0,
|
||||
polarStart: 0,
|
||||
radiusFinish: 0.05,
|
||||
radiusSpread: 0,
|
||||
radiusStart: 0.2,
|
||||
speedSpread: 0,
|
||||
textures: "http://hifi-content.s3.amazonaws.com/alan/dev/Particles/Bokeh-Particle-HFC.png",
|
||||
type: 'ParticleEffect'
|
||||
};
|
||||
|
||||
function updateSendAssetParticleEffect() {
|
||||
var timestampNow = Date.now();
|
||||
if ((timestampNow - particleEffectTimestamp) > (SEND_ASSET_PARTICLE_LIFETIME_SECONDS * 1000)) {
|
||||
deleteSendAssetParticleEffect();
|
||||
return;
|
||||
} else if ((timestampNow - particleEffectTimestamp) > SEND_ASSET_PARTICLE_EMITTING_DURATION) {
|
||||
Entities.editEntity(sendAssetParticleEffect, {
|
||||
isEmitting: 0
|
||||
});
|
||||
} else if (sendAssetParticleEffect) {
|
||||
var recipientPosition = AvatarList.getAvatar(sendAssetRecipient).position;
|
||||
var distance = Vec3.distance(recipientPosition, MyAvatar.position);
|
||||
var accel = Vec3.subtract(recipientPosition, MyAvatar.position);
|
||||
accel.y -= 3.0;
|
||||
var life = Math.sqrt(2 * distance / Vec3.length(accel));
|
||||
Entities.editEntity(sendAssetParticleEffect, {
|
||||
emitAcceleration: accel,
|
||||
lifespan: life
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function deleteSendAssetParticleEffect() {
|
||||
if (sendAssetParticleEffectUpdateTimer) {
|
||||
Script.clearInterval(sendAssetParticleEffectUpdateTimer);
|
||||
sendAssetParticleEffectUpdateTimer = null;
|
||||
}
|
||||
if (sendAssetParticleEffect) {
|
||||
sendAssetParticleEffect = Entities.deleteEntity(sendAssetParticleEffect);
|
||||
}
|
||||
sendAssetRecipient = null;
|
||||
}
|
||||
|
||||
// Function Name: fromQml()
|
||||
//
|
||||
// Description:
|
||||
|
@ -546,7 +901,7 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
break;
|
||||
case 'purchases_walletNotSetUp':
|
||||
wireEventBridge(true);
|
||||
tablet.sendToQml({
|
||||
sendToQml({
|
||||
method: 'updateWalletReferrer',
|
||||
referrer: "purchases"
|
||||
});
|
||||
|
@ -554,7 +909,7 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
break;
|
||||
case 'checkout_walletNotSetUp':
|
||||
wireEventBridge(true);
|
||||
tablet.sendToQml({
|
||||
sendToQml({
|
||||
method: 'updateWalletReferrer',
|
||||
referrer: message.referrer === "itemPage" ? message.itemId : message.referrer
|
||||
});
|
||||
|
@ -600,6 +955,9 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
tablet.gotoWebScreen(message.upgradeUrl + "?edition=" + message.itemEdition,
|
||||
MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
break;
|
||||
case 'giftAsset':
|
||||
|
||||
break;
|
||||
case 'passphrasePopup_cancelClicked':
|
||||
case 'needsLogIn_cancelClicked':
|
||||
tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||
|
@ -644,24 +1002,234 @@ var selectionDisplay = null; // for gridTool.js to ignore
|
|||
filterText = "";
|
||||
tablet.pushOntoStack(MARKETPLACE_PURCHASES_QML_PATH);
|
||||
wireEventBridge(true);
|
||||
tablet.sendToQml({
|
||||
sendToQml({
|
||||
method: 'purchases_showMyItems'
|
||||
});
|
||||
break;
|
||||
case 'refreshConnections':
|
||||
print('Refreshing Connections...');
|
||||
getConnectionData(false);
|
||||
break;
|
||||
case 'enable_ChooseRecipientNearbyMode':
|
||||
if (!isUpdateOverlaysWired) {
|
||||
Script.update.connect(updateOverlays);
|
||||
isUpdateOverlaysWired = true;
|
||||
}
|
||||
break;
|
||||
case 'disable_ChooseRecipientNearbyMode':
|
||||
case 'sendMoney_sendPublicly':
|
||||
// NOP
|
||||
if (isUpdateOverlaysWired) {
|
||||
Script.update.disconnect(updateOverlays);
|
||||
isUpdateOverlaysWired = false;
|
||||
}
|
||||
removeOverlays();
|
||||
break;
|
||||
case 'wallet_availableUpdatesReceived':
|
||||
case 'purchases_availableUpdatesReceived':
|
||||
userHasUpdates = message.numUpdates > 0;
|
||||
messagesWaiting(userHasUpdates);
|
||||
break;
|
||||
case 'purchases_updateWearables':
|
||||
var currentlyWornWearables = [];
|
||||
var ATTACHMENT_SEARCH_RADIUS = 100; // meters (just in case)
|
||||
|
||||
var nearbyEntities = Entities.findEntitiesByType('Model', MyAvatar.position, ATTACHMENT_SEARCH_RADIUS);
|
||||
|
||||
for (var i = 0; i < nearbyEntities.length; i++) {
|
||||
var currentProperties = Entities.getEntityProperties(nearbyEntities[i], ['certificateID', 'editionNumber', 'parentID']);
|
||||
if (currentProperties.parentID === MyAvatar.sessionUUID) {
|
||||
currentlyWornWearables.push({
|
||||
entityID: nearbyEntities[i],
|
||||
entityCertID: currentProperties.certificateID,
|
||||
entityEdition: currentProperties.editionNumber
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
sendToQml({ method: 'updateWearables', wornWearables: currentlyWornWearables });
|
||||
break;
|
||||
case 'sendAsset_sendPublicly':
|
||||
if (message.assetName !== "") {
|
||||
deleteSendAssetParticleEffect();
|
||||
sendAssetRecipient = message.recipient;
|
||||
var amount = message.amount;
|
||||
var props = SEND_ASSET_PARTICLE_PROPERTIES;
|
||||
props.parentID = MyAvatar.sessionUUID;
|
||||
props.position = MyAvatar.position;
|
||||
props.position.y += 0.2;
|
||||
if (message.effectImage) {
|
||||
props.textures = message.effectImage;
|
||||
}
|
||||
sendAssetParticleEffect = Entities.addEntity(props, true);
|
||||
particleEffectTimestamp = Date.now();
|
||||
updateSendAssetParticleEffect();
|
||||
sendAssetParticleEffectUpdateTimer = Script.setInterval(updateSendAssetParticleEffect, SEND_ASSET_PARTICLE_TIMER_UPDATE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
print('Unrecognized message from Checkout.qml or Purchases.qml: ' + JSON.stringify(message));
|
||||
}
|
||||
}
|
||||
|
||||
// Function Name: wireEventBridge()
|
||||
//
|
||||
// Description:
|
||||
// -Used to connect/disconnect the script's response to the tablet's "fromQml" signal. Set the "on" argument to enable or
|
||||
// disable to event bridge.
|
||||
//
|
||||
// Relevant Variables:
|
||||
// -hasEventBridge: true/false depending on whether we've already connected the event bridge.
|
||||
var hasEventBridge = false;
|
||||
function wireEventBridge(on) {
|
||||
if (!tablet) {
|
||||
print("Warning in wireEventBridge(): 'tablet' undefined!");
|
||||
return;
|
||||
}
|
||||
if (on) {
|
||||
if (!hasEventBridge) {
|
||||
tablet.fromQml.connect(fromQml);
|
||||
hasEventBridge = true;
|
||||
}
|
||||
} else {
|
||||
if (hasEventBridge) {
|
||||
tablet.fromQml.disconnect(fromQml);
|
||||
hasEventBridge = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Function Name: onTabletScreenChanged()
|
||||
//
|
||||
// Description:
|
||||
// -Called when the TabletScriptingInterface::screenChanged() signal is emitted. The "type" argument can be either the string
|
||||
// value of "Home", "Web", "Menu", "QML", or "Closed". The "url" argument is only valid for Web and QML.
|
||||
var onWalletScreen = false;
|
||||
var onCommerceScreen = false;
|
||||
function onTabletScreenChanged(type, url) {
|
||||
onMarketplaceScreen = type === "Web" && url.indexOf(MARKETPLACE_URL) !== -1;
|
||||
var onWalletScreenNow = url.indexOf(MARKETPLACE_WALLET_QML_PATH) !== -1;
|
||||
var onCommerceScreenNow = type === "QML" && (url.indexOf(MARKETPLACE_CHECKOUT_QML_PATH) !== -1 || url === MARKETPLACE_PURCHASES_QML_PATH
|
||||
|| url.indexOf(MARKETPLACE_INSPECTIONCERTIFICATE_QML_PATH) !== -1);
|
||||
|
||||
if ((!onWalletScreenNow && onWalletScreen) || (!onCommerceScreenNow && onCommerceScreen)) { // exiting wallet or commerce screen
|
||||
if (isHmdPreviewDisabledBySecurity) {
|
||||
DesktopPreviewProvider.setPreviewDisabledReason("USER");
|
||||
Menu.setIsOptionChecked("Disable Preview", false);
|
||||
setTabletVisibleInSecondaryCamera(true);
|
||||
isHmdPreviewDisabledBySecurity = false;
|
||||
}
|
||||
}
|
||||
|
||||
onCommerceScreen = onCommerceScreenNow;
|
||||
onWalletScreen = onWalletScreenNow;
|
||||
wireEventBridge(onMarketplaceScreen || onCommerceScreen || onWalletScreen);
|
||||
|
||||
if (url === MARKETPLACE_PURCHASES_QML_PATH) {
|
||||
sendToQml({
|
||||
method: 'updatePurchases',
|
||||
referrerURL: referrerURL,
|
||||
filterText: filterText
|
||||
});
|
||||
}
|
||||
|
||||
// for toolbar mode: change button to active when window is first openend, false otherwise.
|
||||
if (marketplaceButton) {
|
||||
marketplaceButton.editProperties({ isActive: (onMarketplaceScreen || onCommerceScreen) && !onWalletScreen });
|
||||
}
|
||||
if (type === "Web" && url.indexOf(MARKETPLACE_URL) !== -1) {
|
||||
ContextOverlay.isInMarketplaceInspectionMode = true;
|
||||
} else {
|
||||
ContextOverlay.isInMarketplaceInspectionMode = false;
|
||||
}
|
||||
|
||||
if (onCommerceScreen) {
|
||||
isWired = true;
|
||||
Users.usernameFromIDReply.connect(usernameFromIDReply);
|
||||
Controller.mousePressEvent.connect(handleMouseEvent);
|
||||
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
|
||||
triggerMapping.enable();
|
||||
triggerPressMapping.enable();
|
||||
Wallet.refreshWalletStatus();
|
||||
} else {
|
||||
off();
|
||||
sendToQml({
|
||||
method: 'inspectionCertificate_resetCert'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Manage the connection between the button and the window.
|
||||
//
|
||||
var marketplaceButton;
|
||||
var buttonName = "MARKET";
|
||||
var tablet = null;
|
||||
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";
|
||||
function startup() {
|
||||
tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
marketplaceButton = tablet.addButton({
|
||||
icon: NORMAL_ICON,
|
||||
activeIcon: NORMAL_ACTIVE,
|
||||
text: buttonName,
|
||||
sortOrder: 9
|
||||
});
|
||||
|
||||
ContextOverlay.contextOverlayClicked.connect(setCertificateInfo);
|
||||
Entities.canWriteAssetsChanged.connect(onCanWriteAssetsChanged);
|
||||
GlobalServices.myUsernameChanged.connect(onUsernameChanged);
|
||||
marketplaceButton.clicked.connect(onButtonClicked);
|
||||
tablet.screenChanged.connect(onTabletScreenChanged);
|
||||
tablet.webEventReceived.connect(onMessage);
|
||||
Wallet.walletStatusChanged.connect(sendCommerceSettings);
|
||||
Window.messageBoxClosed.connect(onMessageBoxClosed);
|
||||
|
||||
Wallet.refreshWalletStatus();
|
||||
}
|
||||
var isWired = false;
|
||||
var isUpdateOverlaysWired = false;
|
||||
function off() {
|
||||
if (isWired) { // It is not ok to disconnect these twice, hence guard.
|
||||
Users.usernameFromIDReply.disconnect(usernameFromIDReply);
|
||||
Controller.mousePressEvent.disconnect(handleMouseEvent);
|
||||
Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent);
|
||||
isWired = false;
|
||||
}
|
||||
if (isUpdateOverlaysWired) {
|
||||
Script.update.disconnect(updateOverlays);
|
||||
isUpdateOverlaysWired = false;
|
||||
}
|
||||
triggerMapping.disable(); // It's ok if we disable twice.
|
||||
triggerPressMapping.disable(); // see above
|
||||
removeOverlays();
|
||||
}
|
||||
function shutdown() {
|
||||
deleteSendAssetParticleEffect();
|
||||
|
||||
ContextOverlay.contextOverlayClicked.disconnect(setCertificateInfo);
|
||||
Entities.canWriteAssetsChanged.disconnect(onCanWriteAssetsChanged);
|
||||
GlobalServices.myUsernameChanged.disconnect(onUsernameChanged);
|
||||
marketplaceButton.clicked.disconnect(onButtonClicked);
|
||||
tablet.removeButton(marketplaceButton);
|
||||
tablet.webEventReceived.disconnect(onMessage);
|
||||
Wallet.walletStatusChanged.disconnect(sendCommerceSettings);
|
||||
Window.messageBoxClosed.disconnect(onMessageBoxClosed);
|
||||
|
||||
if (tablet) {
|
||||
tablet.screenChanged.disconnect(onTabletScreenChanged);
|
||||
if (onMarketplaceScreen) {
|
||||
tablet.gotoHomeScreen();
|
||||
}
|
||||
}
|
||||
|
||||
off();
|
||||
}
|
||||
|
||||
//
|
||||
// Run the functions.
|
||||
//
|
||||
startup();
|
||||
Script.scriptEnding.connect(shutdown);
|
||||
|
||||
}()); // END LOCAL_SCOPE
|
||||
|
|