0

Merge remote-tracking branch 'origin/develop' into webv2

This commit is contained in:
Gabe Kangas 2022-11-29 16:37:29 -08:00
commit 0ecaf11a25
No known key found for this signature in database
GPG Key ID: 4345B2060657F330
12 changed files with 627 additions and 468 deletions

View File

@ -18,7 +18,12 @@ func handleUndoInboxRequest(c context.Context, activity vocab.ActivityStreamsUnd
return err return err
} }
} else { } else {
log.Traceln("Undo", iter.GetType().GetTypeName(), "ignored") t := iter.GetType()
if t != nil {
log.Traceln("Undo", t.GetTypeName(), "ignored")
} else {
log.Traceln("Undo (no type) ignored")
}
return nil return nil
} }
} }

View File

@ -5,11 +5,11 @@
"requires": true, "requires": true,
"dependencies": { "dependencies": {
"@babel/runtime": { "@babel/runtime": {
"version": "7.19.4", "version": "7.20.6",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz",
"integrity": "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==", "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==",
"requires": { "requires": {
"regenerator-runtime": "^0.13.4" "regenerator-runtime": "^0.13.11"
} }
}, },
"@fortawesome/fontawesome-common-types": { "@fortawesome/fontawesome-common-types": {
@ -192,9 +192,9 @@
} }
}, },
"@xmldom/xmldom": { "@xmldom/xmldom": {
"version": "0.7.6", "version": "0.7.9",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.6.tgz", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.9.tgz",
"integrity": "sha512-HHXP9hskkFQHy8QxxUXkS7946FFIhYVfGqsk0WLwllmexN9x/+R4UBLvurHEuyXRfVEObVR8APuQehykLviwSQ==" "integrity": "sha512-yceMpm/xd4W2a85iqZyO09gTnHvXF6pyiWjD2jcOJs7hRoZtNNOO1eJlhHj1ixA+xip2hOyGn+LgcvLCMo5zXA=="
}, },
"acorn": { "acorn": {
"version": "7.4.1", "version": "7.4.1",
@ -242,9 +242,9 @@
} }
}, },
"anymatch": { "anymatch": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dev": true, "dev": true,
"requires": { "requires": {
"normalize-path": "^3.0.0", "normalize-path": "^3.0.0",
@ -350,9 +350,9 @@
} }
}, },
"caniuse-lite": { "caniuse-lite": {
"version": "1.0.30001423", "version": "1.0.30001434",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001423.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz",
"integrity": "sha512-09iwWGOlifvE1XuHokFMP7eR38a0JnajoyL3/i87c8ZjRWRrdKo1fqjNfugfBD0UDBIOz0U+jtNhJ0EPm1VleQ==" "integrity": "sha512-aOBHrLmTQw//WFa2rcF1If9fa3ypkC1wzqqiKHgfdrXTWcU8C4gKVZT77eQAPWN1APys3+uQ0Df07rKauXGEYA=="
}, },
"chalk": { "chalk": {
"version": "4.1.2", "version": "4.1.2",
@ -527,25 +527,25 @@
} }
}, },
"cssnano-preset-default": { "cssnano-preset-default": {
"version": "5.2.12", "version": "5.2.13",
"resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.12.tgz", "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.13.tgz",
"integrity": "sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew==", "integrity": "sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"css-declaration-sorter": "^6.3.0", "css-declaration-sorter": "^6.3.1",
"cssnano-utils": "^3.1.0", "cssnano-utils": "^3.1.0",
"postcss-calc": "^8.2.3", "postcss-calc": "^8.2.3",
"postcss-colormin": "^5.3.0", "postcss-colormin": "^5.3.0",
"postcss-convert-values": "^5.1.2", "postcss-convert-values": "^5.1.3",
"postcss-discard-comments": "^5.1.2", "postcss-discard-comments": "^5.1.2",
"postcss-discard-duplicates": "^5.1.0", "postcss-discard-duplicates": "^5.1.0",
"postcss-discard-empty": "^5.1.1", "postcss-discard-empty": "^5.1.1",
"postcss-discard-overridden": "^5.1.0", "postcss-discard-overridden": "^5.1.0",
"postcss-merge-longhand": "^5.1.6", "postcss-merge-longhand": "^5.1.7",
"postcss-merge-rules": "^5.1.2", "postcss-merge-rules": "^5.1.3",
"postcss-minify-font-values": "^5.1.0", "postcss-minify-font-values": "^5.1.0",
"postcss-minify-gradients": "^5.1.1", "postcss-minify-gradients": "^5.1.1",
"postcss-minify-params": "^5.1.3", "postcss-minify-params": "^5.1.4",
"postcss-minify-selectors": "^5.2.1", "postcss-minify-selectors": "^5.2.1",
"postcss-normalize-charset": "^5.1.0", "postcss-normalize-charset": "^5.1.0",
"postcss-normalize-display-values": "^5.1.0", "postcss-normalize-display-values": "^5.1.0",
@ -553,11 +553,11 @@
"postcss-normalize-repeat-style": "^5.1.1", "postcss-normalize-repeat-style": "^5.1.1",
"postcss-normalize-string": "^5.1.0", "postcss-normalize-string": "^5.1.0",
"postcss-normalize-timing-functions": "^5.1.0", "postcss-normalize-timing-functions": "^5.1.0",
"postcss-normalize-unicode": "^5.1.0", "postcss-normalize-unicode": "^5.1.1",
"postcss-normalize-url": "^5.1.0", "postcss-normalize-url": "^5.1.0",
"postcss-normalize-whitespace": "^5.1.1", "postcss-normalize-whitespace": "^5.1.1",
"postcss-ordered-values": "^5.1.3", "postcss-ordered-values": "^5.1.3",
"postcss-reduce-initial": "^5.1.0", "postcss-reduce-initial": "^5.1.1",
"postcss-reduce-transforms": "^5.1.0", "postcss-reduce-transforms": "^5.1.0",
"postcss-svgo": "^5.1.0", "postcss-svgo": "^5.1.0",
"postcss-unique-selectors": "^5.1.1" "postcss-unique-selectors": "^5.1.1"
@ -856,9 +856,9 @@
} }
}, },
"ignore": { "ignore": {
"version": "5.2.0", "version": "5.2.1",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz",
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==",
"dev": true "dev": true
}, },
"individual": { "individual": {
@ -1263,12 +1263,12 @@
} }
}, },
"postcss-convert-values": { "postcss-convert-values": {
"version": "5.1.2", "version": "5.1.3",
"resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz", "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz",
"integrity": "sha512-c6Hzc4GAv95B7suy4udszX9Zy4ETyMCgFPUDtWjdFTKH1SE9eFY/jEpHSwTH1QPuwxHpWslhckUQWbNRM4ho5g==", "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==",
"dev": true, "dev": true,
"requires": { "requires": {
"browserslist": "^4.20.3", "browserslist": "^4.21.4",
"postcss-value-parser": "^4.2.0" "postcss-value-parser": "^4.2.0"
} }
}, },
@ -1396,22 +1396,22 @@
} }
}, },
"postcss-merge-longhand": { "postcss-merge-longhand": {
"version": "5.1.6", "version": "5.1.7",
"resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.6.tgz", "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz",
"integrity": "sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw==", "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"postcss-value-parser": "^4.2.0", "postcss-value-parser": "^4.2.0",
"stylehacks": "^5.1.0" "stylehacks": "^5.1.1"
} }
}, },
"postcss-merge-rules": { "postcss-merge-rules": {
"version": "5.1.2", "version": "5.1.3",
"resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.2.tgz", "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.3.tgz",
"integrity": "sha512-zKMUlnw+zYCWoPN6yhPjtcEdlJaMUZ0WyVcxTAmw3lkkN/NDMRkOkiuctQEoWAOvH7twaxUUdvBWl0d4+hifRQ==", "integrity": "sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA==",
"dev": true, "dev": true,
"requires": { "requires": {
"browserslist": "^4.16.6", "browserslist": "^4.21.4",
"caniuse-api": "^3.0.0", "caniuse-api": "^3.0.0",
"cssnano-utils": "^3.1.0", "cssnano-utils": "^3.1.0",
"postcss-selector-parser": "^6.0.5" "postcss-selector-parser": "^6.0.5"
@ -1438,12 +1438,12 @@
} }
}, },
"postcss-minify-params": { "postcss-minify-params": {
"version": "5.1.3", "version": "5.1.4",
"resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.3.tgz", "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz",
"integrity": "sha512-bkzpWcjykkqIujNL+EVEPOlLYi/eZ050oImVtHU7b4lFS82jPnsCb44gvC6pxaNt38Els3jWYDHTjHKf0koTgg==", "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==",
"dev": true, "dev": true,
"requires": { "requires": {
"browserslist": "^4.16.6", "browserslist": "^4.21.4",
"cssnano-utils": "^3.1.0", "cssnano-utils": "^3.1.0",
"postcss-value-parser": "^4.2.0" "postcss-value-parser": "^4.2.0"
} }
@ -1529,12 +1529,12 @@
} }
}, },
"postcss-normalize-unicode": { "postcss-normalize-unicode": {
"version": "5.1.0", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz", "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz",
"integrity": "sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ==", "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==",
"dev": true, "dev": true,
"requires": { "requires": {
"browserslist": "^4.16.6", "browserslist": "^4.21.4",
"postcss-value-parser": "^4.2.0" "postcss-value-parser": "^4.2.0"
} }
}, },
@ -1568,12 +1568,12 @@
} }
}, },
"postcss-reduce-initial": { "postcss-reduce-initial": {
"version": "5.1.0", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz", "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.1.tgz",
"integrity": "sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw==", "integrity": "sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w==",
"dev": true, "dev": true,
"requires": { "requires": {
"browserslist": "^4.16.6", "browserslist": "^4.21.4",
"caniuse-api": "^3.0.0" "caniuse-api": "^3.0.0"
} }
}, },
@ -1605,9 +1605,9 @@
} }
}, },
"postcss-selector-parser": { "postcss-selector-parser": {
"version": "6.0.10", "version": "6.0.11",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz",
"integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==",
"requires": { "requires": {
"cssesc": "^3.0.0", "cssesc": "^3.0.0",
"util-deprecate": "^1.0.2" "util-deprecate": "^1.0.2"
@ -1746,9 +1746,9 @@
} }
}, },
"regenerator-runtime": { "regenerator-runtime": {
"version": "0.13.10", "version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
"integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==" "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
}, },
"require-directory": { "require-directory": {
"version": "2.1.1", "version": "2.1.1",
@ -1862,12 +1862,12 @@
} }
}, },
"stylehacks": { "stylehacks": {
"version": "5.1.0", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz",
"integrity": "sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q==", "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==",
"dev": true, "dev": true,
"requires": { "requires": {
"browserslist": "^4.16.6", "browserslist": "^4.21.4",
"postcss-selector-parser": "^6.0.4" "postcss-selector-parser": "^6.0.4"
} }
}, },
@ -2050,9 +2050,9 @@
} }
}, },
"tslib": { "tslib": {
"version": "2.4.0", "version": "2.4.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA=="
}, },
"twemoji": { "twemoji": {
"version": "12.1.6", "version": "12.1.6",
@ -2194,9 +2194,9 @@
"dev": true "dev": true
}, },
"yargs": { "yargs": {
"version": "17.6.0", "version": "17.6.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
"integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==", "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
"dev": true, "dev": true,
"requires": { "requires": {
"cliui": "^8.0.1", "cliui": "^8.0.1",
@ -2205,7 +2205,7 @@
"require-directory": "^2.1.1", "require-directory": "^2.1.1",
"string-width": "^4.2.3", "string-width": "^4.2.3",
"y18n": "^5.0.5", "y18n": "^5.0.5",
"yargs-parser": "^21.0.0" "yargs-parser": "^21.1.1"
} }
}, },
"yargs-parser": { "yargs-parser": {

View File

@ -3,7 +3,6 @@ package chat
import ( import (
"context" "context"
"database/sql" "database/sql"
"fmt"
"strings" "strings"
"time" "time"
@ -209,20 +208,14 @@ type rowData struct {
userType *string userType *string
} }
func getChat(query string) []interface{} { func getChat(rows *sql.Rows) ([]interface{}, error) {
history := make([]interface{}, 0) history := make([]interface{}, 0)
rows, err := _datastore.DB.Query(query)
if err != nil || rows.Err() != nil {
log.Errorln("error fetching chat history", err)
return history
}
defer rows.Close()
for rows.Next() { for rows.Next() {
row := rowData{} row := rowData{}
// Convert a database row into a chat event // Convert a database row into a chat event
if err = rows.Scan( if err := rows.Scan(
&row.id, &row.id,
&row.userID, &row.userID,
&row.body, &row.body,
@ -243,9 +236,7 @@ func getChat(query string) []interface{} {
&row.userScopes, &row.userScopes,
&row.userType, &row.userType,
); err != nil { ); err != nil {
log.Errorln(err) return nil, err
log.Errorln("There is a problem converting query to chat objects. Please report this:", query)
break
} }
var message interface{} var message interface{}
@ -268,7 +259,7 @@ func getChat(query string) []interface{} {
history = append(history, message) history = append(history, message)
} }
return history return history, nil
} }
var _historyCache *[]interface{} var _historyCache *[]interface{}
@ -279,20 +270,87 @@ func GetChatModerationHistory() []interface{} {
return *_historyCache return *_historyCache
} }
tx, err := _datastore.DB.Begin()
if err != nil {
log.Errorln("error fetching chat moderation history", err)
return nil
}
defer tx.Rollback() // nolint
// Get all messages regardless of visibility // Get all messages regardless of visibility
query := "SELECT messages.id, user_id, body, title, subtitle, image, link, eventType, hidden_at, timestamp, display_name, display_color, created_at, disabled_at, previous_names, namechanged_at, authenticated_at, scopes, type FROM messages INNER JOIN users ON messages.user_id = users.id ORDER BY timestamp DESC" query := "SELECT messages.id, user_id, body, title, subtitle, image, link, eventType, hidden_at, timestamp, display_name, display_color, created_at, disabled_at, previous_names, namechanged_at, authenticated_at, scopes, type FROM messages INNER JOIN users ON messages.user_id = users.id ORDER BY timestamp DESC"
result := getChat(query) stmt, err := tx.Prepare(query)
if err != nil {
log.Errorln("error fetching chat moderation history", err)
return nil
}
rows, err := stmt.Query()
if err != nil {
log.Errorln("error fetching chat moderation history", err)
return nil
}
defer stmt.Close()
defer rows.Close()
result, err := getChat(rows)
if err != nil {
log.Errorln(err)
log.Errorln("There is a problem enumerating chat message rows. Please report this:", query)
return nil
}
_historyCache = &result _historyCache = &result
if err = tx.Commit(); err != nil {
log.Errorln("error fetching chat moderation history", err)
return nil
}
return result return result
} }
// GetChatHistory will return all the chat messages suitable for returning as user-facing chat history. // GetChatHistory will return all the chat messages suitable for returning as user-facing chat history.
func GetChatHistory() []interface{} { func GetChatHistory() []interface{} {
tx, err := _datastore.DB.Begin()
if err != nil {
log.Errorln("error fetching chat history", err)
return nil
}
defer tx.Rollback() // nolint
// Get all visible messages // Get all visible messages
query := fmt.Sprintf("SELECT messages.id, messages.user_id, messages.body, messages.title, messages.subtitle, messages.image, messages.link, messages.eventType, messages.hidden_at, messages.timestamp, users.display_name, users.display_color, users.created_at, users.disabled_at, users.previous_names, users.namechanged_at, users.authenticated_at, users.scopes, users.type FROM users JOIN messages ON users.id = messages.user_id WHERE hidden_at IS NULL AND disabled_at IS NULL ORDER BY timestamp DESC LIMIT %d", maxBacklogNumber) query := "SELECT messages.id, messages.user_id, messages.body, messages.title, messages.subtitle, messages.image, messages.link, messages.eventType, messages.hidden_at, messages.timestamp, users.display_name, users.display_color, users.created_at, users.disabled_at, users.previous_names, users.namechanged_at, users.authenticated_at, users.scopes, users.type FROM users JOIN messages ON users.id = messages.user_id WHERE hidden_at IS NULL AND disabled_at IS NULL ORDER BY timestamp DESC LIMIT ?"
m := getChat(query)
stmt, err := tx.Prepare(query)
if err != nil {
log.Errorln("error fetching chat history", err)
return nil
}
rows, err := stmt.Query(maxBacklogNumber)
if err != nil {
log.Errorln("error fetching chat history", err)
return nil
}
defer stmt.Close()
defer rows.Close()
m, err := getChat(rows)
if err != nil {
log.Errorln(err)
log.Errorln("There is a problem enumerating chat message rows. Please report this:", query)
return nil
}
if err = tx.Commit(); err != nil {
log.Errorln("error fetching chat history", err)
return nil
}
// Invert order of messages // Invert order of messages
for i, j := 0, len(m)-1; i < j; i, j = i+1, j-1 { for i, j := 0, len(m)-1; i < j; i, j = i+1, j-1 {
@ -332,10 +390,39 @@ func SetMessageVisibilityForUserID(userID string, visible bool) error {
_historyCache = nil _historyCache = nil
}() }()
tx, err := _datastore.DB.Begin()
if err != nil {
log.Errorln("error while setting message visibility", err)
return nil
}
defer tx.Rollback() // nolint
query := "SELECT messages.id, user_id, body, title, subtitle, image, link, eventType, hidden_at, timestamp, display_name, display_color, created_at, disabled_at, previous_names, namechanged_at, authenticated_at, scopes, type FROM messages INNER JOIN users ON messages.user_id = users.id WHERE user_id IS ?"
stmt, err := tx.Prepare(query)
if err != nil {
log.Errorln("error while setting message visibility", err)
return nil
}
rows, err := stmt.Query(userID)
if err != nil {
log.Errorln("error while setting message visibility", err)
return nil
}
defer stmt.Close()
defer rows.Close()
// Get a list of IDs to send to the connected clients to hide // Get a list of IDs to send to the connected clients to hide
ids := make([]string, 0) ids := make([]string, 0)
query := fmt.Sprintf("SELECT messages.id, user_id, body, title, subtitle, image, link, eventType, hidden_at, timestamp, display_name, display_color, created_at, disabled_at, previous_names, namechanged_at, authenticated_at, scopes, type FROM messages INNER JOIN users ON messages.user_id = users.id WHERE user_id IS '%s'", userID)
messages := getChat(query) messages, err := getChat(rows)
if err != nil {
log.Errorln(err)
log.Errorln("There is a problem enumerating chat message rows. Please report this:", query)
return nil
}
if len(messages) == 0 { if len(messages) == 0 {
return nil return nil
@ -345,6 +432,11 @@ func SetMessageVisibilityForUserID(userID string, visible bool) error {
ids = append(ids, message.(events.UserMessageEvent).ID) ids = append(ids, message.(events.UserMessageEvent).ID)
} }
if err = tx.Commit(); err != nil {
log.Errorln("error while setting message visibility ", err)
return nil
}
// Tell the clients to hide/show these messages. // Tell the clients to hide/show these messages.
return SetMessagesVisibility(ids, visible) return SetMessagesVisibility(ids, visible)
} }

File diff suppressed because one or more lines are too long

View File

@ -3,11 +3,17 @@ Description=Owncast Service
[Service] [Service]
Type=simple Type=simple
WorkingDirectory=[path_to_owncast_root_directory] WorkingDirectory=[path to owncast directory]
ExecStart=[path_to_owncast_executable] ReadWritePaths=[path to owncast directory]
Restart=on-failure ExecStart=[path to owncast directory]/owncast
Restart=always
RestartSec=5 RestartSec=5
User=[user to run owncast as]
Group=[group to run owncast as]
NoNewPrivileges=true
SecureBits=noroot
ProtectSystem=strict
ProtectHome=read-only
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

18
go.mod
View File

@ -4,7 +4,7 @@ go 1.17
require ( require (
github.com/amalfra/etag v1.0.0 github.com/amalfra/etag v1.0.0
github.com/aws/aws-sdk-go v1.44.124 github.com/aws/aws-sdk-go v1.44.145
github.com/go-fed/activity v1.0.1-0.20210803212804-d866ba75dd0f github.com/go-fed/activity v1.0.1-0.20210803212804-d866ba75dd0f
github.com/go-fed/httpsig v1.1.0 github.com/go-fed/httpsig v1.1.0
github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
@ -20,9 +20,9 @@ require (
github.com/schollz/sqlite3dump v1.3.1 github.com/schollz/sqlite3dump v1.3.1
github.com/sirupsen/logrus v1.9.0 github.com/sirupsen/logrus v1.9.0
github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569
github.com/yuin/goldmark v1.5.2 github.com/yuin/goldmark v1.5.3
golang.org/x/mod v0.6.0 golang.org/x/mod v0.7.0
golang.org/x/time v0.1.0 golang.org/x/time v0.2.0
mvdan.cc/xurls v1.1.0 mvdan.cc/xurls v1.1.0
) )
@ -35,11 +35,11 @@ require (
github.com/tklauser/numcpus v0.4.0 // indirect github.com/tklauser/numcpus v0.4.0 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.1.0 // indirect golang.org/x/crypto v0.1.0 // indirect
golang.org/x/net v0.1.0 golang.org/x/net v0.2.0
golang.org/x/sys v0.1.0 // indirect golang.org/x/sys v0.2.0 // indirect
) )
require github.com/prometheus/client_golang v1.13.0 require github.com/prometheus/client_golang v1.14.0
require ( require (
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
@ -48,7 +48,7 @@ require (
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect
golang.org/x/text v0.4.0 // indirect golang.org/x/text v0.4.0 // indirect
@ -57,7 +57,7 @@ require (
require ( require (
github.com/nakabonne/tstorage v0.3.5 github.com/nakabonne/tstorage v0.3.5
github.com/shirou/gopsutil/v3 v3.22.9 github.com/shirou/gopsutil/v3 v3.22.10
) )
require github.com/SherClockHolmes/webpush-go v1.2.0 require github.com/SherClockHolmes/webpush-go v1.2.0

39
go.sum
View File

@ -82,6 +82,18 @@ github.com/aws/aws-sdk-go v1.44.118 h1:FJOqIRTukf7+Ulp047/k7JB6eqMXNnj7eb+coORTh
github.com/aws/aws-sdk-go v1.44.118/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.118/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.44.124 h1:Xe1WQRUUekZf6ZFm3SD0vplB/AP/hymVqMiRS9LQRIs= github.com/aws/aws-sdk-go v1.44.124 h1:Xe1WQRUUekZf6ZFm3SD0vplB/AP/hymVqMiRS9LQRIs=
github.com/aws/aws-sdk-go v1.44.124/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.124/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.44.125 h1:yIyCs6HX1BOj6SFTirvBwVM1tTfplKrJOyilIZPtKV8=
github.com/aws/aws-sdk-go v1.44.125/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.44.128 h1:X34pX5t0LIZXjBY11yf9JKMP3c1aZgirh+5PjtaZyJ4=
github.com/aws/aws-sdk-go v1.44.128/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.44.130 h1:a/qwOxmYJF47xTZvTjECSJXnfRbjegb3YxvCXfETtnY=
github.com/aws/aws-sdk-go v1.44.130/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.44.136 h1:J1KJJssa8pjU8jETYUxwRS37KTcxjACfKd9GK8t+5ZU=
github.com/aws/aws-sdk-go v1.44.136/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go v1.44.142 h1:KZ1/FDwCSft1DuNllFaBtWpcG0CW2NgQjvOrE1TdlXE=
github.com/aws/aws-sdk-go v1.44.142/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go v1.44.145 h1:KMVRrIyjBsNz3xGPuHIRnhIuKlb5h3Ii5e5jbi3cgnc=
github.com/aws/aws-sdk-go v1.44.145/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@ -292,11 +304,17 @@ github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnY
github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU=
github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
github.com/prometheus/client_golang v1.13.1 h1:3gMjIY2+/hzmqhtUC/aQNYldJA6DtH3CgQvwS+02K1c=
github.com/prometheus/client_golang v1.13.1/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
@ -327,6 +345,8 @@ github.com/shirou/gopsutil/v3 v3.22.8 h1:a4s3hXogo5mE2PfdfJIonDbstO/P+9JszdfhAHS
github.com/shirou/gopsutil/v3 v3.22.8/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI= github.com/shirou/gopsutil/v3 v3.22.8/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI=
github.com/shirou/gopsutil/v3 v3.22.9 h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA= github.com/shirou/gopsutil/v3 v3.22.9 h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA=
github.com/shirou/gopsutil/v3 v3.22.9/go.mod h1:bBYl1kjgEJpWpxeHmLI+dVHWtyAwfcmSBLDsp2TNT8A= github.com/shirou/gopsutil/v3 v3.22.9/go.mod h1:bBYl1kjgEJpWpxeHmLI+dVHWtyAwfcmSBLDsp2TNT8A=
github.com/shirou/gopsutil/v3 v3.22.10 h1:4KMHdfBRYXGF9skjDWiL4RA2N+E8dRdodU/bOZpPoVg=
github.com/shirou/gopsutil/v3 v3.22.10/go.mod h1:QNza6r4YQoydyCfo6rH0blGfKahgibh4dQmV5xdFkQk=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
@ -339,6 +359,7 @@ github.com/spf13/pflag v1.0.4-0.20181223182923-24fa6976df40/go.mod h1:DYY7MBk1bd
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@ -347,6 +368,7 @@ github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMT
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 h1:3SNcvBmEPE1YlB1JpVZouslJpI3GBNoiqW7+wb0Rz7w= github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 h1:3SNcvBmEPE1YlB1JpVZouslJpI3GBNoiqW7+wb0Rz7w=
github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0= github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0=
github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 h1:xzABM9let0HLLqFypcxvLmlvEciCHL7+Lv+4vwZqecI= github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 h1:xzABM9let0HLLqFypcxvLmlvEciCHL7+Lv+4vwZqecI=
@ -368,6 +390,8 @@ github.com/yuin/goldmark v1.4.14 h1:jwww1XQfhJN7Zm+/a1ZA/3WUiEBEroYFNTiV3dKwM8U=
github.com/yuin/goldmark v1.4.14/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.14/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.5.2 h1:ALmeCk/px5FSm1MAcFBAsVKZjDuMVj8Tm7FFIlMJnqU= github.com/yuin/goldmark v1.5.2 h1:ALmeCk/px5FSm1MAcFBAsVKZjDuMVj8Tm7FFIlMJnqU=
github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.5.3 h1:3HUJmBFbQW9fhQOzMgseU134xfi6hU+mjWywx5Ty+/M=
github.com/yuin/goldmark v1.5.3/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@ -383,6 +407,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
@ -419,8 +444,11 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38= golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -450,6 +478,7 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
@ -488,6 +517,8 @@ golang.org/x/net v0.0.0-20221019024206-cb67ada4b0ad h1:Zx6wVVDwwNJFWXNIvDi7o952w
golang.org/x/net v0.0.0-20221019024206-cb67ada4b0ad/go.mod h1:RpDiru2p0u2F0lLpEoqnP2+7xs0ifAuOcJ442g6GU2s= golang.org/x/net v0.0.0-20221019024206-cb67ada4b0ad/go.mod h1:RpDiru2p0u2F0lLpEoqnP2+7xs0ifAuOcJ442g6GU2s=
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -504,6 +535,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180525142821-c11f84a56e43/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180525142821-c11f84a56e43/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -553,6 +585,7 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbuf
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220804214406-8e32c043e418 h1:9vYwv7OjYaky/tlAeD7C4oC9EsPTlaFl1H2jS++V+ME= golang.org/x/sys v0.0.0-20220804214406-8e32c043e418 h1:9vYwv7OjYaky/tlAeD7C4oC9EsPTlaFl1H2jS++V+ME=
@ -561,9 +594,12 @@ golang.org/x/sys v0.0.0-20221010170243-090e33056c14 h1:k5II8e6QD8mITdi+okbbmR/cI
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -587,6 +623,8 @@ golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQL
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.2.0 h1:52I/1L54xyEQAYdtcSuxtiT84KGYTBGXwayxmIpNJhE=
golang.org/x/time v0.2.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@ -627,6 +665,7 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -2,7 +2,7 @@ openapi: 3.0.1
info: info:
title: Owncast title: Owncast
description: Owncast is a self-hosted live video and web chat server for use with existing popular broadcasting software. description: Owncast is a self-hosted live video and web chat server for use with existing popular broadcasting software.
version: '0.0.12' version: '0.0.13'
contact: contact:
name: Gabe Kangas name: Gabe Kangas
email: gabek@real-ity.com email: gabek@real-ity.com

View File

@ -9,11 +9,16 @@
"timezone": "America/Los_Angeles", "timezone": "America/Los_Angeles",
"lockFileMaintenance": { "lockFileMaintenance": {
"enabled": true, "enabled": true,
"automerge": true "automerge": true,
"platformAutomerge": true
}, },
"npm": { "npm": {
"stabilityDays": 3 "stabilityDays": 3
}, },
"dependencyDashboard": true,
"major": {
"dependencyDashboardApproval": true
},
"packageRules": [ "packageRules": [
{ {
"description": "Automatically merge minor and patch-level updates", "description": "Automatically merge minor and patch-level updates",
@ -23,20 +28,31 @@
"digest" "digest"
], ],
"automerge": true, "automerge": true,
"major": { "automergeType": "branch",
"dependencyDashboardApproval": true "platformAutomerge": true,
}, "dependencyDashboardApproval": false
"automergeType": "branch"
}, },
{ {
"matchDepTypes": [ "description": "Require approval for every Go language update",
"devDependencies" "dependencyDashboardApproval": true,
"matchPackagePatterns": [
"go"
]
},
{
"description": "Ignore the old pre-0.1.0 web packages",
"matchPackageNames": [
"postcss",
"tailwindcss",
"cssnano",
"htm",
"mark.js",
"postcss-cli",
"@videojs/themes",
"@joeattardi/emoji-button",
"preact"
], ],
"automerge": true, "enabled": false
"major": {
"dependencyDashboardApproval": true
}
} }
], ]
"platformAutomerge": true
} }

View File

@ -1585,9 +1585,9 @@
} }
}, },
"socket.io-parser": { "socket.io-parser": {
"version": "3.3.2", "version": "3.3.3",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.3.tgz",
"integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==", "integrity": "sha512-qOg87q1PMWWTeO01768Yh9ogn7chB9zkKtQnya41Y355S0UmpXgpcrFwAgjYJxu9BdKug5r5e9YtVSeWhKBUZg==",
"requires": { "requires": {
"component-emitter": "~1.3.0", "component-emitter": "~1.3.0",
"debug": "~3.1.0", "debug": "~3.1.0",
@ -1605,7 +1605,7 @@
"ms": { "ms": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
} }
} }
}, },

View File

@ -6,394 +6,395 @@ import { EmojiButton } from '/js/web_modules/@joeattardi/emoji-button.js';
import ContentEditable, { replaceCaret } from './content-editable.js'; import ContentEditable, { replaceCaret } from './content-editable.js';
import { import {
generatePlaceholderText, generatePlaceholderText,
getCaretPosition, getCaretPosition,
convertToText, convertToText,
convertOnPaste, convertOnPaste,
createEmojiMarkup, createEmojiMarkup,
trimNbsp, trimNbsp,
emojify, emojify,
} from '../../utils/chat.js'; } from '../../utils/chat.js';
import { import {
getLocalStorage, getLocalStorage,
setLocalStorage, setLocalStorage,
classNames, classNames,
} from '../../utils/helpers.js'; } from '../../utils/helpers.js';
import { import {
URL_CUSTOM_EMOJIS, URL_CUSTOM_EMOJIS,
KEY_CHAT_FIRST_MESSAGE_SENT, KEY_CHAT_FIRST_MESSAGE_SENT,
CHAT_CHAR_COUNT_BUFFER, CHAT_CHAR_COUNT_BUFFER,
CHAT_OK_KEYCODES, CHAT_OK_KEYCODES,
CHAT_KEY_MODIFIERS, CHAT_KEY_MODIFIERS,
} from '../../utils/constants.js'; } from '../../utils/constants.js';
export default class ChatInput extends Component { export default class ChatInput extends Component {
constructor(props, context) { constructor(props, context) {
super(props, context); super(props, context);
this.formMessageInput = createRef(); this.formMessageInput = createRef();
this.emojiPickerButton = createRef(); this.emojiPickerButton = createRef();
this.messageCharCount = 0; this.messageCharCount = 0;
this.prepNewLine = false; this.prepNewLine = false;
this.modifierKeyPressed = false; // control/meta/shift/alt this.modifierKeyPressed = false; // control/meta/shift/alt
this.state = { this.state = {
inputHTML: '', inputHTML: '',
inputCharsLeft: props.inputMaxBytes, inputCharsLeft: props.inputMaxBytes,
hasSentFirstChatMessage: getLocalStorage(KEY_CHAT_FIRST_MESSAGE_SENT), hasSentFirstChatMessage: getLocalStorage(KEY_CHAT_FIRST_MESSAGE_SENT),
emojiPicker: null, emojiPicker: null,
emojiList: null, emojiList: null,
emojiNames: null, emojiNames: null,
}; };
this.handleEmojiButtonClick = this.handleEmojiButtonClick.bind(this); this.handleEmojiButtonClick = this.handleEmojiButtonClick.bind(this);
this.handleEmojiSelected = this.handleEmojiSelected.bind(this); this.handleEmojiSelected = this.handleEmojiSelected.bind(this);
this.getCustomEmojis = this.getCustomEmojis.bind(this); this.getCustomEmojis = this.getCustomEmojis.bind(this);
this.handleMessageInputKeydown = this.handleMessageInputKeydown.bind(this); this.handleMessageInputKeydown = this.handleMessageInputKeydown.bind(this);
this.handleMessageInputKeyup = this.handleMessageInputKeyup.bind(this); this.handleMessageInputKeyup = this.handleMessageInputKeyup.bind(this);
this.handleMessageInputBlur = this.handleMessageInputBlur.bind(this); this.handleMessageInputBlur = this.handleMessageInputBlur.bind(this);
this.handleSubmitChatButton = this.handleSubmitChatButton.bind(this); this.handleSubmitChatButton = this.handleSubmitChatButton.bind(this);
this.handlePaste = this.handlePaste.bind(this); this.handlePaste = this.handlePaste.bind(this);
this.handleContentEditableChange = this.handleContentEditableChange =
this.handleContentEditableChange.bind(this); this.handleContentEditableChange.bind(this);
} }
componentDidMount() { componentDidMount() {
this.getCustomEmojis(); this.getCustomEmojis();
} }
getCustomEmojis() { getCustomEmojis() {
fetch(URL_CUSTOM_EMOJIS) fetch(URL_CUSTOM_EMOJIS)
.then((response) => { .then((response) => {
if (!response.ok) { if (!response.ok) {
throw new Error(`Network response was not ok ${response.ok}`); throw new Error(`Network response was not ok ${response.ok}`);
} }
return response.json(); return response.json();
}) })
.then((json) => { .then((json) => {
const emojiList = json; const emojiList = json;
const emojiNames = emojiList.map((emoji) => emoji.name); const emojiNames = emojiList.map((emoji) => emoji.name);
const emojiPicker = new EmojiButton({ const emojiPicker = new EmojiButton({
zIndex: 100, zIndex: 100,
theme: 'owncast', // see chat.css theme: 'owncast', // see chat.css
custom: json, custom: json,
initialCategory: 'custom', initialCategory: 'custom',
showPreview: false, showPreview: false,
autoHide: false, autoHide: false,
autoFocusSearch: false, autoFocusSearch: false,
showAnimation: false, showAnimation: false,
emojiSize: '24px', emojiSize: '24px',
position: 'right-start', position: 'right-start',
strategy: 'absolute', strategy: 'absolute',
}); });
emojiPicker.on('emoji', (emoji) => { emojiPicker.on('emoji', (emoji) => {
this.handleEmojiSelected(emoji); this.handleEmojiSelected(emoji);
}); });
emojiPicker.on('hidden', () => { emojiPicker.on('hidden', () => {
this.formMessageInput.current.focus(); this.formMessageInput.current.focus();
replaceCaret(this.formMessageInput.current); replaceCaret(this.formMessageInput.current);
}); });
this.setState({ emojiNames, emojiList, emojiPicker }); this.setState({ emojiNames, emojiList, emojiPicker });
}) })
.catch((error) => { .catch((error) => {
// this.handleNetworkingError(`Emoji Fetch: ${error}`); // this.handleNetworkingError(`Emoji Fetch: ${error}`);
}); });
} }
handleEmojiButtonClick() { handleEmojiButtonClick() {
const { emojiPicker } = this.state; const { emojiPicker } = this.state;
if (emojiPicker) { if (emojiPicker) {
emojiPicker.togglePicker(this.emojiPickerButton.current); emojiPicker.togglePicker(this.emojiPickerButton.current);
} }
} }
handleEmojiSelected(emoji) { handleEmojiSelected(emoji) {
const { inputHTML, inputCharsLeft } = this.state; const { inputHTML, inputCharsLeft } = this.state;
// if we're already at char limit, don't do anything // if we're already at char limit, don't do anything
if (inputCharsLeft < 0) { if (inputCharsLeft < 0) {
return; return;
} }
let content = ''; let content = '';
if (emoji.url) { if (emoji.url) {
content = createEmojiMarkup(emoji, false); content = createEmojiMarkup(emoji, false);
} else { } else {
content = emoji.emoji; content = emoji.emoji;
} }
const position = getCaretPosition(this.formMessageInput.current); const position = getCaretPosition(this.formMessageInput.current);
const newHTML = const newHTML =
inputHTML.substring(0, position) + inputHTML.substring(0, position) +
content + content +
inputHTML.substring(position); inputHTML.substring(position);
const charsLeft = this.calculateCurrentBytesLeft(newHTML); const charsLeft = this.calculateCurrentBytesLeft(newHTML);
this.setState({ this.setState({
inputHTML: newHTML, inputHTML: newHTML,
inputCharsLeft: charsLeft, inputCharsLeft: charsLeft,
}); });
// a hacky way add focus back into input field // a hacky way add focus back into input field
setTimeout(() => { setTimeout(() => {
const input = this.formMessageInput.current; const input = this.formMessageInput.current;
input.focus(); input.focus();
replaceCaret(input); replaceCaret(input);
}, 100); }, 100);
} }
// autocomplete text from the given "list". "token" marks the start of word lookup. // autocomplete text from the given "list". "token" marks the start of word lookup.
autoComplete(token, list) { autoComplete(token, list) {
const { inputHTML } = this.state; const { inputHTML } = this.state;
const position = getCaretPosition(this.formMessageInput.current); const position = getCaretPosition(this.formMessageInput.current);
const at = inputHTML.lastIndexOf(token, position - 1); const at = inputHTML.lastIndexOf(token, position - 1);
if (at === -1) { if (at === -1) {
return false; return false;
} }
let partial = inputHTML.substring(at + 1, position).trim(); let partial = inputHTML.substring(at + 1, position).trim();
if (this.partial === undefined) { if (this.partial === undefined) {
this.partial = []; this.partial = [];
} }
if (partial === this.suggestion) { if (partial === this.suggestion) {
partial = this.partial[token]; partial = this.partial[token];
} else { } else {
this.partial[token] = partial; this.partial[token] = partial;
} }
const possibilities = list.filter(function (item) { const possibilities = list.filter(function (item) {
return item.toLowerCase().startsWith(partial.toLowerCase()); return item.toLowerCase().startsWith(partial.toLowerCase());
}); });
if (this.completionIndex === undefined) { if (this.completionIndex === undefined) {
this.completionIndex = []; this.completionIndex = [];
} }
if ( if (
this.completionIndex[token] === undefined || this.completionIndex[token] === undefined ||
++this.completionIndex[token] >= possibilities.length ++this.completionIndex[token] >= possibilities.length
) { ) {
this.completionIndex[token] = 0; this.completionIndex[token] = 0;
} }
if (possibilities.length > 0) { if (possibilities.length > 0) {
this.suggestion = possibilities[this.completionIndex[token]]; this.suggestion = possibilities[this.completionIndex[token]];
const newHTML = const newHTML =
inputHTML.substring(0, at + 1) + inputHTML.substring(0, at + 1) +
this.suggestion + this.suggestion +
' ' + ' ' +
inputHTML.substring(position); inputHTML.substring(position);
this.setState({ this.setState({
inputHTML: newHTML, inputHTML: newHTML,
inputCharsLeft: this.calculateCurrentBytesLeft(newHTML), inputCharsLeft: this.calculateCurrentBytesLeft(newHTML),
}); });
} }
return true; return true;
} }
// replace :emoji: with the emoji <img> // replace :emoji: with the emoji <img>
injectEmoji() { injectEmoji() {
const { inputHTML, emojiList } = this.state; const { inputHTML, emojiList } = this.state;
const textValue = convertToText(inputHTML); const textValue = convertToText(inputHTML);
const processedHTML = emojify(inputHTML, emojiList); const processedHTML = emojify(inputHTML, emojiList);
if (textValue != convertToText(processedHTML)) { if (textValue != convertToText(processedHTML)) {
this.setState({ this.setState({
inputHTML: processedHTML, inputHTML: processedHTML,
}); });
return true; return true;
} }
return false; return false;
} }
handleMessageInputKeydown(event) { handleMessageInputKeydown(event) {
const key = event && event.key; const key = event && event.key;
if (key === 'Enter') { if (key === 'Enter') {
if (!this.prepNewLine) { if (!this.prepNewLine) {
this.sendMessage(); this.sendMessage();
event.preventDefault(); event.preventDefault();
this.prepNewLine = false; this.prepNewLine = false;
return; return;
} }
} }
// allow key presses such as command/shift/meta, etc even when message length is full later. // allow key presses such as command/shift/meta, etc even when message length is full later.
if (CHAT_KEY_MODIFIERS.includes(key)) { if (CHAT_KEY_MODIFIERS.includes(key)) {
this.modifierKeyPressed = true; this.modifierKeyPressed = true;
} }
if (key === 'Control' || key === 'Shift') { if (key === 'Control' || key === 'Shift') {
this.prepNewLine = true; this.prepNewLine = true;
} }
if (key === 'Tab') { if (key === 'Tab') {
const { chatUserNames } = this.props; const { chatUserNames } = this.props;
const { emojiNames } = this.state; const { emojiNames } = this.state;
if (this.autoComplete('@', chatUserNames)) { if (this.autoComplete('@', chatUserNames)) {
event.preventDefault(); event.preventDefault();
} }
if (this.autoComplete(':', emojiNames)) { if (this.autoComplete(':', emojiNames)) {
event.preventDefault(); event.preventDefault();
} }
} }
// if new input pushes the potential chars over, don't do anything // if new input pushes the potential chars over, don't do anything
const formField = this.formMessageInput.current; const formField = this.formMessageInput.current;
const tempCharsLeft = this.calculateCurrentBytesLeft(formField.innerHTML); const tempCharsLeft = this.calculateCurrentBytesLeft(formField.innerHTML);
if (tempCharsLeft <= 0 && !CHAT_OK_KEYCODES.includes(key)) { if (tempCharsLeft <= 0 && !CHAT_OK_KEYCODES.includes(key)) {
if (!this.modifierKeyPressed) { if (!this.modifierKeyPressed) {
event.preventDefault(); // prevent typing more event.preventDefault(); // prevent typing more
} }
return; return;
} }
} }
handleMessageInputKeyup(event) { handleMessageInputKeyup(event) {
const { key } = event; const { key } = event;
if (key === 'Control' || key === 'Shift') { if (key === 'Control' || key === 'Shift') {
this.prepNewLine = false; this.prepNewLine = false;
} }
if (CHAT_KEY_MODIFIERS.includes(key)) { if (CHAT_KEY_MODIFIERS.includes(key)) {
this.modifierKeyPressed = false; this.modifierKeyPressed = false;
} }
if (key === ':' || key === ';') { if (key === ':' || key === ';') {
this.injectEmoji(); this.injectEmoji();
} }
} }
handleMessageInputBlur() { handleMessageInputBlur() {
this.prepNewLine = false; this.prepNewLine = false;
this.modifierKeyPressed = false; this.modifierKeyPressed = false;
} }
handlePaste(event) { handlePaste(event) {
// don't allow paste if too much text already // don't allow paste if too much text already
if (this.state.inputCharsLeft < 0) { if (this.state.inputCharsLeft < 0) {
event.preventDefault(); event.preventDefault();
return; return;
} }
convertOnPaste(event, this.state.emojiList); convertOnPaste(event, this.state.emojiList);
this.handleMessageInputKeydown(event); this.handleMessageInputKeydown(event);
} }
handleSubmitChatButton(event) { handleSubmitChatButton(event) {
event.preventDefault(); event.preventDefault();
this.sendMessage(); this.sendMessage();
} }
sendMessage() { sendMessage() {
const { handleSendMessage, inputMaxBytes } = this.props; const { handleSendMessage, inputMaxBytes } = this.props;
const { hasSentFirstChatMessage, inputHTML, inputCharsLeft } = this.state; const { hasSentFirstChatMessage, inputHTML, inputCharsLeft } = this.state;
if (inputCharsLeft < 0) { if (inputCharsLeft < 0) {
return; return;
} }
const message = convertToText(inputHTML); const message = convertToText(inputHTML);
const newStates = { const newStates = {
inputHTML: '', inputHTML: '',
inputCharsLeft: inputMaxBytes, inputCharsLeft: inputMaxBytes,
}; };
handleSendMessage(message); handleSendMessage(message);
if (!hasSentFirstChatMessage) { if (!hasSentFirstChatMessage) {
newStates.hasSentFirstChatMessage = true; newStates.hasSentFirstChatMessage = true;
setLocalStorage(KEY_CHAT_FIRST_MESSAGE_SENT, true); setLocalStorage(KEY_CHAT_FIRST_MESSAGE_SENT, true);
} }
// clear things out. // clear things out.
this.setState(newStates); this.setState(newStates);
} }
handleContentEditableChange(event) { handleContentEditableChange(event) {
const value = event.target.value; const value = event.target.value;
this.setState({ this.setState({
inputHTML: value, inputHTML: value,
inputCharsLeft: this.calculateCurrentBytesLeft(value), inputCharsLeft: this.calculateCurrentBytesLeft(value),
}); });
} }
calculateCurrentBytesLeft(inputContent) { calculateCurrentBytesLeft(inputContent) {
const { inputMaxBytes } = this.props; const { inputMaxBytes } = this.props;
const curBytes = new Blob([trimNbsp(inputContent)]).size; const curBytes = new Blob([trimNbsp(inputContent)]).size;
return inputMaxBytes - curBytes; return inputMaxBytes - curBytes;
} }
render(props, state) { render(props, state) {
const { hasSentFirstChatMessage, inputCharsLeft, inputHTML, emojiPicker } = const { hasSentFirstChatMessage, inputCharsLeft, inputHTML, emojiPicker } =
state; state;
const { inputEnabled, inputMaxBytes } = props; const { inputEnabled, inputMaxBytes } = props;
const emojiButtonStyle = { const emojiButtonStyle = {
display: emojiPicker && inputCharsLeft > 0 ? 'block' : 'none', display: emojiPicker && inputCharsLeft > 0 ? 'block' : 'none',
}; };
const extraClasses = classNames({ const extraClasses = classNames({
'display-count': inputCharsLeft <= CHAT_CHAR_COUNT_BUFFER, 'display-count': inputCharsLeft <= CHAT_CHAR_COUNT_BUFFER,
}); });
const placeholderText = generatePlaceholderText( const placeholderText = generatePlaceholderText(
inputEnabled, inputEnabled,
hasSentFirstChatMessage hasSentFirstChatMessage
); );
return html` return html`
<div <div
id="message-input-container" id="message-input-container"
class="relative shadow-md bg-gray-900 border-t border-gray-700 border-solid p-4 z-20 ${extraClasses}" class="relative shadow-md bg-gray-900 border-t border-gray-700 border-solid p-4 z-20 ${extraClasses}"
> >
<div <div
id="message-input-wrap" id="message-input-wrap"
class="flex flex-row justify-end appearance-none w-full bg-gray-200 border border-black-500 rounded py-2 px-2 pr-20 my-2 overflow-auto" class="flex flex-row justify-end appearance-none w-full bg-gray-200 border border-black-500 rounded py-2 px-2 pr-20 my-2 overflow-auto"
> >
<${ContentEditable} <${ContentEditable}
id="message-input" id="message-input"
class="appearance-none block w-full bg-transparent text-sm text-gray-700 h-full focus:outline-none" aria-role="textbox"
placeholderText=${placeholderText} class="appearance-none block w-full bg-transparent text-sm text-gray-700 h-full focus:outline-none"
innerRef=${this.formMessageInput} aria-placeholder=${placeholderText}
html=${inputHTML} innerRef=${this.formMessageInput}
disabled=${!inputEnabled} html=${inputHTML}
onChange=${this.handleContentEditableChange} disabled=${!inputEnabled}
onKeyDown=${this.handleMessageInputKeydown} onChange=${this.handleContentEditableChange}
onKeyUp=${this.handleMessageInputKeyup} onKeyDown=${this.handleMessageInputKeydown}
onBlur=${this.handleMessageInputBlur} onKeyUp=${this.handleMessageInputKeyup}
onPaste=${this.handlePaste} onBlur=${this.handleMessageInputBlur}
/> onPaste=${this.handlePaste}
</div> />
<div </div>
id="message-form-actions" <div
class="absolute flex flex-col justify-end items-end mr-4" id="message-form-actions"
> class="absolute flex flex-col justify-end items-end mr-4"
<span class="flex flex-row justify-center"> >
<button <span class="flex flex-row justify-center">
ref=${this.emojiPickerButton} <button
id="emoji-button" ref=${this.emojiPickerButton}
class="text-3xl leading-3 cursor-pointer text-purple-600" id="emoji-button"
type="button" class="text-3xl leading-3 cursor-pointer text-purple-600"
style=${emojiButtonStyle} type="button"
onclick=${this.handleEmojiButtonClick} style=${emojiButtonStyle}
aria-label="Select an emoji" onclick=${this.handleEmojiButtonClick}
disabled=${!inputEnabled} aria-label="Select an emoji"
> disabled=${!inputEnabled}
<img src="../../../img/smiley.png" /> >
</button> <img src="../../../img/smiley.png" />
</button>
<button <button
id="send-message-button" id="send-message-button"
class="text-sm text-white rounded bg-gray-600 hidden p-1 ml-1 -mr-2" class="text-sm text-white rounded bg-gray-600 hidden p-1 ml-1 -mr-2"
type="button" type="button"
onclick=${this.handleSubmitChatButton} onclick=${this.handleSubmitChatButton}
disabled=${inputHTML === '' || inputCharsLeft < 0} disabled=${inputHTML === '' || inputCharsLeft < 0}
aria-label="Send message" aria-label="Send message"
> >
Send Send
</button> </button>
</span> </span>
<span id="message-form-warning" class="text-red-600 text-xs" <span id="message-form-warning" class="text-red-600 text-xs"
>${inputCharsLeft} bytes</span >${inputCharsLeft} bytes</span
> >
</div> </div>
</div> </div>
`; `;
} }
} }

View File

@ -62,7 +62,7 @@
/* If the div is empty then show the placeholder */ /* If the div is empty then show the placeholder */
#message-input:empty:before { #message-input:empty:before {
content: attr(placeholderText); content: attr(aria-placeholder);
pointer-events: none; pointer-events: none;
position: absolute; /* Fixes firefox positioning caret on the right */ position: absolute; /* Fixes firefox positioning caret on the right */
display: block; /* For Firefox */ display: block; /* For Firefox */