diff --git a/functions/index.js b/functions/index.js index f523f2b23..302be6f06 100644 --- a/functions/index.js +++ b/functions/index.js @@ -395,4 +395,32 @@ exports.removeTag = functions.https.onCall((request,response) => { console.error(`error deleting tag for ${request.uid} - ${e}`); return {resultCode:-999}; } +}) + +exports.updateResultTags = functions.https.onCall((request,response) => { + try{ + let validTags = true; + request.tags.forEach(tag => { + if(!/^[0-9a-zA-Z]+$/.test(tag)) validTags = false; + }) + if(validTags){ + return admin.firestore().collection(`users/${request.uid}/results`).doc(request.resultid).update({ + tags: request.tags + }).then(e => { + console.log(`user ${request.uid} updated tags for result ${request.resultid}`); + return { + resultCode:1 + }; + }).catch(e => { + console.error(`error while updating tags for result by user ${request.uid}: ${e.message}`); + return {resultCode:-999}; + }) + }else{ + console.error(`invalid tags for user ${request.uid}: ${request.tags}`); + return {resultCode:-1}; + } + }catch(e){ + console.error(`error updating tags by ${request.uid} - ${e}`); + return {resultCode:-999}; + } }) \ No newline at end of file diff --git a/functions/package-lock.json b/functions/package-lock.json index 5a2b860f6..b26868b3a 100644 --- a/functions/package-lock.json +++ b/functions/package-lock.json @@ -2858,7 +2858,7 @@ } }, "websocket-extensions": { - "version": "0.1.4", + "version": ">=0.1.4", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" }, diff --git a/package-lock.json b/package-lock.json index 5be5b1b97..ab1d6fbf2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4232,7 +4232,7 @@ } }, "websocket-extensions": { - "version": "0.1.3", + "version": ">=0.1.4", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==" }, diff --git a/public/css/balloon.css b/public/css/balloon.css new file mode 100644 index 000000000..466035e20 --- /dev/null +++ b/public/css/balloon.css @@ -0,0 +1,204 @@ +:root { + --balloon-border-radius: 2px; + --balloon-color: rgba(16, 16, 16, 0.95); + --balloon-text-color: #fff; + --balloon-font-size: 1rem; + --balloon-move: 4px; } + +button[aria-label][data-balloon-pos] { + overflow: visible; } + +[aria-label][data-balloon-pos] { + position: relative; + cursor: pointer; } + [aria-label][data-balloon-pos]:after { + opacity: 0; + pointer-events: none; + transition: all 0.18s ease-out 0s; + text-indent: 0; + /* font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; */ + font-weight: normal; + font-style: normal; + text-shadow: none; + font-size: var(--balloon-font-size); + background: var(--balloon-color); + border-radius: 2px; + color: var(--balloon-text-color); + border-radius: var(--balloon-border-radius); + content: attr(aria-label); + padding: .5em 1em; + position: absolute; + white-space: nowrap; + z-index: 10; } + [aria-label][data-balloon-pos]:before { + width: 0; + height: 0; + border: 5px solid transparent; + border-top-color: var(--balloon-color); + opacity: 0; + pointer-events: none; + transition: all 0.18s ease-out 0s; + content: ""; + position: absolute; + z-index: 10; } + [aria-label][data-balloon-pos]:hover:before, [aria-label][data-balloon-pos]:hover:after, [aria-label][data-balloon-pos][data-balloon-visible]:before, [aria-label][data-balloon-pos][data-balloon-visible]:after, [aria-label][data-balloon-pos]:not([data-balloon-nofocus]):focus:before, [aria-label][data-balloon-pos]:not([data-balloon-nofocus]):focus:after { + opacity: 1; + pointer-events: none; } + [aria-label][data-balloon-pos].font-awesome:after { + font-family: FontAwesome, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } + [aria-label][data-balloon-pos][data-balloon-break]:after { + white-space: pre; } + [aria-label][data-balloon-pos][data-balloon-break][data-balloon-length]:after { + white-space: pre-line; + word-break: break-word; } + [aria-label][data-balloon-pos][data-balloon-blunt]:before, [aria-label][data-balloon-pos][data-balloon-blunt]:after { + transition: none; } + [aria-label][data-balloon-pos][data-balloon-pos="up"]:after { + bottom: 100%; + left: 50%; + margin-bottom: 10px; + transform: translate(-50%, var(--balloon-move)); + transform-origin: top; } + [aria-label][data-balloon-pos][data-balloon-pos="up"]:before { + bottom: 100%; + left: 50%; + transform: translate(-50%, var(--balloon-move)); + transform-origin: top; } + [aria-label][data-balloon-pos][data-balloon-pos="up"]:hover:after, [aria-label][data-balloon-pos][data-balloon-pos="up"][data-balloon-visible]:after { + transform: translate(-50%, 0); } + [aria-label][data-balloon-pos][data-balloon-pos="up"]:hover:before, [aria-label][data-balloon-pos][data-balloon-pos="up"][data-balloon-visible]:before { + transform: translate(-50%, 0); } + [aria-label][data-balloon-pos][data-balloon-pos="up-left"]:after { + bottom: 100%; + left: 0; + margin-bottom: 10px; + transform: translate(0, var(--balloon-move)); + transform-origin: top; } + [aria-label][data-balloon-pos][data-balloon-pos="up-left"]:before { + bottom: 100%; + left: 5px; + transform: translate(0, var(--balloon-move)); + transform-origin: top; } + [aria-label][data-balloon-pos][data-balloon-pos="up-left"]:hover:after, [aria-label][data-balloon-pos][data-balloon-pos="up-left"][data-balloon-visible]:after { + transform: translate(0, 0); } + [aria-label][data-balloon-pos][data-balloon-pos="up-left"]:hover:before, [aria-label][data-balloon-pos][data-balloon-pos="up-left"][data-balloon-visible]:before { + transform: translate(0, 0); } + [aria-label][data-balloon-pos][data-balloon-pos="up-right"]:after { + bottom: 100%; + right: 0; + margin-bottom: 10px; + transform: translate(0, var(--balloon-move)); + transform-origin: top; } + [aria-label][data-balloon-pos][data-balloon-pos="up-right"]:before { + bottom: 100%; + right: 5px; + transform: translate(0, var(--balloon-move)); + transform-origin: top; } + [aria-label][data-balloon-pos][data-balloon-pos="up-right"]:hover:after, [aria-label][data-balloon-pos][data-balloon-pos="up-right"][data-balloon-visible]:after { + transform: translate(0, 0); } + [aria-label][data-balloon-pos][data-balloon-pos="up-right"]:hover:before, [aria-label][data-balloon-pos][data-balloon-pos="up-right"][data-balloon-visible]:before { + transform: translate(0, 0); } + [aria-label][data-balloon-pos][data-balloon-pos="down"]:after { + left: 50%; + margin-top: 10px; + top: 100%; + transform: translate(-50%, calc(var(--balloon-move) * -1)); } + [aria-label][data-balloon-pos][data-balloon-pos="down"]:before { + width: 0; + height: 0; + border: 5px solid transparent; + border-bottom-color: var(--balloon-color); + left: 50%; + top: 100%; + transform: translate(-50%, calc(var(--balloon-move) * -1)); } + [aria-label][data-balloon-pos][data-balloon-pos="down"]:hover:after, [aria-label][data-balloon-pos][data-balloon-pos="down"][data-balloon-visible]:after { + transform: translate(-50%, 0); } + [aria-label][data-balloon-pos][data-balloon-pos="down"]:hover:before, [aria-label][data-balloon-pos][data-balloon-pos="down"][data-balloon-visible]:before { + transform: translate(-50%, 0); } + [aria-label][data-balloon-pos][data-balloon-pos="down-left"]:after { + left: 0; + margin-top: 10px; + top: 100%; + transform: translate(0, calc(var(--balloon-move) * -1)); } + [aria-label][data-balloon-pos][data-balloon-pos="down-left"]:before { + width: 0; + height: 0; + border: 5px solid transparent; + border-bottom-color: var(--balloon-color); + left: 5px; + top: 100%; + transform: translate(0, calc(var(--balloon-move) * -1)); } + [aria-label][data-balloon-pos][data-balloon-pos="down-left"]:hover:after, [aria-label][data-balloon-pos][data-balloon-pos="down-left"][data-balloon-visible]:after { + transform: translate(0, 0); } + [aria-label][data-balloon-pos][data-balloon-pos="down-left"]:hover:before, [aria-label][data-balloon-pos][data-balloon-pos="down-left"][data-balloon-visible]:before { + transform: translate(0, 0); } + [aria-label][data-balloon-pos][data-balloon-pos="down-right"]:after { + right: 0; + margin-top: 10px; + top: 100%; + transform: translate(0, calc(var(--balloon-move) * -1)); } + [aria-label][data-balloon-pos][data-balloon-pos="down-right"]:before { + width: 0; + height: 0; + border: 5px solid transparent; + border-bottom-color: var(--balloon-color); + right: 5px; + top: 100%; + transform: translate(0, calc(var(--balloon-move) * -1)); } + [aria-label][data-balloon-pos][data-balloon-pos="down-right"]:hover:after, [aria-label][data-balloon-pos][data-balloon-pos="down-right"][data-balloon-visible]:after { + transform: translate(0, 0); } + [aria-label][data-balloon-pos][data-balloon-pos="down-right"]:hover:before, [aria-label][data-balloon-pos][data-balloon-pos="down-right"][data-balloon-visible]:before { + transform: translate(0, 0); } + [aria-label][data-balloon-pos][data-balloon-pos="left"]:after { + margin-right: 10px; + right: 100%; + top: 50%; + transform: translate(var(--balloon-move), -50%); } + [aria-label][data-balloon-pos][data-balloon-pos="left"]:before { + width: 0; + height: 0; + border: 5px solid transparent; + border-left-color: var(--balloon-color); + right: 100%; + top: 50%; + transform: translate(var(--balloon-move), -50%); } + [aria-label][data-balloon-pos][data-balloon-pos="left"]:hover:after, [aria-label][data-balloon-pos][data-balloon-pos="left"][data-balloon-visible]:after { + transform: translate(0, -50%); } + [aria-label][data-balloon-pos][data-balloon-pos="left"]:hover:before, [aria-label][data-balloon-pos][data-balloon-pos="left"][data-balloon-visible]:before { + transform: translate(0, -50%); } + [aria-label][data-balloon-pos][data-balloon-pos="right"]:after { + left: 100%; + margin-left: 10px; + top: 50%; + transform: translate(calc(var(--balloon-move) * -1), -50%); } + [aria-label][data-balloon-pos][data-balloon-pos="right"]:before { + width: 0; + height: 0; + border: 5px solid transparent; + border-right-color: var(--balloon-color); + left: 100%; + top: 50%; + transform: translate(calc(var(--balloon-move) * -1), -50%); } + [aria-label][data-balloon-pos][data-balloon-pos="right"]:hover:after, [aria-label][data-balloon-pos][data-balloon-pos="right"][data-balloon-visible]:after { + transform: translate(0, -50%); } + [aria-label][data-balloon-pos][data-balloon-pos="right"]:hover:before, [aria-label][data-balloon-pos][data-balloon-pos="right"][data-balloon-visible]:before { + transform: translate(0, -50%); } + [aria-label][data-balloon-pos][data-balloon-length="small"]:after { + white-space: normal; + width: 80px; } + [aria-label][data-balloon-pos][data-balloon-length="medium"]:after { + white-space: normal; + width: 150px; } + [aria-label][data-balloon-pos][data-balloon-length="large"]:after { + white-space: normal; + width: 260px; } + [aria-label][data-balloon-pos][data-balloon-length="xlarge"]:after { + white-space: normal; + width: 380px; } + @media screen and (max-width: 768px) { + [aria-label][data-balloon-pos][data-balloon-length="xlarge"]:after { + white-space: normal; + width: 90vw; } } + [aria-label][data-balloon-pos][data-balloon-length="fit"]:after { + white-space: normal; + width: 100%; } diff --git a/public/css/style.scss b/public/css/style.scss index f0a4f714f..1f59e6fcb 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -148,6 +148,60 @@ a:hover { } +#resultEditTagsPanelWrapper{ + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.75); + position: fixed; + left: 0; + top: 0; + z-index: 1000; + display: grid; + justify-content: center; + align-items: center; + padding: 5rem 0; + #resultEditTagsPanel{ + background: var(--bg-color); + border-radius: var(--roundness); + padding: 2rem; + display: grid; + gap: 1rem; + overflow-y: scroll; + width: 500px; + .buttons{ + display: grid; + gap: 1rem; + grid-template-columns: 1fr 1fr 1fr; + } + .button{ + display: block; + color: var(--text-color); + cursor: pointer; + transition: .25s; + padding: .2rem .5rem; + border-radius: var(--roundness); + + background: rgba(0,0,0,.1); + text-align: center; + -webkit-user-select: none; + display: grid; + align-content: center; + height: min-content; + height: -moz-min-content; + &.active{ + background: var(--main-color); + color: var(--bg-color); + } + &:hover,&:focus{ + color: var(--bg-color); + background: var(--main-color); + outline: none; + } + } + } +} + + #versionHistoryWrapper{ width: 100%; height: 100%; @@ -274,6 +328,9 @@ a:hover { font-size: 0.75rem; line-height: 0.75rem; color: var(--sub-color); + .fas{ + margin-right: .5rem; + } &:last-child{ border-radius: 0 0 var(--roundness) var(--roundness); } @@ -575,6 +632,7 @@ a:hover { margin-left: -0.15rem; color: var(--main-color); transition: .25s; + cursor: pointer; } @@ -1489,6 +1547,17 @@ key { tbody tr:nth-child(odd) td{ background: rgba(0, 0, 0, 0.1); } + td.infoIcons span{ + margin: 0 .1rem; + } + } + #resultEditTags{ + transition: .25s; + } + #resultEditTags:hover{ + cursor: pointer; + color: var(--main-color); + opacity: 1 !important; } } diff --git a/public/index.html b/public/index.html index e70cbdc66..2cea40e85 100644 --- a/public/index.html +++ b/public/index.html @@ -6,14 +6,15 @@ Monkey Type - + + - + @@ -40,6 +41,14 @@
+