Merge pull request #12862 from zfox23/discovery_April2018

Discovery: April 2018 (Huge PR; see description)
This commit is contained in:
Zach Fox 2018-04-17 15:11:50 -07:00 committed by GitHub
commit 3b8e52ea41
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 2269 additions and 1279 deletions

View file

@ -25,7 +25,6 @@
<glyph glyph-name="web" unicode="&#113;" 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" unicode="&#113;" 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="&#114;" 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="web-2" unicode="&#114;" 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="&#115;" 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="edit" unicode="&#115;" 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="&#116;" 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="&#117;" 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="directory" unicode="&#117;" 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="&#118;" 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="menu" unicode="&#118;" 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="&#119;" 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"/> <glyph glyph-name="close" unicode="&#119;" 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="&#57381;" 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="rez" unicode="&#57381;" 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="&#57387;" 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="keyboard-collapse" unicode="&#57387;" 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="&#57386;" 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="image" unicode="&#57386;" 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="&#57388;" 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="&#57389;" 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="&#116;" 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="&#57390;" 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="&#57392;" 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="&#57393;" 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="&#57394;" 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="&#57395;" 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="&#57391;" 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="&#57396;" 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> </font></defs></svg>

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View file

@ -12,7 +12,7 @@
<body> <body>
<div class="container"> <div class="container">
<h1>HiFi Glyphs</h1> <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> <h2>CSS mapping</h2>
<ul class="glyphs css-mapping"> <ul class="glyphs css-mapping">
<li> <li>
@ -87,10 +87,6 @@
<div class="icon icon-edit"></div> <div class="icon icon-edit"></div>
<input type="text" readonly="readonly" value="edit"> <input type="text" readonly="readonly" value="edit">
</li> </li>
<li>
<div class="icon icon-market"></div>
<input type="text" readonly="readonly" value="market">
</li>
<li> <li>
<div class="icon icon-directory"></div> <div class="icon icon-directory"></div>
<input type="text" readonly="readonly" value="directory"> <input type="text" readonly="readonly" value="directory">
@ -567,6 +563,46 @@
<div class="icon icon-image"></div> <div class="icon icon-image"></div>
<input type="text" readonly="readonly" value="image"> <input type="text" readonly="readonly" value="image">
</li> </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> </ul>
<h2>Character mapping</h2> <h2>Character mapping</h2>
<ul class="glyphs character-mapping"> <ul class="glyphs character-mapping">
@ -642,10 +678,6 @@
<div data-icon="s" class="icon"></div> <div data-icon="s" class="icon"></div>
<input type="text" readonly="readonly" value="s"> <input type="text" readonly="readonly" value="s">
</li> </li>
<li>
<div data-icon="t" class="icon"></div>
<input type="text" readonly="readonly" value="t">
</li>
<li> <li>
<div data-icon="u" class="icon"></div> <div data-icon="u" class="icon"></div>
<input type="text" readonly="readonly" value="u"> <input type="text" readonly="readonly" value="u">
@ -1122,6 +1154,46 @@
<div data-icon="&#xe02a;" class="icon"></div> <div data-icon="&#xe02a;" class="icon"></div>
<input type="text" readonly="readonly" value="&amp;#xe02a;"> <input type="text" readonly="readonly" value="&amp;#xe02a;">
</li> </li>
<li>
<div data-icon="&#xe02c;" class="icon"></div>
<input type="text" readonly="readonly" value="&amp;#xe02c;">
</li>
<li>
<div data-icon="&#xe02d;" class="icon"></div>
<input type="text" readonly="readonly" value="&amp;#xe02d;">
</li>
<li>
<div data-icon="t" class="icon"></div>
<input type="text" readonly="readonly" value="t">
</li>
<li>
<div data-icon="&#xe02e;" class="icon"></div>
<input type="text" readonly="readonly" value="&amp;#xe02e;">
</li>
<li>
<div data-icon="&#xe030;" class="icon"></div>
<input type="text" readonly="readonly" value="&amp;#xe030;">
</li>
<li>
<div data-icon="&#xe031;" class="icon"></div>
<input type="text" readonly="readonly" value="&amp;#xe031;">
</li>
<li>
<div data-icon="&#xe032;" class="icon"></div>
<input type="text" readonly="readonly" value="&amp;#xe032;">
</li>
<li>
<div data-icon="&#xe033;" class="icon"></div>
<input type="text" readonly="readonly" value="&amp;#xe033;">
</li>
<li>
<div data-icon="&#xe02f;" class="icon"></div>
<input type="text" readonly="readonly" value="&amp;#xe02f;">
</li>
<li>
<div data-icon="&#xe034;" class="icon"></div>
<input type="text" readonly="readonly" value="&amp;#xe034;">
</li>
</ul> </ul>
</div> </div>
<script>(function() { <script>(function() {

View file

@ -92,9 +92,6 @@
.icon-edit:before { .icon-edit:before {
content: "\73"; content: "\73";
} }
.icon-market:before {
content: "\74";
}
.icon-directory:before { .icon-directory:before {
content: "\75"; content: "\75";
} }
@ -452,3 +449,33 @@
.icon-image:before { .icon-image:before {
content: "\e02a"; 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";
}

View file

@ -8,8 +8,9 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
import QtQuick 2.7 import QtQuick 2.5
import QtQuick.Controls 2.2 import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import "../styles-uit" import "../styles-uit"
import "../controls-uit" as HifiControls import "../controls-uit" as HifiControls
@ -28,17 +29,11 @@ TextField {
property int roundedBorderRadius: 4 property int roundedBorderRadius: 4
property bool error: false; property bool error: false;
property bool hasClearButton: false; property bool hasClearButton: false;
property alias textColor: textField.color
property string leftPermanentGlyph: ""; property string leftPermanentGlyph: "";
property string centerPlaceholderGlyph: ""; property string centerPlaceholderGlyph: "";
placeholderText: textField.placeholderText placeholderText: textField.placeholderText
property bool rightAnchorSet: false;
anchors.onRightChanged: {
rightAnchorSet = true;
}
font.family: "Fira Sans" font.family: "Fira Sans"
font.pixelSize: hifi.fontSizes.textFieldInput font.pixelSize: hifi.fontSizes.textFieldInput
height: implicitHeight + 3 // Make surrounding box higher so that highlight is vertically centered. height: implicitHeight + 3 // Make surrounding box higher so that highlight is vertically centered.
@ -49,56 +44,42 @@ TextField {
// workaround for https://bugreports.qt.io/browse/QTBUG-49297 // workaround for https://bugreports.qt.io/browse/QTBUG-49297
Keys.onPressed: { Keys.onPressed: {
switch (event.key) { switch (event.key) {
case Qt.Key_Return: case Qt.Key_Return:
case Qt.Key_Enter: case Qt.Key_Enter:
event.accepted = true; event.accepted = true;
// emit accepted signal manually // emit accepted signal manually
if (acceptableInput) { if (acceptableInput) {
accepted(); accepted();
} }
} }
} }
Text { style: TextFieldStyle {
id: placeholder id: style;
x: textField.leftPadding textColor: {
y: textField.topPadding if (isLightColorScheme) {
width: textField.width - (textField.leftPadding + textField.rightPadding) if (textField.activeFocus) {
height: textField.height - (textField.topPadding + textField.bottomPadding) hifi.colors.black
} else {
text: textField.placeholderText hifi.colors.lightGray
font: textField.font }
color: textField.placeholderTextColor } else if (isFaintGrayColorScheme) {
verticalAlignment: textField.verticalAlignment if (textField.activeFocus) {
visible: !textField.length && !textField.preeditText && (!textField.activeFocus || textField.horizontalAlignment !== Qt.AlignHCenter) hifi.colors.black
elide: Text.ElideRight } else {
} hifi.colors.lightGray
}
color: {
if (isLightColorScheme) {
if (textField.activeFocus) {
hifi.colors.black
} else { } else {
hifi.colors.lightGray if (textField.activeFocus) {
} hifi.colors.white
} else if (isFaintGrayColorScheme) { } else {
if (textField.activeFocus) { hifi.colors.lightGrayText
hifi.colors.black }
} else {
hifi.colors.lightGray
}
} else {
if (textField.activeFocus) {
hifi.colors.white
} else {
hifi.colors.lightGrayText
} }
} }
} background: Rectangle {
color: {
background: Rectangle {
color: {
if (isLightColorScheme) { if (isLightColorScheme) {
if (textField.activeFocus) { if (textField.activeFocus) {
hifi.colors.white hifi.colors.white
@ -119,22 +100,22 @@ TextField {
} }
} }
} }
border.color: textField.error ? hifi.colors.redHighlight : border.color: textField.error ? hifi.colors.redHighlight :
(textField.activeFocus ? hifi.colors.primaryHighlight : (hasDefocusedBorder ? (isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray) : color)) (textField.activeFocus ? hifi.colors.primaryHighlight : (hasDefocusedBorder ? (isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray) : color))
border.width: textField.activeFocus || hasRoundedBorder || textField.error ? 1 : 0 border.width: textField.activeFocus || hasRoundedBorder || textField.error ? 1 : 0
radius: isSearchField ? textField.height / 2 : (hasRoundedBorder ? roundedBorderRadius : 0) radius: isSearchField ? textField.height / 2 : (hasRoundedBorder ? roundedBorderRadius : 0)
HiFiGlyphs { HiFiGlyphs {
text: textField.leftPermanentGlyph; text: textField.leftPermanentGlyph;
color: textColor; color: textColor;
size: hifi.fontSizes.textFieldSearchIcon; size: hifi.fontSizes.textFieldSearchIcon;
anchors.left: parent.left; anchors.left: parent.left;
anchors.verticalCenter: parent.verticalCenter; anchors.verticalCenter: parent.verticalCenter;
anchors.leftMargin: hifi.dimensions.textPadding - 2; anchors.leftMargin: hifi.dimensions.textPadding - 2;
visible: text; visible: text;
} }
HiFiGlyphs { HiFiGlyphs {
text: textField.centerPlaceholderGlyph; text: textField.centerPlaceholderGlyph;
color: textColor; color: textColor;
size: parent.height; size: parent.height;
@ -144,57 +125,48 @@ TextField {
} }
HiFiGlyphs { HiFiGlyphs {
text: hifi.glyphs.search text: hifi.glyphs.search
color: textColor color: textColor
size: hifi.fontSizes.textFieldSearchIcon size: hifi.fontSizes.textFieldSearchIcon
anchors.left: parent.left anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: hifi.dimensions.textPadding - 2 anchors.leftMargin: hifi.dimensions.textPadding - 2
visible: isSearchField visible: isSearchField
} }
HiFiGlyphs { HiFiGlyphs {
text: hifi.glyphs.error text: hifi.glyphs.error
color: textColor color: textColor
size: 40 size: 40
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: hifi.dimensions.textPadding - 2 anchors.rightMargin: hifi.dimensions.textPadding - 2
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
visible: hasClearButton && textField.text !== ""; visible: hasClearButton && textField.text !== "";
MouseArea { MouseArea {
anchors.fill: parent; anchors.fill: parent;
onClicked: { onClicked: {
textField.text = ""; textField.text = "";
}
} }
} }
} }
placeholderTextColor: isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray
selectedTextColor: hifi.colors.black
selectionColor: hifi.colors.primaryHighlight
padding.left: hasRoundedBorder ? textField.height / 2 : ((isSearchField || textField.leftPermanentGlyph !== "") ? textField.height - 2 : 0) + hifi.dimensions.textPadding
padding.right: (hasClearButton ? textField.height - 2 : 0) + hifi.dimensions.textPadding
} }
property color placeholderTextColor: isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray
selectedTextColor: hifi.colors.black
selectionColor: hifi.colors.primaryHighlight
leftPadding: hasRoundedBorder ? textField.height / 2 : ((isSearchField || textField.leftPermanentGlyph !== "") ? textField.height - 2 : 0) + hifi.dimensions.textPadding
rightPadding: (hasClearButton ? textField.height - 2 : 0) + hifi.dimensions.textPadding
HifiControls.Label { HifiControls.Label {
id: textFieldLabel id: textFieldLabel
text: textField.label text: textField.label
colorScheme: textField.colorScheme colorScheme: textField.colorScheme
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right
Binding on anchors.right {
when: rightAnchorSet
value: textField.right
}
Binding on wrapMode {
when: rightAnchorSet
value: Text.WordWrap
}
anchors.bottom: parent.top anchors.bottom: parent.top
anchors.bottomMargin: 3 anchors.bottomMargin: 3
wrapMode: Text.WordWrap
visible: label != "" visible: label != ""
} }
} }

View file

@ -257,9 +257,14 @@ Rectangle {
lightboxPopup.bodyImageSource = msg.securityImageSource; lightboxPopup.bodyImageSource = msg.securityImageSource;
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText; lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
lightboxPopup.button1text = "CLOSE"; lightboxPopup.button1text = "CLOSE";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.button2text = "GO TO WALLET"; lightboxPopup.button2text = "GO TO WALLET";
lightboxPopup.button2method = "sendToParent({method: 'checkout_openWallet'});"; lightboxPopup.button2method = function() {
lightboxPopup.visible = false;
sendToScript({method: 'checkout_openWallet'});
};
lightboxPopup.visible = true; lightboxPopup.visible = true;
} else { } else {
sendToScript(msg); sendToScript(msg);
@ -623,10 +628,16 @@ Rectangle {
lightboxPopup.bodyText = "You will not be able to replace this domain's content with <b>" + root.itemName + 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?"; " </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.button1text = "CANCEL";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.button2text = "CONFIRM"; lightboxPopup.button2text = "CONFIRM";
lightboxPopup.button2method = "Commerce.buy('" + root.itemId + "', " + root.itemPrice + ");" + lightboxPopup.button2method = function() {
"root.visible = false; buyButton.enabled = false; loading.visible = true;"; Commerce.buy(root.itemId, root.itemPrice);
lightboxPopup.visible = false;
buyButton.enabled = false;
loading.visible = true;
};
lightboxPopup.visible = true; lightboxPopup.visible = true;
} else { } else {
buyButton.enabled = false; 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'>" + "<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."; "click here to open info on your desktop browser.";
lightboxPopup.button1text = "CANCEL"; lightboxPopup.button1text = "CANCEL";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.button2text = "CONFIRM"; lightboxPopup.button2text = "CONFIRM";
lightboxPopup.button2method = "Commerce.replaceContentSet('" + root.itemHref + "', '" + root.certificateId + "');" + lightboxPopup.button2method = function() {
"root.visible = false;rezzedNotifContainer.visible = true; rezzedNotifContainerTimer.start();" + Commerce.replaceContentSet(root.itemHref);
"UserActivityLogger.commerceEntityRezzed('" + root.itemId + "', 'checkout', '" + root.itemType + "');"; lightboxPopup.visible = false;
rezzedNotifContainer.visible = true;
rezzedNotifContainerTimer.start();
UserActivityLogger.commerceEntityRezzed(root.itemId, 'checkout', root.itemType);
};
lightboxPopup.visible = true; lightboxPopup.visible = true;
} else if (root.itemType === "avatar") { } else if (root.itemType === "avatar") {
lightboxPopup.titleText = "Change Avatar"; lightboxPopup.titleText = "Change Avatar";
lightboxPopup.bodyText = "This will change your current avatar to " + root.itemName + " while retaining your wearables."; lightboxPopup.bodyText = "This will change your current avatar to " + root.itemName + " while retaining your wearables.";
lightboxPopup.button1text = "CANCEL"; lightboxPopup.button1text = "CANCEL";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.button2text = "CONFIRM"; 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; lightboxPopup.visible = true;
} else if (root.itemType === "app") { } else if (root.itemType === "app") {
if (root.isInstalled) { if (root.isInstalled) {
@ -822,9 +844,14 @@ Rectangle {
lightboxPopup.bodyText = "You don't have permission to rez certified items in this domain.<br><br>" + 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>"; "Use the <b>GOTO app</b> to visit another domain or <b>go to your own sandbox.</b>";
lightboxPopup.button1text = "CLOSE"; lightboxPopup.button1text = "CLOSE";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.button2text = "OPEN GOTO"; lightboxPopup.button2text = "OPEN GOTO";
lightboxPopup.button2method = "sendToParent({method: 'purchases_openGoTo'});"; lightboxPopup.button2method = function() {
sendToScript({method: 'purchases_openGoTo'});
lightboxPopup.visible = false;
};
lightboxPopup.visible = true; lightboxPopup.visible = true;
} }
} }
@ -918,7 +945,9 @@ Rectangle {
lightboxPopup.bodyText = 'Your item is marked "pending" while your purchase is being confirmed.<br><br>' + lightboxPopup.bodyText = 'Your item is marked "pending" while your purchase is being confirmed.<br><br>' +
'Confirmations usually take about 90 seconds.'; 'Confirmations usually take about 90 seconds.';
lightboxPopup.button1text = "CLOSE"; lightboxPopup.button1text = "CLOSE";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.visible = true; lightboxPopup.visible = true;
} }
} }

View file

@ -26,10 +26,10 @@ Rectangle {
property string bodyText; property string bodyText;
property string button1color: hifi.buttons.noneBorderlessGray; property string button1color: hifi.buttons.noneBorderlessGray;
property string button1text; property string button1text;
property string button1method; property var button1method;
property string button2color: hifi.buttons.noneBorderless; property string button2color: hifi.buttons.blue;
property string button2text; property string button2text;
property string button2method; property var button2method;
property string buttonLayout: "leftright"; property string buttonLayout: "leftright";
readonly property string securityPicBodyText: "When you see your Security Pic, your actions and data are securely making use of your " + readonly property string securityPicBodyText: "When you see your Security Pic, your actions and data are securely making use of your " +
@ -72,7 +72,7 @@ Rectangle {
anchors.right: parent.right; anchors.right: parent.right;
anchors.rightMargin: 30; anchors.rightMargin: 30;
height: paintedHeight; height: paintedHeight;
color: hifi.colors.baseGray; color: hifi.colors.black;
size: 24; size: 24;
verticalAlignment: Text.AlignTop; verticalAlignment: Text.AlignTop;
wrapMode: Text.WordWrap; wrapMode: Text.WordWrap;
@ -104,7 +104,7 @@ Rectangle {
anchors.right: parent.right; anchors.right: parent.right;
anchors.rightMargin: 30; anchors.rightMargin: 30;
height: paintedHeight; height: paintedHeight;
color: hifi.colors.baseGray; color: hifi.colors.black;
size: 20; size: 20;
verticalAlignment: Text.AlignTop; verticalAlignment: Text.AlignTop;
wrapMode: Text.WordWrap; wrapMode: Text.WordWrap;
@ -129,15 +129,15 @@ Rectangle {
colorScheme: hifi.colorSchemes.light; colorScheme: hifi.colorSchemes.light;
anchors.top: root.buttonLayout === "leftright" ? parent.top : parent.top; anchors.top: root.buttonLayout === "leftright" ? parent.top : parent.top;
anchors.left: parent.left; anchors.left: parent.left;
anchors.leftMargin: 10; anchors.leftMargin: root.buttonLayout === "leftright" ? 30 : 10;
anchors.right: root.buttonLayout === "leftright" ? undefined : parent.right; anchors.right: root.buttonLayout === "leftright" ? undefined : parent.right;
anchors.rightMargin: root.buttonLayout === "leftright" ? undefined : 10; anchors.rightMargin: root.buttonLayout === "leftright" ? undefined : 10;
width: root.buttonLayout === "leftright" ? (root.button2text ? parent.width/2 - anchors.leftMargin*2 : parent.width - anchors.leftMargin * 2) : width: root.buttonLayout === "leftright" ? (root.button2text ? parent.width/2 - anchors.leftMargin*2 : parent.width - anchors.leftMargin * 2) :
(undefined); (undefined);
height: 50; height: 40;
text: root.button1text; text: root.button1text;
onClicked: { onClicked: {
eval(button1method); button1method();
} }
} }
@ -152,12 +152,12 @@ Rectangle {
anchors.left: root.buttonLayout === "leftright" ? undefined : parent.left; anchors.left: root.buttonLayout === "leftright" ? undefined : parent.left;
anchors.leftMargin: root.buttonLayout === "leftright" ? undefined : 10; anchors.leftMargin: root.buttonLayout === "leftright" ? undefined : 10;
anchors.right: parent.right; 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; width: root.buttonLayout === "leftright" ? parent.width/2 - anchors.rightMargin*2 : undefined;
height: 50; height: 40;
text: root.button2text; text: root.button2text;
onClicked: { onClicked: {
eval(button2method); button2method();
} }
} }
} }
@ -174,10 +174,10 @@ Rectangle {
root.bodyText = ""; root.bodyText = "";
root.button1color = hifi.buttons.noneBorderlessGray; root.button1color = hifi.buttons.noneBorderlessGray;
root.button1text = ""; root.button1text = "";
root.button1method = ""; root.button1method = function() {};
root.button2color = hifi.buttons.noneBorderless; root.button2color = hifi.buttons.blue;
root.button2text = ""; root.button2text = "";
root.button2method = ""; root.button2method = function() {};
root.buttonLayout = "leftright"; root.buttonLayout = "leftright";
} }
// //

View file

@ -1,6 +1,6 @@
// //
// ConnectionItem.qml // ConnectionItem.qml
// qml/hifi/commerce/wallet/sendMoney // qml/hifi/commerce/common/sendAsset
// //
// ConnectionItem // ConnectionItem
// //
@ -113,7 +113,7 @@ Item {
text: "CHOOSE"; text: "CHOOSE";
onClicked: { onClicked: {
var msg = { method: 'chooseConnection', userName: root.userName, profilePicUrl: root.profilePicUrl }; var msg = { method: 'chooseConnection', userName: root.userName, profilePicUrl: root.profilePicUrl };
sendToSendMoney(msg); sendToParent(msg);
} }
} }
} }
@ -121,7 +121,7 @@ Item {
// //
// FUNCTION DEFINITIONS START // FUNCTION DEFINITIONS START
// //
signal sendToSendMoney(var msg); signal sendToParent(var msg);
// //
// FUNCTION DEFINITIONS END // FUNCTION DEFINITIONS END
// //

View file

@ -1,6 +1,6 @@
// //
// RecipientDisplay.qml // RecipientDisplay.qml
// qml/hifi/commerce/wallet/sendMoney // qml/hifi/commerce/common/sendAsset
// //
// RecipientDisplay // RecipientDisplay
// //
@ -18,7 +18,7 @@ import QtGraphicalEffects 1.0
import "../../../../styles-uit" import "../../../../styles-uit"
import "../../../../controls-uit" as HifiControlsUit import "../../../../controls-uit" as HifiControlsUit
import "../../../../controls" as HifiControls import "../../../../controls" as HifiControls
import "../../common" as HifiCommerceCommon import "../" as HifiCommerceCommon
Item { Item {
HifiConstants { id: hifi; } HifiConstants { id: hifi; }

View file

@ -13,7 +13,6 @@
import Hifi 1.0 as Hifi import Hifi 1.0 as Hifi
import QtQuick 2.5 import QtQuick 2.5
import QtGraphicalEffects 1.0
import QtQuick.Controls 1.4 import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4 import QtQuick.Controls.Styles 1.4
import "../../../styles-uit" import "../../../styles-uit"
@ -22,14 +21,11 @@ import "../../../controls" as HifiControls
import "../wallet" as HifiWallet import "../wallet" as HifiWallet
import TabletScriptingInterface 1.0 import TabletScriptingInterface 1.0
// references XXX from root context
Item { Item {
HifiConstants { id: hifi; } HifiConstants { id: hifi; }
id: root; id: root;
property string purchaseStatus; property string purchaseStatus;
property bool purchaseStatusChanged;
property string itemName; property string itemName;
property string itemId; property string itemId;
property string itemPreviewImageUrl; 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 var buttonGlyph: [hifi.glyphs.wand, hifi.glyphs.hat, hifi.glyphs.globe, hifi.glyphs.install, hifi.glyphs.avatar];
property bool showConfirmation: false; property bool showConfirmation: false;
property bool hasPermissionToRezThis; property bool hasPermissionToRezThis;
property bool permissionExplanationCardVisible; property bool cardBackVisible;
property bool isInstalled; property bool isInstalled;
property string wornEntityID;
property string upgradeUrl; property string upgradeUrl;
property string upgradeTitle; property string upgradeTitle;
property bool updateAvailable: root.upgradeUrl !== "" && !root.isShowingMyItems;
property bool isShowingMyItems; property bool isShowingMyItems;
property string originalStatusText; property string originalStatusText;
property string originalStatusColor; property string originalStatusColor;
height: (root.upgradeUrl === "" || root.isShowingMyItems) ? 110 : 150; height: 102;
width: parent.width; width: parent.width;
Connections { 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: { onShowConfirmationChanged: {
if (root.showConfirmation) { if (root.showConfirmation) {
rezzedNotifContainer.visible = true; rezzedNotifContainer.visible = true;
@ -118,35 +106,307 @@ Item {
} }
} }
Timer { Rectangle {
id: confirmedTimer; id: background;
interval: 3000; z: 10;
onTriggered: { color: Qt.rgba(0, 0, 0, 0.25);
statusText.text = root.originalStatusText; anchors.fill: parent;
statusText.color = root.originalStatusColor; }
root.purchaseStatusChanged = false;
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 { Rectangle {
id: mainContainer; id: mainContainer;
z: 51;
// Style // Style
color: hifi.colors.white; color: hifi.colors.white;
// Size // Size
anchors.left: parent.left; 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.right: parent.right;
anchors.top: parent.top; anchors.top: parent.top;
height: 100; height: root.height - 2;
Image { Image {
id: itemPreviewImage; id: itemPreviewImage;
@ -154,8 +414,9 @@ Item {
anchors.left: parent.left; anchors.left: parent.left;
anchors.top: parent.top; anchors.top: parent.top;
anchors.bottom: parent.bottom; anchors.bottom: parent.bottom;
width: height; width: height * 1.78;
fillMode: Image.PreserveAspectCrop; fillMode: Image.PreserveAspectCrop;
mipmap: true;
MouseArea { MouseArea {
anchors.fill: parent; anchors.fill: parent;
@ -165,218 +426,53 @@ Item {
} }
} }
TextMetrics { RalewayRegular {
id: itemNameTextMetrics;
font: itemName.font;
text: itemName.text;
}
RalewaySemiBold {
id: itemName; id: itemName;
anchors.top: itemPreviewImage.top; anchors.top: parent.top;
anchors.topMargin: 4; anchors.topMargin: 4;
anchors.left: itemPreviewImage.right; anchors.left: itemPreviewImage.right;
anchors.leftMargin: 8; anchors.leftMargin: 10;
width: !noPermissionGlyph.visible ? (buttonContainer.x - itemPreviewImage.x - itemPreviewImage.width - anchors.leftMargin) : anchors.right: contextMenuButtonContainer.left;
Math.min(itemNameTextMetrics.tightBoundingRect.width + 2, anchors.rightMargin: 4;
buttonContainer.x - itemPreviewImage.x - itemPreviewImage.width - anchors.leftMargin - noPermissionGlyph.width + 2);
height: paintedHeight; height: paintedHeight;
// Text size // Text size
size: 24; size: 20;
// Style // Style
color: hifi.colors.blueAccent; color: hifi.colors.black;
text: root.itemName; text: root.itemName;
elide: Text.ElideRight; elide: Text.ElideRight;
// Alignment // Alignment
horizontalAlignment: Text.AlignLeft; horizontalAlignment: Text.AlignLeft;
verticalAlignment: Text.AlignVCenter; 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 { RalewayRegular {
id: certificateContainer; id: editionNumberText;
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;
visible: root.displayedItemCount > 1 && !statusContainer.visible; visible: root.displayedItemCount > 1 && !statusContainer.visible;
anchors.left: itemName.left; anchors.left: itemName.left;
anchors.top: certificateContainer.bottom; anchors.right: itemName.right;
anchors.topMargin: 8; anchors.top: itemName.bottom;
anchors.bottom: parent.bottom; anchors.topMargin: 4;
anchors.right: buttonContainer.left; anchors.bottom: buttonContainer.top;
anchors.rightMargin: 2; anchors.bottomMargin: 4;
width: itemName.width;
RalewayRegular { text: "Edition #" + root.itemEdition;
anchors.left: parent.left; size: 13;
anchors.top: parent.top; color: hifi.colors.black;
anchors.bottom: parent.bottom; verticalAlignment: Text.AlignVCenter;
width: paintedWidth;
text: "#" + root.itemEdition;
size: 13;
color: hifi.colors.black;
verticalAlignment: Text.AlignTop;
}
} }
Item { Item {
id: statusContainer; 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.left: itemName.left;
anchors.top: certificateContainer.bottom; anchors.right: itemName.right;
anchors.topMargin: 8; anchors.top: itemName.bottom;
anchors.bottom: parent.bottom; anchors.topMargin: 4;
anchors.right: buttonContainer.left; anchors.bottom: buttonContainer.top;
anchors.rightMargin: 2; anchors.bottomMargin: 4;
RalewaySemiBold { RalewayRegular {
id: statusText; id: statusText;
anchors.left: parent.left; anchors.left: parent.left;
anchors.top: parent.top; anchors.top: parent.top;
@ -393,7 +489,7 @@ Item {
"" ""
} }
} }
size: 18; size: 13;
color: { color: {
if (root.purchaseStatus === "pending") { if (root.purchaseStatus === "pending") {
hifi.colors.blueAccent hifi.colors.blueAccent
@ -418,10 +514,10 @@ Item {
} }
} }
// Size // Size
size: 36; size: 34;
// Anchors // Anchors
anchors.top: parent.top; anchors.top: parent.top;
anchors.topMargin: -8; anchors.topMargin: -10;
anchors.left: statusText.right; anchors.left: statusText.right;
anchors.bottom: parent.bottom; anchors.bottom: parent.bottom;
// Style // 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 { Rectangle {
id: rezzedNotifContainer; id: rezzedNotifContainer;
z: 998; z: 998;
@ -489,62 +629,22 @@ Item {
horizontalAlignment: Text.AlignHCenter; horizontalAlignment: Text.AlignHCenter;
} }
Timer { Timer {
id: rezzedNotifContainerTimer; id: rezzedNotifContainerTimer;
interval: 2000; interval: 2000;
onTriggered: rezzedNotifContainer.visible = false 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);
}
} }
} }
Button { Button {
id: buttonContainer; id: buttonContainer;
property int color: hifi.buttons.blue; property int color: hifi.buttons.blue;
property int colorScheme: hifi.colorSchemes.light; property int colorScheme: hifi.colorSchemes.light;
anchors.top: parent.top; anchors.left: itemName.left;
anchors.topMargin: 4;
anchors.bottom: parent.bottom; anchors.bottom: parent.bottom;
anchors.bottomMargin: 4; anchors.bottomMargin: 8;
anchors.right: parent.right; width: 160;
anchors.rightMargin: 4; height: 40;
width: height;
enabled: root.hasPermissionToRezThis && enabled: root.hasPermissionToRezThis &&
root.purchaseStatus !== "invalidated" && root.purchaseStatus !== "invalidated" &&
MyAvatar.skeletonModelURL !== root.itemHref; MyAvatar.skeletonModelURL !== root.itemHref;
@ -568,8 +668,12 @@ Item {
} else if (root.itemType === "avatar") { } else if (root.itemType === "avatar") {
sendToPurchases({method: 'showChangeAvatarLightbox', itemName: root.itemName, itemHref: root.itemHref}); sendToPurchases({method: 'showChangeAvatarLightbox', itemName: root.itemName, itemHref: root.itemHref});
} else if (root.itemType === "app") { } else if (root.itemType === "app") {
// "Run" and "Uninstall" buttons are separate. if (root.isInstalled) {
Commerce.installApp(root.itemHref); Commerce.openApp(root.itemHref);
} else {
// "Run" and "Uninstall" buttons are separate.
Commerce.installApp(root.itemHref);
}
} else { } else {
sendToPurchases({method: 'purchases_rezClicked', itemHref: root.itemHref, itemType: root.itemType}); sendToPurchases({method: 'purchases_rezClicked', itemHref: root.itemHref, itemType: root.itemType});
root.showConfirmation = true; root.showConfirmation = true;
@ -612,93 +716,76 @@ Item {
} }
label: Item { label: Item {
TextMetrics {
id: rezIconTextMetrics;
font: rezIcon.font;
text: rezIcon.text;
}
HiFiGlyphs { HiFiGlyphs {
id: rezIcon; id: rezIcon;
text: (root.buttonGlyph)[itemTypesArray.indexOf(root.itemType)]; text: (root.buttonGlyph)[itemTypesArray.indexOf(root.itemType)];
// Size anchors.right: rezIconLabel.left;
size: 60; anchors.rightMargin: 2;
// Anchors anchors.verticalCenter: parent.verticalCenter;
anchors.top: parent.top; size: 36;
anchors.topMargin: 0;
anchors.left: parent.left;
anchors.right: parent.right;
horizontalAlignment: Text.AlignHCenter; horizontalAlignment: Text.AlignHCenter;
// Style
color: enabled ? hifi.buttons.textColor[control.color] 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 { RalewayBold {
id: rezIconLabel; id: rezIconLabel;
anchors.top: rezIcon.bottom; text: root.isInstalled ? "OPEN" : (MyAvatar.skeletonModelURL === root.itemHref ? "CURRENT" : (root.buttonTextNormal)[itemTypesArray.indexOf(root.itemType)]);
anchors.topMargin: -4; anchors.verticalCenter: parent.verticalCenter;
anchors.right: parent.right; width: rezIconLabelTextMetrics.width;
anchors.left: parent.left; x: parent.width/2 - rezIconLabelTextMetrics.width/2 + rezIconTextMetrics.width/2;
anchors.bottom: parent.bottom;
font.capitalization: Font.AllUppercase
color: enabled ? hifi.buttons.textColor[control.color]
: hifi.buttons.disabledTextColor[control.colorScheme]
size: 15; size: 15;
verticalAlignment: Text.AlignVCenter font.capitalization: Font.AllUppercase;
horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter;
text: MyAvatar.skeletonModelURL === root.itemHref ? "CURRENT" : (root.buttonTextNormal)[itemTypesArray.indexOf(root.itemType)]; horizontalAlignment: Text.AlignHCenter;
color: enabled ? hifi.buttons.textColor[control.color]
: hifi.buttons.disabledTextColor[control.colorScheme]
} }
} }
} }
} }
} HiFiGlyphs {
// END "incorrect indentation to prevent insane diffs" 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 { onEntered: {
id: upgradeAvailableContainer; noPermissionGlyph.color = hifi.colors.redHighlight;
visible: root.upgradeUrl !== "" && !root.isShowingMyItems; }
anchors.top: itemContainer.bottom; onExited: {
anchors.bottom: parent.bottom; noPermissionGlyph.color = hifi.colors.redAccent;
anchors.left: parent.left; }
anchors.right: parent.right; onClicked: {
color: "#B5EAFF"; contextCard.z = 0;
permissionExplanationCard.z = 1;
RalewayRegular { root.sendToPurchases({ method: 'flipCard' });
id: updateAvailableText;
text: "UPDATE AVAILABLE";
size: 13;
anchors.left: parent.left;
anchors.leftMargin: 12;
anchors.top: parent.top;
anchors.bottom: parent.bottom;
width: paintedWidth;
color: hifi.colors.black;
verticalAlignment: Text.AlignVCenter;
}
RalewaySemiBold {
id: updateNowText;
text: "<font color='#0093C5'><a href='#'>Update this item now</a></font>";
size: 13;
anchors.left: updateAvailableText.right;
anchors.leftMargin: 16;
anchors.top: parent.top;
anchors.bottom: parent.bottom;
width: paintedWidth;
color: hifi.colors.black;
verticalAlignment: Text.AlignVCenter;
onLinkActivated: {
sendToPurchases({method: 'updateItemClicked', itemId: root.itemId, itemEdition: root.itemEdition, upgradeUrl: root.upgradeUrl});
} }
} }
} }
} }
DropShadow {
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 // FUNCTION DEFINITIONS START
// //

View file

@ -19,6 +19,7 @@ import "../../../controls" as HifiControls
import "../wallet" as HifiWallet import "../wallet" as HifiWallet
import "../common" as HifiCommerceCommon import "../common" as HifiCommerceCommon
import "../inspectionCertificate" as HifiInspectionCertificate import "../inspectionCertificate" as HifiInspectionCertificate
import "../common/sendAsset" as HifiSendAsset
// references XXX from root context // references XXX from root context
@ -31,7 +32,6 @@ Rectangle {
property bool securityImageResultReceived: false; property bool securityImageResultReceived: false;
property bool purchasesReceived: false; property bool purchasesReceived: false;
property bool punctuationMode: false; property bool punctuationMode: false;
property bool pendingInventoryReply: true;
property bool isShowingMyItems: false; property bool isShowingMyItems: false;
property bool isDebuggingFirstUseTutorial: false; property bool isDebuggingFirstUseTutorial: false;
property int pendingItemCount: 0; property int pendingItemCount: 0;
@ -114,12 +114,6 @@ Rectangle {
purchasesContentsList.positionViewAtIndex(currentIndex, ListView.Beginning); purchasesContentsList.positionViewAtIndex(currentIndex, ListView.Beginning);
} }
if (root.pendingInventoryReply && root.pendingItemCount > 0) {
inventoryTimer.start();
}
root.pendingInventoryReply = false;
} }
onAvailableUpdatesResult: { onAvailableUpdatesResult: {
@ -142,7 +136,7 @@ Rectangle {
HifiInspectionCertificate.InspectionCertificate { HifiInspectionCertificate.InspectionCertificate {
id: inspectionCertificate; id: inspectionCertificate;
z: 999; z: 998;
visible: false; visible: false;
anchors.fill: parent; anchors.fill: parent;
@ -155,6 +149,7 @@ Rectangle {
HifiCommerceCommon.CommerceLightbox { HifiCommerceCommon.CommerceLightbox {
id: lightboxPopup; id: lightboxPopup;
z: 999;
visible: false; visible: false;
anchors.fill: parent; anchors.fill: parent;
@ -169,12 +164,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 // TITLE BAR START
// //
HifiCommerceCommon.EmulatedMarketplaceHeader { HifiCommerceCommon.EmulatedMarketplaceHeader {
id: titleBarContainer; id: titleBarContainer;
z: 998; z: 997;
visible: !needsLogIn.visible; visible: !needsLogIn.visible;
// Size // Size
width: parent.width; width: parent.width;
@ -191,9 +207,14 @@ Rectangle {
lightboxPopup.bodyImageSource = msg.securityImageSource; lightboxPopup.bodyImageSource = msg.securityImageSource;
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText; lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
lightboxPopup.button1text = "CLOSE"; lightboxPopup.button1text = "CLOSE";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.button2text = "GO TO WALLET"; lightboxPopup.button2text = "GO TO WALLET";
lightboxPopup.button2method = "sendToParent({method: 'purchases_openWallet'});"; lightboxPopup.button2method = function() {
sendToScript({method: 'purchases_openWallet'});
lightboxPopup.visible = false;
};
lightboxPopup.visible = true; lightboxPopup.visible = true;
} else { } else {
sendToScript(msg); sendToScript(msg);
@ -308,7 +329,7 @@ Rectangle {
// FILTER BAR START // FILTER BAR START
// //
Item { Item {
z: 997; z: 996;
id: filterBarContainer; id: filterBarContainer;
// Size // Size
height: 40; height: 40;
@ -316,7 +337,7 @@ Rectangle {
anchors.left: parent.left; anchors.left: parent.left;
anchors.leftMargin: 8; anchors.leftMargin: 8;
anchors.right: parent.right; anchors.right: parent.right;
anchors.rightMargin: 16; anchors.rightMargin: 8;
anchors.top: parent.top; anchors.top: parent.top;
anchors.topMargin: 4; anchors.topMargin: 4;
@ -341,6 +362,7 @@ Rectangle {
colorScheme: hifi.colorSchemes.faintGray; colorScheme: hifi.colorSchemes.faintGray;
anchors.top: parent.top; anchors.top: parent.top;
anchors.right: parent.right; anchors.right: parent.right;
anchors.rightMargin: 8;
anchors.left: myText.right; anchors.left: myText.right;
anchors.leftMargin: 16; anchors.leftMargin: 16;
textFieldHeight: 39; textFieldHeight: 39;
@ -396,7 +418,7 @@ Rectangle {
// //
HifiControlsUit.Separator { HifiControlsUit.Separator {
z: 996; z: 995;
id: separator; id: separator;
colorScheme: 2; colorScheme: 2;
anchors.left: parent.left; anchors.left: parent.left;
@ -426,7 +448,6 @@ Rectangle {
snapMode: ListView.SnapToItem; snapMode: ListView.SnapToItem;
// Anchors // Anchors
anchors.top: separator.bottom; anchors.top: separator.bottom;
anchors.topMargin: 12;
anchors.left: parent.left; anchors.left: parent.left;
anchors.bottom: updatesAvailableBanner.visible ? updatesAvailableBanner.top : parent.bottom; anchors.bottom: updatesAvailableBanner.visible ? updatesAvailableBanner.top : parent.bottom;
width: parent.width; width: parent.width;
@ -437,13 +458,13 @@ Rectangle {
itemHref: download_url; itemHref: download_url;
certificateId: certificate_id; certificateId: certificate_id;
purchaseStatus: status; purchaseStatus: status;
purchaseStatusChanged: statusChanged;
itemEdition: model.edition_number; itemEdition: model.edition_number;
numberSold: model.number_sold; numberSold: model.number_sold;
limitedRun: model.limited_run; limitedRun: model.limited_run;
displayedItemCount: model.displayedItemCount; displayedItemCount: model.displayedItemCount;
permissionExplanationCardVisible: model.permissionExplanationCardVisible; cardBackVisible: model.cardBackVisible;
isInstalled: model.isInstalled; isInstalled: model.isInstalled;
wornEntityID: model.wornEntityID;
upgradeUrl: model.upgrade_url; upgradeUrl: model.upgrade_url;
upgradeTitle: model.upgrade_title; upgradeTitle: model.upgrade_title;
itemType: model.itemType; itemType: model.itemType;
@ -457,6 +478,11 @@ Rectangle {
sendToScript({method: 'purchases_itemInfoClicked', itemId: itemId}); sendToScript({method: 'purchases_itemInfoClicked', itemId: itemId});
} else if (msg.method === "purchases_rezClicked") { } else if (msg.method === "purchases_rezClicked") {
sendToScript({method: 'purchases_rezClicked', itemHref: itemHref, itemType: itemType}); 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') { } else if (msg.method === 'purchases_itemCertificateClicked') {
inspectionCertificate.visible = true; inspectionCertificate.visible = true;
inspectionCertificate.isLightbox = true; inspectionCertificate.isLightbox = true;
@ -466,14 +492,18 @@ Rectangle {
lightboxPopup.bodyText = 'Your item is marked "invalidated" because this item has been suspended ' + lightboxPopup.bodyText = 'Your item is marked "invalidated" because this item has been suspended ' +
"from the Marketplace due to a claim against its author."; "from the Marketplace due to a claim against its author.";
lightboxPopup.button1text = "CLOSE"; lightboxPopup.button1text = "CLOSE";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.visible = true; lightboxPopup.visible = true;
} else if (msg.method === "showPendingLightbox") { } else if (msg.method === "showPendingLightbox") {
lightboxPopup.titleText = "Item Pending"; lightboxPopup.titleText = "Item Pending";
lightboxPopup.bodyText = 'Your item is marked "pending" while your purchase is being confirmed. ' + lightboxPopup.bodyText = 'Your item is marked "pending" while your purchase is being confirmed. ' +
"Usually, purchases take about 90 seconds to confirm."; "Usually, purchases take about 90 seconds to confirm.";
lightboxPopup.button1text = "CLOSE"; lightboxPopup.button1text = "CLOSE";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.visible = true; lightboxPopup.visible = true;
} else if (msg.method === "showReplaceContentLightbox") { } else if (msg.method === "showReplaceContentLightbox") {
lightboxPopup.titleText = "Replace Content"; lightboxPopup.titleText = "Replace Content";
@ -483,17 +513,27 @@ Rectangle {
"<a href='https://docs.highfidelity.com/create-and-explore/start-working-in-your-sandbox/restoring-sandbox-content'>" + "<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."; "click here to open info on your desktop browser.";
lightboxPopup.button1text = "CANCEL"; lightboxPopup.button1text = "CANCEL";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.button2text = "CONFIRM"; 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; lightboxPopup.visible = true;
} else if (msg.method === "showChangeAvatarLightbox") { } else if (msg.method === "showChangeAvatarLightbox") {
lightboxPopup.titleText = "Change Avatar"; lightboxPopup.titleText = "Change Avatar";
lightboxPopup.bodyText = "This will change your current avatar to " + msg.itemName + " while retaining your wearables."; lightboxPopup.bodyText = "This will change your current avatar to " + msg.itemName + " while retaining your wearables.";
lightboxPopup.button1text = "CANCEL"; lightboxPopup.button1text = "CANCEL";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.button2text = "CONFIRM"; 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; lightboxPopup.visible = true;
} else if (msg.method === "showPermissionsExplanation") { } else if (msg.method === "showPermissionsExplanation") {
if (msg.itemType === "entity") { if (msg.itemType === "entity") {
@ -501,27 +541,86 @@ Rectangle {
lightboxPopup.bodyText = "You don't have permission to rez certified items in this domain.<br><br>" + 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>"; "Use the <b>GOTO app</b> to visit another domain or <b>go to your own sandbox.</b>";
lightboxPopup.button2text = "OPEN GOTO"; 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") { } else if (msg.itemType === "contentSet") {
lightboxPopup.titleText = "Replace Content Permission"; 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 " + 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."; "must enable it for you before you can replace content sets in this domain.";
} }
lightboxPopup.button1text = "CLOSE"; lightboxPopup.button1text = "CLOSE";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.visible = true; lightboxPopup.visible = true;
} else if (msg.method === "setFilterText") { } else if (msg.method === "setFilterText") {
filterBar.text = msg.filterText; filterBar.text = msg.filterText;
} else if (msg.method === "openPermissionExplanationCard") { } else if (msg.method === "flipCard") {
for (var i = 0; i < filteredPurchasesModel.count; i++) { for (var i = 0; i < filteredPurchasesModel.count; i++) {
if (i !== index || msg.closeAll) { if (i !== index || msg.closeAll) {
filteredPurchasesModel.setProperty(i, "permissionExplanationCardVisible", false); filteredPurchasesModel.setProperty(i, "cardBackVisible", false);
} else { } else {
filteredPurchasesModel.setProperty(i, "permissionExplanationCardVisible", true); filteredPurchasesModel.setProperty(i, "cardBackVisible", true);
} }
} }
} else if (msg.method === "updateItemClicked") { } else if (msg.method === "updateItemClicked") {
sendToScript(msg); 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";
}
} }
} }
} }
@ -693,6 +792,7 @@ Rectangle {
HifiControlsUit.Keyboard { HifiControlsUit.Keyboard {
id: keyboard; id: keyboard;
z: 999;
raised: HMD.mounted && parent.keyboardRaised; raised: HMD.mounted && parent.keyboardRaised;
numeric: parent.punctuationMode; numeric: parent.punctuationMode;
anchors { anchors {
@ -702,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 // FUNCTION DEFINITIONS START
// //
@ -833,10 +913,12 @@ Rectangle {
continue; continue;
} }
filteredPurchasesModel.append(tempPurchasesModel.get(i)); 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, 'isInstalled', ((root.installedApps).indexOf(currentId) > -1));
filteredPurchasesModel.setProperty(i, 'wornEntityID', '');
} }
sendToScript({ method: 'purchases_updateWearables' });
populateDisplayedItemCounts(); populateDisplayedItemCounts();
sortByDate(); sortByDate();
} }
@ -863,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() // Function Name: fromScript()
@ -890,6 +985,16 @@ Rectangle {
case 'purchases_showMyItems': case 'purchases_showMyItems':
root.isShowingMyItems = true; root.isShowingMyItems = true;
break; break;
case 'updateConnections':
sendAsset.updateConnections(message.connections);
break;
case 'selectRecipient':
case 'updateSelectedRecipientUsername':
sendAsset.fromScript(message);
break;
case 'updateWearables':
updateCurrentlyWornWearables(message.wornWearables);
break;
default: default:
console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message)); console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
} }

View file

@ -143,7 +143,9 @@ Item {
lightboxPopup.bodyImageSource = titleBarSecurityImage.source; lightboxPopup.bodyImageSource = titleBarSecurityImage.source;
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText; lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
lightboxPopup.button1text = "CLOSE"; lightboxPopup.button1text = "CLOSE";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.visible = true; lightboxPopup.visible = true;
} }
} }

View file

@ -42,18 +42,6 @@ Item {
} }
} }
} }
// This will cause a bug -- if you bring up security image selection in HUD mode while
// in HMD while having HMD preview enabled, then move, then finish passphrase selection,
// HMD preview will stay off.
// TODO: Fix this unlikely bug
onVisibleChanged: {
if (visible) {
sendSignalToWallet({method: 'disableHmdPreview'});
} else {
sendSignalToWallet({method: 'maybeEnableHmdPreview'});
}
}
// Security Image // Security Image
Item { Item {

View file

@ -18,7 +18,7 @@ import "../../../styles-uit"
import "../../../controls-uit" as HifiControlsUit import "../../../controls-uit" as HifiControlsUit
import "../../../controls" as HifiControls import "../../../controls" as HifiControls
import "../common" as HifiCommerceCommon import "../common" as HifiCommerceCommon
import "./sendMoney" import "../common/sendAsset"
Rectangle { Rectangle {
HifiConstants { id: hifi; } HifiConstants { id: hifi; }
@ -160,7 +160,9 @@ Rectangle {
lightboxPopup.bodyImageSource = titleBarSecurityImage.source; lightboxPopup.bodyImageSource = titleBarSecurityImage.source;
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText; lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
lightboxPopup.button1text = "CLOSE"; lightboxPopup.button1text = "CLOSE";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.visible = true; lightboxPopup.visible = true;
} }
} }
@ -341,7 +343,7 @@ Rectangle {
} }
} }
SendMoney { SendAsset {
id: sendMoney; id: sendMoney;
z: 997; z: 997;
visible: root.activeView === "sendMoney"; visible: root.activeView === "sendMoney";
@ -350,7 +352,7 @@ Rectangle {
parentAppNavBarHeight: tabButtonsContainer.height; parentAppNavBarHeight: tabButtonsContainer.height;
Connections { Connections {
onSendSignalToWallet: { onSendSignalToParent: {
sendToScript(msg); sendToScript(msg);
} }
} }
@ -405,7 +407,7 @@ Rectangle {
// //
Item { Item {
id: tabButtonsContainer; 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; property int numTabs: 5;
// Size // Size
width: root.width; width: root.width;

View file

@ -206,9 +206,14 @@ Item {
"This step cannot be undone."; "This step cannot be undone.";
lightboxPopup.button1color = hifi.buttons.red; lightboxPopup.button1color = hifi.buttons.red;
lightboxPopup.button1text = "YES, CREATE NEW WALLET"; 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.button2text = "CANCEL";
lightboxPopup.button2method = "root.visible = false;" lightboxPopup.button2method = function() {
lightboxPopup.visible = false;
};
lightboxPopup.buttonLayout = "topbottom"; lightboxPopup.buttonLayout = "topbottom";
lightboxPopup.visible = true; 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 " + "If you'd prefer to create a new wallet (not recommended - you will lose your money and past " +
"purchases), click 'Create New Wallet'."; "purchases), click 'Create New Wallet'.";
lightboxPopup.button1text = "CLOSE"; lightboxPopup.button1text = "CLOSE";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.visible = true; lightboxPopup.visible = true;
} else { } else {
lightboxPopup.titleText = "You may have set up more than one wallet"; 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 " + "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."; "you've stored the private keys for that wallet.";
lightboxPopup.button1text = "CLOSE"; lightboxPopup.button1text = "CLOSE";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.visible = true; lightboxPopup.visible = true;
} }
} }

View file

@ -76,7 +76,7 @@ Item {
UserActivityLogger.commerceWalletSetupProgress(timestamp, root.setupAttemptID, UserActivityLogger.commerceWalletSetupProgress(timestamp, root.setupAttemptID,
Math.round((timestamp - root.startingTimestamp)/1000), currentStepNumber, root.setupStepNames[currentStepNumber - 1]); Math.round((timestamp - root.startingTimestamp)/1000), currentStepNumber, root.setupStepNames[currentStepNumber - 1]);
if (root.activeView === "step_2" || root.activeView === "step_3") { if (root.activeView === "step_3") {
sendSignalToWallet({method: 'disableHmdPreview'}); sendSignalToWallet({method: 'disableHmdPreview'});
} else { } else {
sendSignalToWallet({method: 'maybeEnableHmdPreview'}); sendSignalToWallet({method: 'maybeEnableHmdPreview'});
@ -150,7 +150,9 @@ Item {
lightboxPopup.bodyImageSource = titleBarSecurityImage.source; lightboxPopup.bodyImageSource = titleBarSecurityImage.source;
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText; lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
lightboxPopup.button1text = "CLOSE"; lightboxPopup.button1text = "CLOSE";
lightboxPopup.button1method = "root.visible = false;" lightboxPopup.button1method = function() {
lightboxPopup.visible = false;
}
lightboxPopup.visible = true; lightboxPopup.visible = true;
} }
} }

View file

@ -344,5 +344,10 @@ QtObject {
readonly property string wand: "\ue02d" readonly property string wand: "\ue02d"
readonly property string hat: "\ue02e" readonly property string hat: "\ue02e"
readonly property string install: "\ue02f" 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"
} }
} }

View file

@ -2563,6 +2563,7 @@ void Application::initializeUi() {
QUrl{ "hifi/commerce/common/EmulatedMarketplaceHeader.qml" }, QUrl{ "hifi/commerce/common/EmulatedMarketplaceHeader.qml" },
QUrl{ "hifi/commerce/common/FirstUseTutorial.qml" }, QUrl{ "hifi/commerce/common/FirstUseTutorial.qml" },
QUrl{ "hifi/commerce/common/SortableListModel.qml" }, QUrl{ "hifi/commerce/common/SortableListModel.qml" },
QUrl{ "hifi/commerce/common/sendAsset/SendAsset.qml" },
QUrl{ "hifi/commerce/inspectionCertificate/InspectionCertificate.qml" }, QUrl{ "hifi/commerce/inspectionCertificate/InspectionCertificate.qml" },
QUrl{ "hifi/commerce/purchases/PurchasedItem.qml" }, QUrl{ "hifi/commerce/purchases/PurchasedItem.qml" },
QUrl{ "hifi/commerce/purchases/Purchases.qml" }, QUrl{ "hifi/commerce/purchases/Purchases.qml" },
@ -2575,7 +2576,6 @@ void Application::initializeUi() {
QUrl{ "hifi/commerce/wallet/SecurityImageChange.qml" }, QUrl{ "hifi/commerce/wallet/SecurityImageChange.qml" },
QUrl{ "hifi/commerce/wallet/SecurityImageModel.qml" }, QUrl{ "hifi/commerce/wallet/SecurityImageModel.qml" },
QUrl{ "hifi/commerce/wallet/SecurityImageSelection.qml" }, QUrl{ "hifi/commerce/wallet/SecurityImageSelection.qml" },
QUrl{ "hifi/commerce/wallet/sendMoney/SendMoney.qml" },
QUrl{ "hifi/commerce/wallet/Wallet.qml" }, QUrl{ "hifi/commerce/wallet/Wallet.qml" },
QUrl{ "hifi/commerce/wallet/WalletHome.qml" }, QUrl{ "hifi/commerce/wallet/WalletHome.qml" },
QUrl{ "hifi/commerce/wallet/WalletSetup.qml" }, QUrl{ "hifi/commerce/wallet/WalletSetup.qml" },

View file

@ -56,8 +56,8 @@ Handler(buy)
Handler(receiveAt) Handler(receiveAt)
Handler(balance) Handler(balance)
Handler(inventory) Handler(inventory)
Handler(transferHfcToNode) Handler(transferAssetToNode)
Handler(transferHfcToUsername) Handler(transferAssetToUsername)
Handler(alreadyOwned) Handler(alreadyOwned)
Handler(availableUpdates) Handler(availableUpdates)
Handler(updateItem) Handler(updateItem)
@ -173,7 +173,8 @@ QString userLink(const QString& username, const QString& placename) {
QString transactionString(const QJsonObject& valueObject) { QString transactionString(const QJsonObject& valueObject) {
int sentCerts = valueObject["sent_certs"].toInt(); int sentCerts = valueObject["sent_certs"].toInt();
int receivedCerts = valueObject["received_certs"].toInt(); int receivedCerts = valueObject["received_certs"].toInt();
int sent = valueObject["sent_money"].toInt(); int sentMoney = valueObject["sent_money"].toInt();
int receivedMoney = valueObject["received_money"].toInt();
int dateInteger = valueObject["created_at"].toInt(); int dateInteger = valueObject["created_at"].toInt();
QString message = valueObject["message"].toString(); QString message = valueObject["message"].toString();
QDateTime createdAt(QDateTime::fromSecsSinceEpoch(dateInteger, Qt::UTC)); QDateTime createdAt(QDateTime::fromSecsSinceEpoch(dateInteger, Qt::UTC));
@ -181,7 +182,7 @@ QString transactionString(const QJsonObject& valueObject) {
if (sentCerts <= 0 && receivedCerts <= 0 && !KNOWN_USERS.contains(valueObject["sender_name"].toString())) { if (sentCerts <= 0 && receivedCerts <= 0 && !KNOWN_USERS.contains(valueObject["sender_name"].toString())) {
// this is an hfc transfer. // this is an hfc transfer.
if (sent > 0) { if (sentMoney > 0) {
QString recipient = userLink(valueObject["recipient_name"].toString(), valueObject["place_name"].toString()); QString recipient = userLink(valueObject["recipient_name"].toString(), valueObject["place_name"].toString());
result += QString("Money sent to %1").arg(recipient); result += QString("Money sent to %1").arg(recipient);
} else { } else {
@ -191,6 +192,18 @@ QString transactionString(const QJsonObject& valueObject) {
if (!message.isEmpty()) { if (!message.isEmpty()) {
result += QString("<br>with memo: <i>\"%1\"</i>").arg(message); result += QString("<br>with memo: <i>\"%1\"</i>").arg(message);
} }
} else if (sentMoney <= 0 && receivedMoney <= 0 && (sentCerts > 0 || receivedCerts > 0) && !KNOWN_USERS.contains(valueObject["sender_name"].toString())) {
// this is a non-HFC asset transfer.
if (sentCerts > 0) {
QString recipient = userLink(valueObject["recipient_name"].toString(), valueObject["place_name"].toString());
result += QString("Gift sent to %1").arg(recipient);
} else {
QString sender = userLink(valueObject["sender_name"].toString(), valueObject["place_name"].toString());
result += QString("Gift from %1").arg(sender);
}
if (!message.isEmpty()) {
result += QString("<br>with memo: <i>\"%1\"</i>").arg(message);
}
} else { } else {
result += valueObject["message"].toString(); result += valueObject["message"].toString();
} }
@ -354,27 +367,41 @@ void Ledger::certificateInfo(const QString& certificateId) {
send(endpoint, "certificateInfoSuccess", "certificateInfoFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::None, request); 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; QJsonObject transaction;
transaction["public_key"] = hfc_key; transaction["public_key"] = hfc_key;
transaction["node_id"] = nodeID; transaction["node_id"] = nodeID;
transaction["quantity"] = amount; transaction["quantity"] = amount;
transaction["message"] = optionalMessage; transaction["message"] = optionalMessage;
transaction["place_name"] = DependencyManager::get<AddressManager>()->getPlaceName(); transaction["place_name"] = DependencyManager::get<AddressManager>()->getPlaceName();
if (!certificateID.isEmpty()) {
transaction["certificate_id"] = certificateID;
}
QJsonDocument transactionDoc{ transaction }; QJsonDocument transactionDoc{ transaction };
auto transactionString = transactionDoc.toJson(QJsonDocument::Compact); 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; QJsonObject transaction;
transaction["public_key"] = hfc_key; transaction["public_key"] = hfc_key;
transaction["username"] = username; transaction["username"] = username;
transaction["quantity"] = amount; transaction["quantity"] = amount;
transaction["message"] = optionalMessage; transaction["message"] = optionalMessage;
if (!certificateID.isEmpty()) {
transaction["certificate_id"] = certificateID;
}
QJsonDocument transactionDoc{ transaction }; QJsonDocument transactionDoc{ transaction };
auto transactionString = transactionDoc.toJson(QJsonDocument::Compact); 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) { void Ledger::alreadyOwned(const QString& marketplaceId) {

View file

@ -33,8 +33,8 @@ public:
void account(); void account();
void updateLocation(const QString& asset_id, const QString& location, const bool& alsoUpdateSiblings = false, const bool controlledFailure = false); void updateLocation(const QString& asset_id, const QString& location, const bool& alsoUpdateSiblings = false, const bool controlledFailure = false);
void certificateInfo(const QString& certificateId); void certificateInfo(const QString& certificateId);
void transferHfcToNode(const QString& hfc_key, const QString& nodeID, 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 transferHfcToUsername(const QString& hfc_key, const QString& username, 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 alreadyOwned(const QString& marketplaceId);
void getAvailableUpdates(const QString& itemId = ""); void getAvailableUpdates(const QString& itemId = "");
void updateItem(const QString& hfc_key, const QString& certificate_id); void updateItem(const QString& hfc_key, const QString& certificate_id);
@ -56,8 +56,8 @@ signals:
void accountResult(QJsonObject result); void accountResult(QJsonObject result);
void locationUpdateResult(QJsonObject result); void locationUpdateResult(QJsonObject result);
void certificateInfoResult(QJsonObject result); void certificateInfoResult(QJsonObject result);
void transferHfcToNodeResult(QJsonObject result); void transferAssetToNodeResult(QJsonObject result);
void transferHfcToUsernameResult(QJsonObject result); void transferAssetToUsernameResult(QJsonObject result);
void alreadyOwnedResult(QJsonObject result); void alreadyOwnedResult(QJsonObject result);
void availableUpdatesResult(QJsonObject result); void availableUpdatesResult(QJsonObject result);
void updateItemResult(QJsonObject result); void updateItemResult(QJsonObject result);
@ -81,10 +81,10 @@ public slots:
void updateLocationFailure(QNetworkReply& reply); void updateLocationFailure(QNetworkReply& reply);
void certificateInfoSuccess(QNetworkReply& reply); void certificateInfoSuccess(QNetworkReply& reply);
void certificateInfoFailure(QNetworkReply& reply); void certificateInfoFailure(QNetworkReply& reply);
void transferHfcToNodeSuccess(QNetworkReply& reply); void transferAssetToNodeSuccess(QNetworkReply& reply);
void transferHfcToNodeFailure(QNetworkReply& reply); void transferAssetToNodeFailure(QNetworkReply& reply);
void transferHfcToUsernameSuccess(QNetworkReply& reply); void transferAssetToUsernameSuccess(QNetworkReply& reply);
void transferHfcToUsernameFailure(QNetworkReply& reply); void transferAssetToUsernameFailure(QNetworkReply& reply);
void alreadyOwnedSuccess(QNetworkReply& reply); void alreadyOwnedSuccess(QNetworkReply& reply);
void alreadyOwnedFailure(QNetworkReply& reply); void alreadyOwnedFailure(QNetworkReply& reply);
void availableUpdatesSuccess(QNetworkReply& reply); void availableUpdatesSuccess(QNetworkReply& reply);

View file

@ -36,8 +36,8 @@ QmlCommerce::QmlCommerce() {
connect(ledger.data(), &Ledger::certificateInfoResult, this, &QmlCommerce::certificateInfoResult); connect(ledger.data(), &Ledger::certificateInfoResult, this, &QmlCommerce::certificateInfoResult);
connect(ledger.data(), &Ledger::alreadyOwnedResult, this, &QmlCommerce::alreadyOwnedResult); connect(ledger.data(), &Ledger::alreadyOwnedResult, this, &QmlCommerce::alreadyOwnedResult);
connect(ledger.data(), &Ledger::updateCertificateStatus, this, &QmlCommerce::updateCertificateStatus); connect(ledger.data(), &Ledger::updateCertificateStatus, this, &QmlCommerce::updateCertificateStatus);
connect(ledger.data(), &Ledger::transferHfcToNodeResult, this, &QmlCommerce::transferHfcToNodeResult); connect(ledger.data(), &Ledger::transferAssetToNodeResult, this, &QmlCommerce::transferAssetToNodeResult);
connect(ledger.data(), &Ledger::transferHfcToUsernameResult, this, &QmlCommerce::transferHfcToUsernameResult); connect(ledger.data(), &Ledger::transferAssetToUsernameResult, this, &QmlCommerce::transferAssetToUsernameResult);
connect(ledger.data(), &Ledger::availableUpdatesResult, this, &QmlCommerce::availableUpdatesResult); connect(ledger.data(), &Ledger::availableUpdatesResult, this, &QmlCommerce::availableUpdatesResult);
connect(ledger.data(), &Ledger::updateItemResult, this, &QmlCommerce::updateItemResult); connect(ledger.data(), &Ledger::updateItemResult, this, &QmlCommerce::updateItemResult);
@ -166,28 +166,28 @@ void QmlCommerce::certificateInfo(const QString& certificateId) {
ledger->certificateInfo(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 ledger = DependencyManager::get<Ledger>();
auto wallet = DependencyManager::get<Wallet>(); auto wallet = DependencyManager::get<Wallet>();
QStringList keys = wallet->listPublicKeys(); QStringList keys = wallet->listPublicKeys();
if (keys.count() == 0) { if (keys.count() == 0) {
QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } }; QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } };
return emit buyResult(result); return emit transferAssetToNodeResult(result);
} }
QString key = keys[0]; 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 ledger = DependencyManager::get<Ledger>();
auto wallet = DependencyManager::get<Wallet>(); auto wallet = DependencyManager::get<Wallet>();
QStringList keys = wallet->listPublicKeys(); QStringList keys = wallet->listPublicKeys();
if (keys.count() == 0) { if (keys.count() == 0) {
QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } }; QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } };
return emit buyResult(result); return emit transferAssetToUsernameResult(result);
} }
QString key = keys[0]; 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) { void QmlCommerce::replaceContentSet(const QString& itemHref, const QString& certificateID) {

View file

@ -48,8 +48,8 @@ signals:
void updateCertificateStatus(const QString& certID, uint certStatus); void updateCertificateStatus(const QString& certID, uint certStatus);
void transferHfcToNodeResult(QJsonObject result); void transferAssetToNodeResult(QJsonObject result);
void transferHfcToUsernameResult(QJsonObject result); void transferAssetToUsernameResult(QJsonObject result);
void contentSetChanged(const QString& contentSetHref); void contentSetChanged(const QString& contentSetHref);
@ -81,8 +81,8 @@ protected:
Q_INVOKABLE void certificateInfo(const QString& certificateId); Q_INVOKABLE void certificateInfo(const QString& certificateId);
Q_INVOKABLE void alreadyOwned(const QString& marketplaceId); Q_INVOKABLE void alreadyOwned(const QString& marketplaceId);
Q_INVOKABLE void transferHfcToNode(const QString& nodeID, 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 transferHfcToUsername(const QString& username, 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); Q_INVOKABLE void replaceContentSet(const QString& itemHref, const QString& certificateID);

View file

@ -13,8 +13,9 @@
#include "Ledger.h" #include "Ledger.h"
#include "Wallet.h" #include "Wallet.h"
#include "Application.h" #include "Application.h"
#include "ui/ImageProvider.h" #include "ui/SecurityImageProvider.h"
#include "scripting/HMDScriptingInterface.h" #include "scripting/HMDScriptingInterface.h"
#include <ui/TabletScriptingInterface.h>
#include <PathUtils.h> #include <PathUtils.h>
#include <OffscreenUi.h> #include <OffscreenUi.h>
@ -566,7 +567,6 @@ bool Wallet::generateKeyPair() {
} }
QStringList Wallet::listPublicKeys() { QStringList Wallet::listPublicKeys() {
qCInfo(commerce) << "Enumerating public keys.";
return _publicKeys; return _publicKeys;
} }
@ -607,11 +607,17 @@ QString Wallet::signWithKey(const QByteArray& text, const QString& key) {
} }
void Wallet::updateImageProvider() { void Wallet::updateImageProvider() {
// inform the image provider. Note it doesn't matter which one you inform, as the SecurityImageProvider* securityImageProvider;
// images are statics
auto engine = DependencyManager::get<OffscreenUi>()->getSurfaceContext()->engine(); // inform offscreenUI security image provider
auto imageProvider = reinterpret_cast<ImageProvider*>(engine->imageProvider(ImageProvider::PROVIDER_NAME)); QQmlEngine* engine = DependencyManager::get<OffscreenUi>()->getSurfaceContext()->engine();
imageProvider->setSecurityImage(_securityImage); securityImageProvider = reinterpret_cast<SecurityImageProvider*>(engine->imageProvider(SecurityImageProvider::PROVIDER_NAME));
securityImageProvider->setSecurityImage(_securityImage);
// inform tablet security image provider
QQmlEngine* tabletEngine = DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system")->getTabletSurface()->getSurfaceContext()->engine();
securityImageProvider = reinterpret_cast<SecurityImageProvider*>(tabletEngine->imageProvider(SecurityImageProvider::PROVIDER_NAME));
securityImageProvider->setSecurityImage(_securityImage);
} }
void Wallet::chooseSecurityImage(const QString& filename) { void Wallet::chooseSecurityImage(const QString& filename) {
@ -651,6 +657,7 @@ bool Wallet::getSecurityImage() {
// if already decrypted, don't do it again // if already decrypted, don't do it again
if (_securityImage) { if (_securityImage) {
updateImageProvider();
emit securityImageResult(true); emit securityImageResult(true);
return true; return true;
} }

View file

@ -759,7 +759,7 @@ QVector<QUuid> EntityScriptingInterface::findEntitiesByType(const QString entity
foreach(EntityItemPointer entity, entities) { foreach(EntityItemPointer entity, entities) {
if (entity->getType() == type) { if (entity->getType() == type) {
result << entity->getEntityItemID(); result << entity->getEntityItemID().toString();
} }
} }
} }

View file

@ -1,59 +0,0 @@
//
// ImageProvider.cpp
// interface/src/ui
//
// Created by David Kelly on 8/23/2017.
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "ImageProvider.h"
#include <QReadLocker>
#include <QWriteLocker>
const QString ImageProvider::PROVIDER_NAME = "security";
QReadWriteLock ImageProvider::_rwLock;
QPixmap* ImageProvider::_securityImage = nullptr;
ImageProvider::~ImageProvider() {
QWriteLocker lock(&_rwLock);
if (_securityImage) {
delete _securityImage;
_securityImage = nullptr;
}
}
void ImageProvider::setSecurityImage(const QPixmap* pixmap) {
// no need to delete old one, that is managed by the wallet
QWriteLocker lock(&_rwLock);
if (_securityImage) {
delete _securityImage;
}
if (pixmap) {
_securityImage = new QPixmap(*pixmap);
} else {
_securityImage = nullptr;
}
}
QPixmap ImageProvider::requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) {
// adjust the internal pixmap to have the requested size
QReadLocker lock(&_rwLock);
if (id == "securityImage" && _securityImage) {
*size = _securityImage->size();
if (requestedSize.width() > 0 && requestedSize.height() > 0) {
return _securityImage->scaled(requestedSize.width(), requestedSize.height(), Qt::KeepAspectRatio);
} else {
return _securityImage->copy();
}
}
// otherwise just return a grey pixmap. This avoids annoying error messages in qml we would get
// when sending a 'null' pixmap (QPixmap())
QPixmap greyPixmap(200, 200);
greyPixmap.fill(QColor("darkGrey"));
return greyPixmap;
}

View file

@ -48,7 +48,7 @@
#include <gl/Context.h> #include <gl/Context.h>
#include <shared/ReadWriteLockable.h> #include <shared/ReadWriteLockable.h>
#include "ImageProvider.h" #include "SecurityImageProvider.h"
#include "types/FileTypeProfile.h" #include "types/FileTypeProfile.h"
#include "types/HFWebEngineProfile.h" #include "types/HFWebEngineProfile.h"
#include "types/SoundEffect.h" #include "types/SoundEffect.h"
@ -233,8 +233,8 @@ void OffscreenQmlSurface::initializeEngine(QQmlEngine* engine) {
qmlRegisterType<SoundEffect>("Hifi", 1, 0, "SoundEffect"); qmlRegisterType<SoundEffect>("Hifi", 1, 0, "SoundEffect");
}); });
// register the pixmap image provider (used only for security image, for now) // Register the pixmap Security Image Provider
engine->addImageProvider(ImageProvider::PROVIDER_NAME, new ImageProvider()); engine->addImageProvider(SecurityImageProvider::PROVIDER_NAME, new SecurityImageProvider());
engine->setNetworkAccessManagerFactory(new QmlNetworkAccessManagerFactory); engine->setNetworkAccessManagerFactory(new QmlNetworkAccessManagerFactory);
auto importList = engine->importPathList(); auto importList = engine->importPathList();
@ -344,6 +344,7 @@ void OffscreenQmlSurface::onRootCreated() {
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", this); tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", this);
QObject* tablet = tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"); QObject* tablet = tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system");
getSurfaceContext()->engine()->setObjectOwnership(tablet, QQmlEngine::CppOwnership); getSurfaceContext()->engine()->setObjectOwnership(tablet, QQmlEngine::CppOwnership);
getSurfaceContext()->engine()->addImageProvider(SecurityImageProvider::PROVIDER_NAME, new SecurityImageProvider());
} }
QMetaObject::invokeMethod(this, "forceQmlAudioOutputDeviceUpdate", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "forceQmlAudioOutputDeviceUpdate", Qt::QueuedConnection);
} }

View file

@ -0,0 +1,52 @@
//
// SecurityImageProvider.cpp
// interface/src/ui
//
// Created by David Kelly on 8/23/2017.
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "SecurityImageProvider.h"
#include <QReadLocker>
#include <QWriteLocker>
const QString SecurityImageProvider::PROVIDER_NAME = "security";
SecurityImageProvider::~SecurityImageProvider() {
}
void SecurityImageProvider::setSecurityImage(const QPixmap* pixmap) {
// no need to delete old one, that is managed by the wallet
QWriteLocker lock(&_rwLock);
if (pixmap) {
_securityImage = pixmap->copy();
} else {
QPixmap greyPixmap(200, 200);
greyPixmap.fill(QColor("darkGrey"));
_securityImage = greyPixmap.copy();
}
}
QPixmap SecurityImageProvider::requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) {
// adjust the internal pixmap to have the requested size
QReadLocker lock(&_rwLock);
if (id == "securityImage") {
*size = _securityImage.size();
if (requestedSize.width() > 0 && requestedSize.height() > 0) {
return _securityImage.scaled(requestedSize.width(), requestedSize.height(), Qt::KeepAspectRatio);
} else {
return _securityImage.copy();
}
}
// otherwise just return a grey pixmap. This avoids annoying error messages in qml we would get
// when sending a 'null' pixmap (QPixmap())
QPixmap greyPixmap(200, 200);
greyPixmap.fill(QColor("darkGrey"));
return greyPixmap;
}

View file

@ -1,5 +1,5 @@
// //
// ImageProvider.h // SecurityImageProvider.h
// //
// Created by David Kelly on 2017/08/23 // Created by David Kelly on 2017/08/23
// Copyright 2017 High Fidelity, Inc. // Copyright 2017 High Fidelity, Inc.
@ -9,26 +9,25 @@
// //
#pragma once #pragma once
#ifndef hifi_ImageProvider_h #ifndef hifi_SecurityImageProvider_h
#define hifi_ImageProvider_h #define hifi_SecurityImageProvider_h
#include <QQuickImageProvider> #include <QQuickImageProvider>
#include <QReadWriteLock> #include <QReadWriteLock>
class ImageProvider: public QQuickImageProvider { class SecurityImageProvider: public QQuickImageProvider {
public: public:
static const QString PROVIDER_NAME; static const QString PROVIDER_NAME;
ImageProvider() : QQuickImageProvider(QQuickImageProvider::Pixmap) {} SecurityImageProvider() : QQuickImageProvider(QQuickImageProvider::Pixmap) {}
virtual ~ImageProvider(); virtual ~SecurityImageProvider();
QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) override; QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize) override;
void setSecurityImage(const QPixmap* pixmap); void setSecurityImage(const QPixmap* pixmap);
protected: protected:
static QReadWriteLock _rwLock; QReadWriteLock _rwLock;
static QPixmap* _securityImage; QPixmap _securityImage;
}; };
#endif //hifi_ImageProvider_h #endif //hifi_SecurityImageProvider_h

View file

@ -18,8 +18,6 @@
var bubbleOverlayTimestamp; var bubbleOverlayTimestamp;
// Used for rate limiting the bubble sound // Used for rate limiting the bubble sound
var lastBubbleSoundTimestamp = 0; var lastBubbleSoundTimestamp = 0;
// Used for flashing the HUD button upon activation
var bubbleButtonFlashState = false;
// Affects bubble height // Affects bubble height
var BUBBLE_HEIGHT_SCALE = 0.15; var BUBBLE_HEIGHT_SCALE = 0.15;
// The bubble model itself // The bubble model itself
@ -36,18 +34,16 @@
var bubbleActivateSound = SoundCache.getSound(Script.resolvePath("assets/sounds/bubble.wav")); var bubbleActivateSound = SoundCache.getSound(Script.resolvePath("assets/sounds/bubble.wav"));
// Is the update() function connected? // Is the update() function connected?
var updateConnected = false; var updateConnected = false;
var bubbleFlashTimer = false;
var BUBBLE_VISIBLE_DURATION_MS = 3000; var BUBBLE_VISIBLE_DURATION_MS = 3000;
var BUBBLE_RAISE_ANIMATION_DURATION_MS = 750; var BUBBLE_RAISE_ANIMATION_DURATION_MS = 750;
var BUBBLE_SOUND_RATE_LIMIT_MS = 15000; var BUBBLE_SOUND_RATE_LIMIT_MS = 15000;
// Hides the bubble model overlay and resets the button flash state // Hides the bubble model overlay
function hideOverlays() { function hideOverlays() {
Overlays.editOverlay(bubbleOverlay, { Overlays.editOverlay(bubbleOverlay, {
visible: false visible: false
}); });
bubbleButtonFlashState = false;
} }
// Make the bubble overlay visible, set its position, and play the sound // Make the bubble overlay visible, set its position, and play the sound
@ -89,8 +85,6 @@
bubbleOverlayTimestamp = nowTimestamp; bubbleOverlayTimestamp = nowTimestamp;
Script.update.connect(update); Script.update.connect(update);
updateConnected = true; updateConnected = true;
writeButtonProperties(bubbleButtonFlashState);
bubbleButtonFlashState = !bubbleButtonFlashState;
} }
// Called from the C++ scripting interface to show the bubble overlay // Called from the C++ scripting interface to show the bubble overlay
@ -110,7 +104,6 @@
var delay = (timestamp - bubbleOverlayTimestamp); var delay = (timestamp - bubbleOverlayTimestamp);
var overlayAlpha = 1.0 - (delay / BUBBLE_VISIBLE_DURATION_MS); var overlayAlpha = 1.0 - (delay / BUBBLE_VISIBLE_DURATION_MS);
if (overlayAlpha > 0) { if (overlayAlpha > 0) {
if (delay < BUBBLE_RAISE_ANIMATION_DURATION_MS) { if (delay < BUBBLE_RAISE_ANIMATION_DURATION_MS) {
Overlays.editOverlay(bubbleOverlay, { Overlays.editOverlay(bubbleOverlay, {
dimensions: { dimensions: {
@ -158,11 +151,6 @@
Script.update.disconnect(update); Script.update.disconnect(update);
updateConnected = false; updateConnected = false;
} }
if (bubbleFlashTimer) {
Script.clearTimeout(bubbleFlashTimer);
bubbleFlashTimer = false;
}
writeButtonProperties(Users.getIgnoreRadiusEnabled());
} }
} }
@ -170,10 +158,6 @@
// NOTE: the c++ calls this with just the first param -- we added a second // NOTE: the c++ calls this with just the first param -- we added a second
// just for not logging the initial state of the bubble when we startup. // just for not logging the initial state of the bubble when we startup.
function onBubbleToggled(enabled, doNotLog) { function onBubbleToggled(enabled, doNotLog) {
if (bubbleFlashTimer) {
Script.clearTimeout(bubbleFlashTimer);
bubbleFlashTimer = false;
}
writeButtonProperties(enabled); writeButtonProperties(enabled);
if (doNotLog !== true) { if (doNotLog !== true) {
UserActivityLogger.bubbleToggled(enabled); UserActivityLogger.bubbleToggled(enabled);
@ -208,17 +192,12 @@
// Cleanup the tablet button and overlays when script is stopped // Cleanup the tablet button and overlays when script is stopped
Script.scriptEnding.connect(function () { Script.scriptEnding.connect(function () {
button.clicked.disconnect(Users.toggleIgnoreRadius); button.clicked.disconnect(Users.toggleIgnoreRadius);
if (bubbleFlashTimer) {
Script.clearTimeout(bubbleFlashTimer);
bubbleFlashTimer = false;
}
if (tablet) { if (tablet) {
tablet.removeButton(button); tablet.removeButton(button);
} }
Users.ignoreRadiusEnabledChanged.disconnect(onBubbleToggled); Users.ignoreRadiusEnabledChanged.disconnect(onBubbleToggled);
Users.enteredIgnoreRadius.disconnect(enteredIgnoreRadius); Users.enteredIgnoreRadius.disconnect(enteredIgnoreRadius);
Overlays.deleteOverlay(bubbleOverlay); Overlays.deleteOverlay(bubbleOverlay);
bubbleButtonFlashState = false;
if (updateConnected === true) { if (updateConnected === true) {
Script.update.disconnect(update); Script.update.disconnect(update);
} }

View file

@ -11,140 +11,16 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
/*global XXX */ /* global getConnectionData */
(function () { // BEGIN LOCAL_SCOPE (function () { // BEGIN LOCAL_SCOPE
Script.include("/~/system/libraries/accountUtils.js"); Script.include("/~/system/libraries/accountUtils.js");
var request = Script.require('request').request; Script.include("/~/system/libraries/connectionUtils.js");
var MARKETPLACE_URL = Account.metaverseServerURL + "/marketplace"; 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() // BEGIN AVATAR SELECTOR LOGIC
//
// 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
//
//***********************************************
var UNSELECTED_TEXTURES = { var UNSELECTED_TEXTURES = {
"idle-D": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-idle.png"), "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") "idle-E": Script.resolvePath("./assets/models/Avatar-Overlay-v1.fbx/Avatar-Overlay-v1.fbm/avatar-overlay-idle.png")
@ -415,7 +291,7 @@
userName: '' userName: ''
}; };
sendToQml(message); sendToQml(message);
ExtendedOverlay.some(function (overlay) { ExtendedOverlay.some(function (overlay) {
var id = overlay.key; var id = overlay.key;
var selected = ExtendedOverlay.isSelected(id); var selected = ExtendedOverlay.isSelected(id);
@ -521,11 +397,40 @@
triggerMapping.from(Controller.Standard.LTClick).peek().to(makeClickHandler(Controller.Standard.LeftHand)); 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.RT).peek().to(makePressHandler(Controller.Standard.RightHand));
triggerPressMapping.from(Controller.Standard.LT).peek().to(makePressHandler(Controller.Standard.LeftHand)); 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 sendMoneyRecipient;
var sendMoneyParticleEffectUpdateTimer; var sendMoneyParticleEffectUpdateTimer;
@ -678,18 +583,23 @@
} }
removeOverlays(); removeOverlays();
break; break;
case 'sendMoney_sendPublicly': case 'sendAsset_sendPublicly':
deleteSendMoneyParticleEffect(); if (message.assetName === "") {
sendMoneyRecipient = message.recipient; deleteSendMoneyParticleEffect();
var amount = message.amount; sendMoneyRecipient = message.recipient;
var props = SEND_MONEY_PARTICLE_PROPERTIES; var amount = message.amount;
props.parentID = MyAvatar.sessionUUID; var props = SEND_MONEY_PARTICLE_PROPERTIES;
props.position = MyAvatar.position; props.parentID = MyAvatar.sessionUUID;
props.position.y += 0.2; props.position = MyAvatar.position;
sendMoneyParticleEffect = Entities.addEntity(props, true); props.position.y += 0.2;
particleEffectTimestamp = Date.now(); if (message.effectImage) {
updateSendMoneyParticleEffect(); props.textures = message.effectImage;
sendMoneyParticleEffectUpdateTimer = Script.setInterval(updateSendMoneyParticleEffect, SEND_MONEY_PARTICLE_TIMER_UPDATE); }
sendMoneyParticleEffect = Entities.addEntity(props, true);
particleEffectTimestamp = Date.now();
updateSendMoneyParticleEffect();
sendMoneyParticleEffectUpdateTimer = Script.setInterval(updateSendMoneyParticleEffect, SEND_MONEY_PARTICLE_TIMER_UPDATE);
}
break; break;
case 'transactionHistory_goToBank': case 'transactionHistory_goToBank':
if (Account.metaverseServerURL.indexOf("staging") >= 0) { if (Account.metaverseServerURL.indexOf("staging") >= 0) {
@ -781,18 +691,19 @@
var isWired = false; var isWired = false;
var isUpdateOverlaysWired = false; var isUpdateOverlaysWired = false;
function off() { function off() {
if (isWired) { // It is not ok to disconnect these twice, hence guard. if (isWired) {
Users.usernameFromIDReply.disconnect(usernameFromIDReply); Users.usernameFromIDReply.disconnect(usernameFromIDReply);
Controller.mousePressEvent.disconnect(handleMouseEvent); Controller.mousePressEvent.disconnect(handleMouseEvent);
Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent); Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent);
triggerMapping.disable();
triggerPressMapping.disable();
isWired = false; isWired = false;
} }
if (isUpdateOverlaysWired) { if (isUpdateOverlaysWired) {
Script.update.disconnect(updateOverlays); Script.update.disconnect(updateOverlays);
isUpdateOverlaysWired = false; isUpdateOverlaysWired = false;
} }
triggerMapping.disable(); // It's ok if we disable twice.
triggerPressMapping.disable(); // see above
removeOverlays(); removeOverlays();
} }
function shutdown() { function shutdown() {

View 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);
}

File diff suppressed because it is too large Load diff

View file

@ -40,7 +40,6 @@ var HOVER_TEXTURES = {
var UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6}; var UNSELECTED_COLOR = { red: 0x1F, green: 0xC6, blue: 0xA6};
var SELECTED_COLOR = {red: 0xF3, green: 0x91, blue: 0x29}; var SELECTED_COLOR = {red: 0xF3, green: 0x91, blue: 0x29};
var HOVER_COLOR = {red: 0xD0, green: 0xD0, blue: 0xD0}; // almost white for now var HOVER_COLOR = {red: 0xD0, green: 0xD0, blue: 0xD0}; // almost white for now
var PAL_QML_SOURCE = "hifi/Pal.qml";
var conserveResources = true; var conserveResources = true;
Script.include("/~/system/libraries/controllers.js"); Script.include("/~/system/libraries/controllers.js");
@ -668,57 +667,6 @@ triggerMapping.from(Controller.Standard.RTClick).peek().to(makeClickHandler(Cont
triggerMapping.from(Controller.Standard.LTClick).peek().to(makeClickHandler(Controller.Standard.LeftHand)); 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.RT).peek().to(makePressHandler(Controller.Standard.RightHand));
triggerPressMapping.from(Controller.Standard.LT).peek().to(makePressHandler(Controller.Standard.LeftHand)); triggerPressMapping.from(Controller.Standard.LT).peek().to(makePressHandler(Controller.Standard.LeftHand));
//
// Manage the connection between the button and the window.
//
var button;
var buttonName = "PEOPLE";
var tablet = null;
function startup() {
tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
button = tablet.addButton({
text: buttonName,
icon: "icons/tablet-icons/people-i.svg",
activeIcon: "icons/tablet-icons/people-a.svg",
sortOrder: 7
});
button.clicked.connect(onTabletButtonClicked);
tablet.screenChanged.connect(onTabletScreenChanged);
Window.domainChanged.connect(clearLocalQMLDataAndClosePAL);
Window.domainConnectionRefused.connect(clearLocalQMLDataAndClosePAL);
Messages.subscribe(CHANNEL);
Messages.messageReceived.connect(receiveMessage);
Users.avatarDisconnected.connect(avatarDisconnected);
AvatarList.avatarAddedEvent.connect(avatarAdded);
AvatarList.avatarRemovedEvent.connect(avatarRemoved);
AvatarList.avatarSessionChangedEvent.connect(avatarSessionChanged);
}
startup();
var isWired = false;
var audioTimer;
var AUDIO_LEVEL_UPDATE_INTERVAL_MS = 100; // 10hz for now (change this and change the AVERAGING_RATIO too)
var AUDIO_LEVEL_CONSERVED_UPDATE_INTERVAL_MS = 300;
function off() {
if (isWired) { // It is not ok to disconnect these twice, hence guard.
Script.update.disconnect(updateOverlays);
Controller.mousePressEvent.disconnect(handleMouseEvent);
Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent);
tablet.tabletShownChanged.disconnect(tabletVisibilityChanged);
Users.usernameFromIDReply.disconnect(usernameFromIDReply);
isWired = false;
ContextOverlay.enabled = true
}
if (audioTimer) {
Script.clearInterval(audioTimer);
}
triggerMapping.disable(); // It's ok if we disable twice.
triggerPressMapping.disable(); // see above
removeOverlays();
Users.requestsDomainListData = false;
}
function tabletVisibilityChanged() { function tabletVisibilityChanged() {
if (!tablet.tabletShown) { if (!tablet.tabletShown) {
@ -728,26 +676,17 @@ function tabletVisibilityChanged() {
} }
var onPalScreen = false; var onPalScreen = false;
var PAL_QML_SOURCE = "hifi/Pal.qml";
function onTabletButtonClicked() { function onTabletButtonClicked() {
if (!tablet) {
print("Warning in onTabletButtonClicked(): 'tablet' undefined!");
return;
}
if (onPalScreen) { if (onPalScreen) {
// for toolbar-mode: go back to home screen, this will close the window. // In Toolbar Mode, `gotoHomeScreen` will close the app window.
tablet.gotoHomeScreen(); tablet.gotoHomeScreen();
ContextOverlay.enabled = true;
} else { } else {
ContextOverlay.enabled = false;
tablet.loadQMLSource(PAL_QML_SOURCE); tablet.loadQMLSource(PAL_QML_SOURCE);
tablet.tabletShownChanged.connect(tabletVisibilityChanged);
Users.requestsDomainListData = true;
populateNearbyUserList();
isWired = true;
Script.update.connect(updateOverlays);
Controller.mousePressEvent.connect(handleMouseEvent);
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
Users.usernameFromIDReply.connect(usernameFromIDReply);
triggerMapping.enable();
triggerPressMapping.enable();
audioTimer = createAudioInterval(conserveResources ? AUDIO_LEVEL_CONSERVED_UPDATE_INTERVAL_MS : AUDIO_LEVEL_UPDATE_INTERVAL_MS);
} }
} }
var hasEventBridge = false; var hasEventBridge = false;
@ -771,9 +710,25 @@ function onTabletScreenChanged(type, url) {
// for toolbar mode: change button to active when window is first openend, false otherwise. // for toolbar mode: change button to active when window is first openend, false otherwise.
button.editProperties({isActive: onPalScreen}); button.editProperties({isActive: onPalScreen});
// disable sphere overlays when not on pal screen. if (onPalScreen) {
if (!onPalScreen) { isWired = true;
ContextOverlay.enabled = false;
Users.requestsDomainListData = true;
populateNearbyUserList();
audioTimer = createAudioInterval(conserveResources ? AUDIO_LEVEL_CONSERVED_UPDATE_INTERVAL_MS : AUDIO_LEVEL_UPDATE_INTERVAL_MS);
tablet.tabletShownChanged.connect(tabletVisibilityChanged);
Script.update.connect(updateOverlays);
Controller.mousePressEvent.connect(handleMouseEvent);
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
Users.usernameFromIDReply.connect(usernameFromIDReply);
triggerMapping.enable();
triggerPressMapping.enable();
} else {
off(); off();
ContextOverlay.enabled = true;
} }
} }
@ -884,6 +839,58 @@ function avatarSessionChanged(avatarID) {
sendToQml({ method: 'palIsStale', params: [avatarID, 'avatarSessionChanged'] }); sendToQml({ method: 'palIsStale', params: [avatarID, 'avatarSessionChanged'] });
} }
var button;
var buttonName = "PEOPLE";
var tablet = null;
function startup() {
tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
button = tablet.addButton({
text: buttonName,
icon: "icons/tablet-icons/people-i.svg",
activeIcon: "icons/tablet-icons/people-a.svg",
sortOrder: 7
});
button.clicked.connect(onTabletButtonClicked);
tablet.screenChanged.connect(onTabletScreenChanged);
Window.domainChanged.connect(clearLocalQMLDataAndClosePAL);
Window.domainConnectionRefused.connect(clearLocalQMLDataAndClosePAL);
Messages.subscribe(CHANNEL);
Messages.messageReceived.connect(receiveMessage);
Users.avatarDisconnected.connect(avatarDisconnected);
AvatarList.avatarAddedEvent.connect(avatarAdded);
AvatarList.avatarRemovedEvent.connect(avatarRemoved);
AvatarList.avatarSessionChangedEvent.connect(avatarSessionChanged);
}
startup();
var isWired = false;
var audioTimer;
var AUDIO_LEVEL_UPDATE_INTERVAL_MS = 100; // 10hz for now (change this and change the AVERAGING_RATIO too)
var AUDIO_LEVEL_CONSERVED_UPDATE_INTERVAL_MS = 300;
function off() {
if (isWired) {
Script.update.disconnect(updateOverlays);
Controller.mousePressEvent.disconnect(handleMouseEvent);
Controller.mouseMoveEvent.disconnect(handleMouseMoveEvent);
tablet.tabletShownChanged.disconnect(tabletVisibilityChanged);
Users.usernameFromIDReply.disconnect(usernameFromIDReply);
ContextOverlay.enabled = true
triggerMapping.disable();
triggerPressMapping.disable();
Users.requestsDomainListData = false;
isWired = false;
if (audioTimer) {
Script.clearInterval(audioTimer);
}
}
removeOverlays();
}
function shutdown() { function shutdown() {
if (onPalScreen) { if (onPalScreen) {
tablet.gotoHomeScreen(); tablet.gotoHomeScreen();
@ -901,10 +908,6 @@ function shutdown() {
AvatarList.avatarSessionChangedEvent.disconnect(avatarSessionChanged); AvatarList.avatarSessionChangedEvent.disconnect(avatarSessionChanged);
off(); off();
} }
//
// Cleanup.
//
Script.scriptEnding.connect(shutdown); Script.scriptEnding.connect(shutdown);
}()); // END LOCAL_SCOPE }()); // END LOCAL_SCOPE