From dd83d51259667f61d2e431c74e66048ca250651a Mon Sep 17 00:00:00 2001 From: Andre Staltz Date: Fri, 4 Nov 2022 14:55:19 +0200 Subject: [PATCH] ux: feature: customize the public feed algorithm Co-authored-by: Andrew Chou --- .../src/main/assets/translations/en-US.json | 10 + .../app/src/main/assets/translations/en.json | 10 + package-lock.json | 1608 +++++++++++++++-- package.json | 10 +- src/frontend/components/Pill.ts | 106 ++ src/frontend/drivers/ssb/index.ts | 32 +- src/frontend/global-styles/dimens.ts | 1 + src/frontend/screens/central/index.ts | 23 +- src/frontend/screens/central/model.ts | 19 +- .../screens/central/public-tab/index.ts | 7 +- .../screens/central/public-tab/model.ts | 47 +- .../screens/central/public-tab/styles.ts | 8 +- .../screens/central/top-bar/asyncstorage.ts | 24 + src/frontend/screens/central/top-bar/index.ts | 255 +-- .../screens/central/top-bar/intent.ts | 42 + src/frontend/screens/central/top-bar/model.ts | 62 + src/frontend/screens/central/top-bar/view.ts | 415 +++++ src/frontend/ssb/plugins/threadsUtils.ts | 9 +- typings/i18n-js.d.ts | 4 + 19 files changed, 2314 insertions(+), 378 deletions(-) create mode 100644 src/frontend/components/Pill.ts create mode 100644 src/frontend/screens/central/top-bar/asyncstorage.ts create mode 100644 src/frontend/screens/central/top-bar/intent.ts create mode 100644 src/frontend/screens/central/top-bar/model.ts create mode 100644 src/frontend/screens/central/top-bar/view.ts diff --git a/android/app/src/main/assets/translations/en-US.json b/android/app/src/main/assets/translations/en-US.json index c3c2c5560..8d88c12ec 100644 --- a/android/app/src/main/assets/translations/en-US.json +++ b/android/app/src/main/assets/translations/en-US.json @@ -215,6 +215,16 @@ "connections": { "accessibility_label": "Connections Tab Button" } + }, + "filters_row": { + "all": { + "label": "All", + "accessibility_label": "All Feeds Button" + }, + "following": { + "label": "Following", + "accessibility_label": "Following Feeds Button" + } } }, "public": { diff --git a/android/app/src/main/assets/translations/en.json b/android/app/src/main/assets/translations/en.json index 134b1b8cf..3acd029de 100644 --- a/android/app/src/main/assets/translations/en.json +++ b/android/app/src/main/assets/translations/en.json @@ -215,6 +215,16 @@ "connections": { "accessibility_label": "Connections Tab Button" } + }, + "filters_row": { + "all": { + "label": "All", + "accessibility_label": "All Feeds Button" + }, + "following": { + "label": "Following", + "accessibility_label": "Following Feeds Button" + } } }, "public": { diff --git a/package-lock.json b/package-lock.json index fc102ddd7..6d58ceb1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,11 @@ "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==", "dev": true }, + "@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==" + }, "@babel/code-frame": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", @@ -3106,6 +3111,39 @@ "resolved": "https://registry.npmjs.org/@react-native/polyfills/-/polyfills-2.0.0.tgz", "integrity": "sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ==" }, + "@sammacbeth/random-access-idb-mutable-file": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@sammacbeth/random-access-idb-mutable-file/-/random-access-idb-mutable-file-0.1.1.tgz", + "integrity": "sha512-jHnpuu2qtFgwCmhgrpCCk3/hU3XqXTqhidh4XmcTijkVsGwh1c2T0+r2hkHs1PRfsxeimx8qDAotphpRoYB2eg==", + "requires": { + "buffer": "5.1.0", + "random-access-storage": "1.3.0" + }, + "dependencies": { + "buffer": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz", + "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "random-access-storage": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/random-access-storage/-/random-access-storage-1.3.0.tgz", + "integrity": "sha512-pdS9Mcb9TB7oICypPRALlheaSuszuAKmLVEPKJMuYor7R/zDuHh5ALuQoS+ox31XRwQUL+tDwWH2GPdyspwelA==", + "requires": { + "inherits": "^2.0.3" + } + } + } + }, "@sentry/browser": { "version": "7.12.1", "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.12.1.tgz", @@ -3894,6 +3932,25 @@ "resolved": "https://registry.npmjs.org/absolute-path/-/absolute-path-0.0.0.tgz", "integrity": "sha1-p4di+9rftSl76ZsV01p4Wy8JW/c=" }, + "abstract-leveldown": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", + "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "requires": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "dependencies": { + "immediate": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" + } + } + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -3983,6 +4040,19 @@ "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", "dev": true }, + "aligned-block-file": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/aligned-block-file/-/aligned-block-file-1.2.2.tgz", + "integrity": "sha512-2Sy0hWhifVb8ycNFJgicL8fDPL2Ct1r62XOVxXnykn36z22MPZwnQlCmB2viQlY/lwfuO67GaQjUZ0rJgdVP7Q==", + "requires": { + "hashlru": "^2.1.0", + "int53": "^1.0.0", + "mkdirp": "^0.5.1", + "obv": "^0.0.1", + "rwlock": "^5.0.0", + "uint48be": "^2.0.1" + } + }, "anser": { "version": "1.4.10", "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", @@ -4231,6 +4301,11 @@ "resolved": "https://registry.npmjs.org/appdirsjs/-/appdirsjs-1.2.6.tgz", "integrity": "sha512-D8wJNkqMCeQs3kLasatELsddox/Xqkhp+J07iXGyL54fVN7oc+nmNfYzGuCs1IEP6uBw+TfpuO3JKwc+lECy4w==" }, + "append-batch": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/append-batch/-/append-batch-0.0.2.tgz", + "integrity": "sha512-v1lD0bKqM4MTtGzapIx6qCGcwbVJyKaTmbzIzA6kpnVwTY1E+VNMeYoOvAywl+hXEEF4CcqkrH/4iFMbzM8XXw==" + }, "appium": { "version": "1.22.3", "resolved": "https://registry.npmjs.org/appium/-/appium-1.22.3.tgz", @@ -10974,6 +11049,54 @@ "lodash": "^4.17.14" } }, + "async-append-only-log": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/async-append-only-log/-/async-append-only-log-4.3.7.tgz", + "integrity": "sha512-eiMSi+WTFVipHJLqML3hXhe6lcV++b6VzPcpR+eKbn7sV8d9OxyogauEy+SXpwrp+LPcwXCU8WbDswLNRpHqKA==", + "requires": { + "@alloc/quick-lru": "^5.2.0", + "atomic-file-rw": "^0.3.0", + "debug": "^4.2.0", + "is-buffer-zero": "^1.0.0", + "lodash.debounce": "^4.0.8", + "looper": "^4.0.0", + "ltgt": "^2.2.1", + "mutexify": "^1.3.1", + "obz": "^1.1.0", + "polyraf": "^1.1.0", + "push-stream": "^11.0.0", + "push-stream-to-pull-stream": "^1.0.3" + }, + "dependencies": { + "atomic-file-rw": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/atomic-file-rw/-/atomic-file-rw-0.3.0.tgz", + "integrity": "sha512-XMFpe/ub9Mwdlyq3DUdOc/g2sdutDMdYw0XNFSvNGQpYdmxqVmLbeklu5KhemUYyrAj1kIrwoHOx6IxA3a7w3A==", + "requires": { + "idb-kv-store": "^4.5.0", + "mutexify": "^1.3.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "looper": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/looper/-/looper-4.0.0.tgz", + "integrity": "sha512-NjGRcX4vCwyfbujv03omakGfAYh6St5kVsZFKfU23MFO1Z9/mZT8ypTZMEnvVC7nJeYtbqkRPFV4GoJBPdJgYw==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "async-each": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", @@ -11033,6 +11156,11 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, + "b4a": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.0.tgz", + "integrity": "sha512-fsTxXxj1081Yq5MOQ06gZ5+e2QcSyP2U6NofdOWyq+lrNI4IjkZ+fLVmoQ6uUCiNg1NWePMMVq93vOTdbJmErw==" + }, "babel-core": { "version": "7.0.0-bridge.0", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", @@ -11375,6 +11503,11 @@ "dev": true, "optional": true }, + "binary-search-bounds": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/binary-search-bounds/-/binary-search-bounds-2.0.5.tgz", + "integrity": "sha512-H0ea4Fd3lS1+sTEB2TgcLoK21lLhwEJzlQv3IN47pJS976Gx4zoWe0ak3q+uYh60ppQxg9F16Ri4tS1sfD4+jA==" + }, "bip39": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.4.tgz", @@ -11418,6 +11551,14 @@ } } }, + "bipf": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/bipf/-/bipf-1.9.0.tgz", + "integrity": "sha512-B/d8IADy5Y4v/CTMRWxLD8ONd2qRkF+2DbZLeIUql7PukfAiBhlGlw5qJcIU03l21qMEyvbi4PdntatH+j40vA==", + "requires": { + "fast-varint": "^1.0.0" + } + }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -11445,6 +11586,24 @@ } } }, + "blake2b": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/blake2b/-/blake2b-2.1.4.tgz", + "integrity": "sha512-AyBuuJNI64gIvwx13qiICz6H6hpmjvYS5DGkG6jbXMOT8Z3WUJ3V1X0FlhIoT1b/5JtHE3ki+xjtMvu1nn+t9A==", + "requires": { + "blake2b-wasm": "^2.4.0", + "nanoassert": "^2.0.0" + } + }, + "blake2b-wasm": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz", + "integrity": "sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==", + "requires": { + "b4a": "^1.0.1", + "nanoassert": "^2.0.0" + } + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -11751,7 +11910,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, "requires": { "buffer-alloc-unsafe": "^1.1.0", "buffer-fill": "^1.0.0" @@ -11760,8 +11918,7 @@ "buffer-alloc-unsafe": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" }, "buffer-crc32": { "version": "0.2.13", @@ -11777,8 +11934,7 @@ "buffer-fill": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", - "dev": true + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" }, "buffer-from": { "version": "1.1.1", @@ -12238,6 +12394,14 @@ "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.4.tgz", "integrity": "sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w==" }, + "chacha20-universal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chacha20-universal/-/chacha20-universal-1.0.4.tgz", + "integrity": "sha512-/IOxdWWNa7nRabfe7+oF+jVkGjlr2xUL4J8l/OvzZhj+c9RpMqoo3Dq+5nU1j/BflRV4BKnaQ4+4oH1yBpQG1Q==", + "requires": { + "nanoassert": "^2.0.0" + } + }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -12276,6 +12440,11 @@ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, + "charwise": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/charwise/-/charwise-3.0.1.tgz", + "integrity": "sha512-RcdumNsM6fJZ5HHbYunqj2bpurVRGsXour3OR+SlLEHFhG6ALm54i6Osnh+OvO7kEoSBzwExpblYFH8zKQiEPw==" + }, "chloride": { "version": "2.2.10", "resolved": "https://registry.npmjs.org/chloride/-/chloride-2.2.10.tgz", @@ -13471,6 +13640,11 @@ } } }, + "cpu-percentage": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cpu-percentage/-/cpu-percentage-1.0.3.tgz", + "integrity": "sha512-LP7N2+hS7optwpkMisZoDfswnLeCzyETNOogkjw7v2YteQSPDd0vEv3nSbU8FVu58fXCkVAWtXaeSXEedT1a5g==" + }, "crc": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", @@ -14094,6 +14268,22 @@ "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", "dev": true }, + "deferred-leveldown": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", + "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", + "requires": { + "abstract-leveldown": "~6.2.1", + "inherits": "^2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + } + } + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -15065,6 +15255,24 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, + "encoding-down": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", + "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", + "requires": { + "abstract-leveldown": "^6.2.1", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + } + } + }, "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", @@ -15107,6 +15315,47 @@ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true }, + "envelope-js": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/envelope-js/-/envelope-js-1.3.2.tgz", + "integrity": "sha512-U3MQnyczN9QvwgXWlxDzAiEbNjwGD1aG+l1fNdwSZijOYboiu1aLHT8vIPSITShLiD4+n9p+EEwR79rp0vsKdw==", + "requires": { + "buffer-xor": "^2.0.2", + "envelope-spec": "^1.0.0", + "futoin-hkdf": "^1.5.1", + "sodium-universal": "^3.1.0", + "ssb-bfe": "^3.3.0" + }, + "dependencies": { + "buffer-xor": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz", + "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==", + "requires": { + "safe-buffer": "^5.1.1" + } + } + } + }, + "envelope-spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/envelope-spec/-/envelope-spec-1.1.0.tgz", + "integrity": "sha512-nM7yTOIVK+0YmnQAmN+00pk8eVOtnPZ/wpYWWz9ofSIk9tBrNIRhV8UTqNsCpsaGHSmEMX/MzNHs9rPVqHtf9Q==", + "requires": { + "ssb-bfe": "^1.0.1" + }, + "dependencies": { + "ssb-bfe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ssb-bfe/-/ssb-bfe-1.1.0.tgz", + "integrity": "sha512-viY/ZzQENnO+gvahYQ35tf3OPV6ChQ+CxnyPpiloDZu7bzQNL0E24wjmoGefF+ftaCK/meeWKP3Hxm7pG50cFA==", + "requires": { + "is-canonical-base64": "^1.1.1", + "ssb-ref": "^2.16.0" + } + } + } + }, "envinfo": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", @@ -15116,7 +15365,6 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, "requires": { "prr": "~1.0.1" } @@ -15624,6 +15872,21 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, + "fast-varint": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-varint/-/fast-varint-1.0.1.tgz", + "integrity": "sha512-Vi9Db6dVe0GbWHtZxYzlpLbIq4o1FnVIaVud3RMYF/E7d4l0r37aepMY16qZBNfniw/o02BP9LAqCYCKjFTy+Q==" + }, + "fastintcompression": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/fastintcompression/-/fastintcompression-0.0.4.tgz", + "integrity": "sha512-sRtejNHcWjJl0Fr+gsbybbgOKKj0sQYvv7rA787EbeFu1fMpmzjHuBW8fLBImSZeqDuR++TZU2n60mRrpAUR9g==" + }, + "fastpriorityqueue": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/fastpriorityqueue/-/fastpriorityqueue-0.7.2.tgz", + "integrity": "sha512-5DtIKh6vtOmEGkYdEPNNb+mxeYCnBiKbK3s4gq52l6cX8I5QaTDWWw0Wx/iYo80fVOblSycHu1/iJeqeNxG8Jw==" + }, "fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -15912,6 +16175,45 @@ "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.121.0.tgz", "integrity": "sha512-1gIBiWJNR0tKUNv8gZuk7l9rVX06OuLzY9AoGio7y/JT4V1IZErEMEq2TJS+PFcw/y0RshZ1J/27VfK1UQzYVg==" }, + "flumecodec": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/flumecodec/-/flumecodec-0.0.1.tgz", + "integrity": "sha512-JT0xivzdV7uTucjsLMw6JhK2e1K5TmU4fGmoQqnrJbydgY/V6+m71QoxX5ZtRR1pKoD48uhPDWWE6G5MlNoGkg==", + "requires": { + "level-codec": "^6.2.0" + }, + "dependencies": { + "level-codec": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-6.2.0.tgz", + "integrity": "sha512-J437PvCMZZKNT88+VRh6dkmh1ndZzwGwDzb5ZZl3QEsl+U9wIlt8hG+Y1gXVOhH75gf8JyceKGiG6WFUBbxyGQ==" + } + } + }, + "flumelog-offset": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/flumelog-offset/-/flumelog-offset-3.4.4.tgz", + "integrity": "sha512-sakCD+dVx541h3VeVq3Ti2lWPRrJf8PBRmnbm9EMBVLJnZkS3UD2lAlClZROxgKbh/JkMPyffvhDGv4VHNCVbA==", + "requires": { + "aligned-block-file": "^1.2.0", + "append-batch": "0.0.2", + "hashlru": "^2.3.0", + "int53": "^1.0.0", + "looper": "^4.0.0", + "obv": "0.0.1", + "pull-cursor": "^3.0.0", + "pull-looper": "^1.0.0", + "pull-stream": "^3.6.13", + "uint48be": "^2.0.1" + }, + "dependencies": { + "looper": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/looper/-/looper-4.0.0.tgz", + "integrity": "sha512-NjGRcX4vCwyfbujv03omakGfAYh6St5kVsZFKfU23MFO1Z9/mZT8ypTZMEnvVC7nJeYtbqkRPFV4GoJBPdJgYw==" + } + } + }, "flush-write-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", @@ -16573,6 +16875,11 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "futoin-hkdf": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/futoin-hkdf/-/futoin-hkdf-1.5.1.tgz", + "integrity": "sha512-g5d0Qp7ks55hYmYmfqn4Nz18XH49lcCR+vvIvHT92xXnsJaGZmY1EtWQWilJ6BQp57heCIXM/rRo+AFep8hGgg==" + }, "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", @@ -17295,6 +17602,11 @@ } } }, + "hashlru": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/hashlru/-/hashlru-2.3.0.tgz", + "integrity": "sha512-0cMsjjIC8I+D3M44pOQdsy0OHXGLVz6Z0beRuufhKa0KfaD2wGwAev6jILzXsd3/vpnNQJmWyZtIILqM1N+n5A==" + }, "hermes-engine": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/hermes-engine/-/hermes-engine-0.9.0.tgz", @@ -17348,6 +17660,11 @@ "parse-passwd": "^1.0.0" } }, + "hoox": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/hoox/-/hoox-0.0.1.tgz", + "integrity": "sha512-4tKFjXcp8AWuw5lLTL7Xnixj1w88r+y1j9HKE8GoSeqDfsv6fLNMLjnrkB/H9tH+LqLp4+7eLss5IFS3Qra4lw==" + }, "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -17666,6 +17983,11 @@ } } }, + "int53": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/int53/-/int53-1.0.0.tgz", + "integrity": "sha512-u8BMiMa05OPBgd32CKTead0CVTsFVgwFk23nNXo1teKPF6Sxcu0lXxEzP//zTcaKzXbGgPDXGmj/woyv+I4C5w==" + }, "internal-slot": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", @@ -17781,6 +18103,11 @@ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, + "is-buffer-zero": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-buffer-zero/-/is-buffer-zero-1.0.0.tgz", + "integrity": "sha512-eqgpqrTMGaAd5dQxg0dcZ79C8wTlDVYrM+zvB8kUXXSBzOqG5JeKWne1Zv9LDV3ePovx06fHLbp372OFbp/cIA==" + }, "is-builtin-module": { "version": "1.0.0", "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", @@ -17996,6 +18323,14 @@ "has-tostringtag": "^1.0.0" } }, + "is-options": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-options/-/is-options-1.0.2.tgz", + "integrity": "sha512-u+Ai74c8Q74aS8BuHwPdI1jptGOT1FQXgCq8/zv0xRuE+wRgSMEJLj8lVO8Zp9BeGb29BXY6AsNPinfqjkr7Fg==", + "requires": { + "b4a": "^1.1.1" + } + }, "is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -18480,6 +18815,87 @@ "resolved": "https://registry.npmjs.org/jetifier/-/jetifier-1.6.8.tgz", "integrity": "sha512-3Zi16h6L5tXDRQJTb221cnRoVG9/9OvreLdLU2/ZjRv/GILL+2Cemt0IKvkowwkDpvouAU1DQPOJ7qaiHeIdrw==" }, + "jitdb": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/jitdb/-/jitdb-7.0.5.tgz", + "integrity": "sha512-2RsHk4z62nufO4vMmzkzc5HSD+ry3txjJbWmN7Mbd0C+jZsJgH9bb660HiuolnsROPHLcBCyUsGAXnloJY8FZg==", + "requires": { + "atomic-file-rw": "^0.3.0", + "binary-search-bounds": "^2.0.4", + "bipf": "^1.6.2", + "crc": "3.6.0", + "debug": "^4.2.0", + "fastpriorityqueue": "^0.7.1", + "idb-kv-store": "^4.5.0", + "jsesc": "^3.0.2", + "mkdirp": "^1.0.4", + "multicb": "1.2.2", + "mutexify": "^1.4.0", + "obz": "^1.1.0", + "promisify-4loc": "1.0.0", + "pull-async": "~1.0.0", + "pull-awaitable": "^1.0.0", + "pull-cat": "~1.1.11", + "pull-stream": "^3.6.14", + "push-stream": "^11.0.0", + "push-stream-to-pull-stream": "^1.0.3", + "rimraf": "^3.0.2", + "sanitize-filename": "^1.6.3", + "traverse": "^0.6.6", + "typedarray-to-buffer": "^4.0.0", + "typedfastbitset": "~0.2.1" + }, + "dependencies": { + "atomic-file-rw": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/atomic-file-rw/-/atomic-file-rw-0.3.0.tgz", + "integrity": "sha512-XMFpe/ub9Mwdlyq3DUdOc/g2sdutDMdYw0XNFSvNGQpYdmxqVmLbeklu5KhemUYyrAj1kIrwoHOx6IxA3a7w3A==", + "requires": { + "idb-kv-store": "^4.5.0", + "mutexify": "^1.3.1" + } + }, + "crc": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.6.0.tgz", + "integrity": "sha512-K9CVP4+ugmpRvZidsumVVL1swX7t0cqYrLhT+5rAp7/S3TjiEtpovD8TISzy+3moanm6v6/cbXOzE6JbzB+siw==", + "requires": { + "buffer": "^5.1.0" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==" + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "mutexify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/mutexify/-/mutexify-1.4.0.tgz", + "integrity": "sha512-pbYSsOrSB/AKN5h/WzzLRMFgZhClWccf2XIB4RSMC8JbquiB0e0/SH5AIfdQMdyHmYtv4seU7yV/TvAwPLJ1Yg==", + "requires": { + "queue-tick": "^1.0.0" + } + } + } + }, "joi": { "version": "17.6.0", "resolved": "https://registry.npmjs.org/joi/-/joi-17.6.0.tgz", @@ -18840,47 +19256,189 @@ "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", "dev": true }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + "level": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/level/-/level-6.0.1.tgz", + "integrity": "sha512-psRSqJZCsC/irNhfHzrVZbmPYXDcEYhA5TVNwr+V92jF44rbf86hqGp8fiT702FyiArScYIlPSBTDUASCVNSpw==", + "requires": { + "level-js": "^5.0.0", + "level-packager": "^5.1.0", + "leveldown": "^5.4.0" + } }, - "libsodium": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.3.tgz", - "integrity": "sha512-ld+deUNqSsZYbAobUs63UyduPq8ICp/Ul/5lbvBIYpuSNWpPRU0PIxbW+xXipVZtuopR6fIz9e0tTnNuPMNeqw==" + "level-codec": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", + "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", + "requires": { + "buffer": "^5.6.0" + } }, - "libsodium-wrappers": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.3.tgz", - "integrity": "sha512-dw5Jh6TZ5qc5rQVZe3JrSO/J05CE+DmAPnqD7Q2glBUE969xZ6o3fchnUxyPlp6ss3x0MFxmdJntveFN+XTg1g==", + "level-concat-iterator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", + "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==" + }, + "level-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", + "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", "requires": { - "libsodium": "0.7.3" + "errno": "~0.1.1" } }, - "license-ls": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/license-ls/-/license-ls-1.5.0.tgz", - "integrity": "sha512-PkGcrLNQIHFyS762aJveoNLq74XBo8cKpau9Q0ZYWhXkT1xUB9RUkYL1a0Y2KR52ffqrh6/JSskns5a9K37rBg==", - "dev": true, + "level-iterator-stream": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", + "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", "requires": { - "cross-spawn": "^7.0.1", - "debug": "^4.1.1", - "glob": "^7.1.6", - "json2csv": "^4.5.4", - "jstoxml": "^1.6.0", - "lodash": "^4.17.15", - "ora": "^4.0.3", - "read-package-tree": "^5.3.1", - "spdx-expression-parse": "^3.0.0", - "spdx-license-list": "^6.1.0", - "table": "^5.4.6", - "yargs": "^15.1.0" + "inherits": "^2.0.4", + "readable-stream": "^3.4.0", + "xtend": "^4.0.2" }, "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } + }, + "level-js": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/level-js/-/level-js-5.0.2.tgz", + "integrity": "sha512-SnBIDo2pdO5VXh02ZmtAyPP6/+6YTJg2ibLtl9C34pWvmtMEmRTWpra+qO/hifkUtBTOtfx6S9vLDjBsBK4gRg==", + "requires": { + "abstract-leveldown": "~6.2.3", + "buffer": "^5.5.0", + "inherits": "^2.0.3", + "ltgt": "^2.1.2" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + } + } + }, + "level-packager": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", + "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", + "requires": { + "encoding-down": "^6.3.0", + "levelup": "^4.3.2" + } + }, + "level-post": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/level-post/-/level-post-1.0.7.tgz", + "integrity": "sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew==", + "requires": { + "ltgt": "^2.1.2" + } + }, + "level-supports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", + "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", + "requires": { + "xtend": "^4.0.2" + }, + "dependencies": { + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } + }, + "leveldown": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-5.6.0.tgz", + "integrity": "sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ==", + "requires": { + "abstract-leveldown": "~6.2.1", + "napi-macros": "~2.0.0", + "node-gyp-build": "~4.1.0" + }, + "dependencies": { + "node-gyp-build": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.1.1.tgz", + "integrity": "sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==" + } + } + }, + "levelup": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", + "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", + "requires": { + "deferred-leveldown": "~5.3.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~4.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + }, + "libsodium": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.3.tgz", + "integrity": "sha512-ld+deUNqSsZYbAobUs63UyduPq8ICp/Ul/5lbvBIYpuSNWpPRU0PIxbW+xXipVZtuopR6fIz9e0tTnNuPMNeqw==" + }, + "libsodium-wrappers": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.3.tgz", + "integrity": "sha512-dw5Jh6TZ5qc5rQVZe3JrSO/J05CE+DmAPnqD7Q2glBUE969xZ6o3fchnUxyPlp6ss3x0MFxmdJntveFN+XTg1g==", + "requires": { + "libsodium": "0.7.3" + } + }, + "license-ls": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/license-ls/-/license-ls-1.5.0.tgz", + "integrity": "sha512-PkGcrLNQIHFyS762aJveoNLq74XBo8cKpau9Q0ZYWhXkT1xUB9RUkYL1a0Y2KR52ffqrh6/JSskns5a9K37rBg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1", + "debug": "^4.1.1", + "glob": "^7.1.6", + "json2csv": "^4.5.4", + "jstoxml": "^1.6.0", + "lodash": "^4.17.15", + "ora": "^4.0.3", + "read-package-tree": "^5.3.1", + "spdx-expression-parse": "^3.0.0", + "spdx-license-list": "^6.1.0", + "table": "^5.4.6", + "yargs": "^15.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, @@ -19505,6 +20063,11 @@ "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==" }, + "ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==" + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -20514,6 +21077,11 @@ } } }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "modify-filename": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/modify-filename/-/modify-filename-1.1.0.tgz", @@ -20737,6 +21305,11 @@ "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==", "optional": true }, + "nanoassert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz", + "integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==" + }, "nanoid": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", @@ -20761,6 +21334,11 @@ "to-regex": "^3.0.1" } }, + "napi-macros": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==" + }, "ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", @@ -20788,6 +21366,11 @@ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" }, + "next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -21273,6 +21856,16 @@ "isobject": "^3.0.1" } }, + "obv": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/obv/-/obv-0.0.1.tgz", + "integrity": "sha512-Iq/Q3TXAfHgABGL7mKlG3ILJnT8jgetOt0sH9a6SGLLCvjh58bsH7RzixLJWkVO6aQK6hI4rxVYHF0rk9KmIwA==" + }, + "obz": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/obz/-/obz-1.1.0.tgz", + "integrity": "sha512-cG6v76kgWh48urwdsFSkxQlKWCKFYkxZJMhOIG9Aj1uPKTnNW9Hvo/ROyBfGzqaZD3K75K3jhsanKssRPkNKYA==" + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -21487,6 +22080,11 @@ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", "dev": true }, + "p-defer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-3.0.0.tgz", + "integrity": "sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw==" + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -22009,6 +22607,15 @@ "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=", "optional": true }, + "polyraf": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/polyraf/-/polyraf-1.1.0.tgz", + "integrity": "sha512-wKRyhZQE6AC70nJyMCWbwd/dX4S6UsFz+58qAF8HTpCn6C7pvr63FiH4vR9vT6VrhZrJKuT7A81ea/lIslS0bA==", + "requires": { + "random-access-file": "^2.1.0", + "random-access-web": "^2.0.1" + } + }, "popper.js": { "version": "1.16.1-lts", "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz", @@ -22359,6 +22966,19 @@ } } }, + "private-box": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/private-box/-/private-box-0.3.1.tgz", + "integrity": "sha512-abAuk3ZDyQvPLY6MygtwaDTUBIZ0C5wMMuX1jXa0svazV+keTwn7cPobRv4WYA9ctsDUztm/9CYu4y2TPL08xw==", + "requires": { + "chloride": "^2.2.9" + } + }, + "private-group-spec": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/private-group-spec/-/private-group-spec-1.1.3.tgz", + "integrity": "sha512-apod3PngS2OWKc2muNPymZNfTrQl8wt4+cj9ZQnYd3FxevlNMcjBIaLeeEy84h/I33ayZMHetGjhkNTypnb36Q==" + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -22388,6 +23008,11 @@ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, + "promisify-4loc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/promisify-4loc/-/promisify-4loc-1.0.0.tgz", + "integrity": "sha512-u/XtndUyqqDXAuhFEgFgkpjHG8IizREoj80j5dL4t41eE9yH0gzFPyOD21/VnikdPJtRziuqf6ryTu1HoTjyog==" + }, "promisify-tuple": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/promisify-tuple/-/promisify-tuple-1.2.0.tgz", @@ -22538,8 +23163,7 @@ "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" }, "pseudomap": { "version": "1.0.2", @@ -22566,6 +23190,19 @@ "safe-buffer": "^5.1.2" } }, + "pull-async": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pull-async/-/pull-async-1.0.0.tgz", + "integrity": "sha512-mm0mZe9tb3yjIhfXt384c8EXGFAtMbau20At2yNqZDPXHevjrfom5b82sk8BMQfGhj6gXimnOde1lhUKkF/v9w==" + }, + "pull-awaitable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pull-awaitable/-/pull-awaitable-1.0.0.tgz", + "integrity": "sha512-tfufzU9wMd1rM38tcgunaKMUNGXMj1Qms1ygEw+ZerkMmLAwilEtMsyzrDSLhNlnfhSzHXovOarieSNrTD1ovQ==", + "requires": { + "pull-thenable": "~1.0.0" + } + }, "pull-box-stream": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/pull-box-stream/-/pull-box-stream-1.0.13.tgz", @@ -22584,6 +23221,32 @@ "resolved": "https://registry.npmjs.org/pull-cat/-/pull-cat-1.1.11.tgz", "integrity": "sha1-tkLdElXaN2pwa220+pYvX9t0wxs=" }, + "pull-cursor": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pull-cursor/-/pull-cursor-3.0.0.tgz", + "integrity": "sha512-95lZVSF2eSEdOmUtlOBaD9p5YOvlYeCr5FBv2ySqcj/4rpaXI6d8OH+zPHHjKAf58R8QXJRZuyfHkcCX8TZbAg==", + "requires": { + "looper": "^4.0.0", + "ltgt": "^2.2.0", + "pull-stream": "^3.6.0" + }, + "dependencies": { + "looper": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/looper/-/looper-4.0.0.tgz", + "integrity": "sha512-NjGRcX4vCwyfbujv03omakGfAYh6St5kVsZFKfU23MFO1Z9/mZT8ypTZMEnvVC7nJeYtbqkRPFV4GoJBPdJgYw==" + } + } + }, + "pull-drain-gently": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pull-drain-gently/-/pull-drain-gently-1.1.0.tgz", + "integrity": "sha512-ZUPsNrn8jkU6Y2B4w8Jz3gXAmjSpb+qn4AQhAL8qTWUHULglH16ANr+6qnfOEa1kUoUGVCQZaORTd2NSQFAnhA==", + "requires": { + "cpu-percentage": "~1.0.3", + "pull-pause": "~0.0.2" + } + }, "pull-electron-ipc": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pull-electron-ipc/-/pull-electron-ipc-2.0.0.tgz", @@ -22593,9 +23256,9 @@ } }, "pull-flat-list": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/pull-flat-list/-/pull-flat-list-2.19.0.tgz", - "integrity": "sha512-viM5wpqnc/TYe28sFlmTv56ReA51vco0LrmUBTkVW4vUc1PU1Cio4dBFBwfSNbpS7v5YBp1E5l0WEKDGAL0xwg==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/pull-flat-list/-/pull-flat-list-2.20.0.tgz", + "integrity": "sha512-fzYO6dIBbHe3m+i/mNUTtIwPQX08Gw61ICJM0VLXIi98bQvRyB7D1NXuZvXeOmpKdNGj3YLcW4f5MEZYxGF8Xg==", "requires": { "@types/react": ">=16.9.0", "@types/react-native": ">=0.63.0", @@ -22623,6 +23286,44 @@ "pull-reader": "^1.2.3" } }, + "pull-level": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pull-level/-/pull-level-2.0.4.tgz", + "integrity": "sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg==", + "requires": { + "level-post": "^1.0.7", + "pull-cat": "^1.1.9", + "pull-live": "^1.0.1", + "pull-pushable": "^2.0.0", + "pull-stream": "^3.4.0", + "pull-window": "^2.1.4", + "stream-to-pull-stream": "^1.7.1" + } + }, + "pull-live": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pull-live/-/pull-live-1.0.1.tgz", + "integrity": "sha512-tkNz1QT5gId8aPhV5+dmwoIiA1nmfDOzJDlOOUpU5DNusj6neNd3EePybJ5+sITr2FwyCs/FVpx74YMCfc8YeA==", + "requires": { + "pull-cat": "^1.1.9", + "pull-stream": "^3.4.0" + } + }, + "pull-looper": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pull-looper/-/pull-looper-1.0.0.tgz", + "integrity": "sha512-djlD60A6NGe5goLdP5pgbqzMEiWmk1bInuAzBp0QOH4vDrVwh05YDz6UP8+pOXveKEk8wHVP+rB2jBrK31QMPA==", + "requires": { + "looper": "^4.0.0" + }, + "dependencies": { + "looper": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/looper/-/looper-4.0.0.tgz", + "integrity": "sha512-NjGRcX4vCwyfbujv03omakGfAYh6St5kVsZFKfU23MFO1Z9/mZT8ypTZMEnvVC7nJeYtbqkRPFV4GoJBPdJgYw==" + } + } + }, "pull-many": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/pull-many/-/pull-many-1.0.9.tgz", @@ -22644,6 +23345,26 @@ "resolved": "https://registry.npmjs.org/pull-pair/-/pull-pair-1.1.0.tgz", "integrity": "sha1-fuQnJj/fTaglOXrAoF4atLdL120=" }, + "pull-paramap": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/pull-paramap/-/pull-paramap-1.2.2.tgz", + "integrity": "sha512-0ALwLcASif3KmKCXO4liySCKsTfC/mGYhRFch+xLvfJJrYOIfXPthrykDUZpeZtbjEXglPySzfUmYcnBqzTj5w==", + "requires": { + "looper": "^4.0.0" + }, + "dependencies": { + "looper": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/looper/-/looper-4.0.0.tgz", + "integrity": "sha512-NjGRcX4vCwyfbujv03omakGfAYh6St5kVsZFKfU23MFO1Z9/mZT8ypTZMEnvVC7nJeYtbqkRPFV4GoJBPdJgYw==" + } + } + }, + "pull-pause": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/pull-pause/-/pull-pause-0.0.2.tgz", + "integrity": "sha512-yQs63NDgD/FeAsdF7INpy4uDolkstkS4Gx1Z3BvMR2gQS8RREJd2tsy6d/K6T+/CDStGnCQI7JLrkjz10YNiSA==" + }, "pull-pushable": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/pull-pushable/-/pull-pushable-2.2.0.tgz", @@ -22672,6 +23393,21 @@ "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.14.tgz", "integrity": "sha512-KIqdvpqHHaTUA2mCYcLG1ibEbu/LCKoJZsBWyv9lSYtPkJPBq8m3Hxa103xHi6D2thj5YXa0TqK3L3GUkwgnew==" }, + "pull-thenable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pull-thenable/-/pull-thenable-1.0.0.tgz", + "integrity": "sha512-gio2Yanuj5lcN8X+VXtx6F2iWxnhxfaHSKaSJHUzJMNNboEz48/+udzZFDaya8kAwj3DbuFFt1pbb8m1tIS6PQ==", + "requires": { + "quicktask": "~1.0.0" + }, + "dependencies": { + "quicktask": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/quicktask/-/quicktask-1.0.1.tgz", + "integrity": "sha512-+jhR01aSsi6Iw9wbYumKusRK72QK1ub2oE0kOnRyMkMdD/rXMMGW/TVl5edjcLjuuIKP1ezkr+xQzUMD5/4JHw==" + } + } + }, "pull-through": { "version": "1.0.18", "resolved": "https://registry.npmjs.org/pull-through/-/pull-through-1.0.18.tgz", @@ -22697,6 +23433,21 @@ } } }, + "pull-window": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/pull-window/-/pull-window-2.1.4.tgz", + "integrity": "sha512-cbDzN76BMlcGG46OImrgpkMf/VkCnupj8JhsrpBw3aWBM9ye345aYnqitmZCgauBkc0HbbRRn9hCnsa3k2FNUg==", + "requires": { + "looper": "^2.0.0" + }, + "dependencies": { + "looper": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/looper/-/looper-2.0.0.tgz", + "integrity": "sha512-6DzMHJcjbQX/UPHc1rRCBfKlLwDkvuGZ715cIR36wSdYqWXFT35uLXq5P/2orl3tz+t+VOVPxw4yPinQlUDGDQ==" + } + } + }, "pull-ws": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/pull-ws/-/pull-ws-3.3.1.tgz", @@ -22759,6 +23510,20 @@ "escape-goat": "^2.0.0" } }, + "push-stream": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/push-stream/-/push-stream-11.0.1.tgz", + "integrity": "sha512-Cb5aOY6Z6JxjAKBmpmmzoJ+8I6pJlRjJ5WYoM2Vw3kSlClojmIXzA+FP0yglJ4ELokrqLX223frxJTnxUx0dpw==" + }, + "push-stream-to-pull-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/push-stream-to-pull-stream/-/push-stream-to-pull-stream-1.0.5.tgz", + "integrity": "sha512-oQfzDroAv+SySQIXFiBVkShIh8Vgpr+hd7TrwyUna1kVrbv3i6D+QQC+31QdI7D6Jow61QLQW+uWToxv4cXI2w==", + "requires": { + "pull-looper": "^1.0.0", + "push-stream": "^11.0.1" + } + }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -22781,6 +23546,11 @@ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, + "queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, "quick-insert": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/quick-insert/-/quick-insert-1.0.0.tgz", @@ -22836,54 +23606,181 @@ "ret": "~0.1.10" } }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "random-access-chrome-file": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/random-access-chrome-file/-/random-access-chrome-file-1.2.0.tgz", + "integrity": "sha512-M1NOdkHEcjRB+acKrdQkwf8aMTnZUIGboiH6i2PMNkjfChBIJiB4j4MuhpOn+u+XU2n7GqpocPN4bzfv0jrBsg==", "requires": { - "safe-buffer": "^5.1.0" + "random-access-storage": "^1.3.0" } }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, + "random-access-file": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/random-access-file/-/random-access-file-2.2.1.tgz", + "integrity": "sha512-RGU0xmDqdOyEiynob1KYSeh8+9c9Td1MJ74GT1viMEYAn8SJ9oBtWCXLsYZukCF46yududHOdM449uRYbzBrZQ==", "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" + "mkdirp-classic": "^0.5.2", + "random-access-storage": "^1.1.1" } }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, + "random-access-idb": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/random-access-idb/-/random-access-idb-1.2.2.tgz", + "integrity": "sha512-NroFuBNVh5wVIHKN/jEYrgkkffppkfxNWFX9OEwC2VP7dYc3sa+Qxv7tMa1Gi9Jp/ObVfLeCZBt/8Sbn1WU1Xg==", "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" + "buffer-alloc": "^1.1.0", + "buffer-from": "^0.1.1", + "inherits": "^2.0.3", + "next-tick": "^1.0.0", + "once": "^1.4.0", + "random-access-storage": "^1.3.0" + }, + "dependencies": { + "buffer-from": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz", + "integrity": "sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + } } }, - "re-emitter": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/re-emitter/-/re-emitter-1.1.3.tgz", - "integrity": "sha1-+p4xn/3u6zWycpbvDz03TawvUqc=", - "optional": true - }, - "react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "random-access-idb-mutable-file": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/random-access-idb-mutable-file/-/random-access-idb-mutable-file-0.3.0.tgz", + "integrity": "sha512-CdVAoFNNDn5uAgYOJ8J3ICSaFzaMOa95XnYcX+taj4jirJuRASiTyQSOGR+Z0K8ZkBGuj0A8ivyeRAWuxRCgQA==", "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "buffer": "5.1.0", + "random-access-storage": "1.3.0" + }, + "dependencies": { + "buffer": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz", + "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "random-access-storage": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/random-access-storage/-/random-access-storage-1.3.0.tgz", + "integrity": "sha512-pdS9Mcb9TB7oICypPRALlheaSuszuAKmLVEPKJMuYor7R/zDuHh5ALuQoS+ox31XRwQUL+tDwWH2GPdyspwelA==", + "requires": { + "inherits": "^2.0.3" + } + } + } + }, + "random-access-memory": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/random-access-memory/-/random-access-memory-3.1.4.tgz", + "integrity": "sha512-rqgqd/8ec65gbpKaYHnDOW391OR39d+eXn8NI87G+f3sUKrtGib9jC+/5/9MBFBwwHAZIS8RLJ8yyB4etzbYTA==", + "requires": { + "inherits": "^2.0.3", + "is-options": "^1.0.1", + "random-access-storage": "^1.1.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + } + } + }, + "random-access-storage": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/random-access-storage/-/random-access-storage-1.4.3.tgz", + "integrity": "sha512-D5e2iIC5dNENWyBxsjhEnNOMCwZZ64TARK6dyMN+3g4OTC4MJxyjh9hKLjTGoNhDOPrgjI+YlFEHFnrp/cSnzQ==", + "requires": { + "events": "^3.3.0", + "inherits": "^2.0.3", + "queue-tick": "^1.0.0" + }, + "dependencies": { + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + } + } + }, + "random-access-web": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/random-access-web/-/random-access-web-2.0.3.tgz", + "integrity": "sha512-nN3AAgl4/lTOYMk5Qm44SzFsglOmaG2d0Kh0603umh35+rk9QXYLFf0nFJ0GOv9INBsP9iT1lub24r8PjyCtvA==", + "requires": { + "@sammacbeth/random-access-idb-mutable-file": "^0.1.1", + "random-access-chrome-file": "^1.1.2", + "random-access-idb": "^1.2.1", + "random-access-idb-mutable-file": "^0.3.0", + "random-access-memory": "^3.1.1", + "random-access-storage": "^1.3.0" + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "re-emitter": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/re-emitter/-/re-emitter-1.1.3.tgz", + "integrity": "sha1-+p4xn/3u6zWycpbvDz03TawvUqc=", + "optional": true + }, + "react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" } }, "react-blurhash": { @@ -24573,7 +25470,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -24630,6 +25526,11 @@ "aproba": "^1.1.1" } }, + "rwlock": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/rwlock/-/rwlock-5.0.0.tgz", + "integrity": "sha512-XgzRqLMfCcm9QfZuPav9cV3Xin5TRcIlp4X/SH3CvB+x5D2AakdlEepfJKDd8ByncvfpcxNWdRZVUl38PS6ZJg==" + }, "rxjs": { "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", @@ -24676,7 +25577,6 @@ "version": "1.6.3", "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", - "dev": true, "requires": { "truncate-utf8-bytes": "^1.0.0" } @@ -24853,6 +25753,42 @@ "inherits": "^2.0.1" } }, + "sha256-universal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sha256-universal/-/sha256-universal-1.2.1.tgz", + "integrity": "sha512-ghn3muhdn1ailCQqqceNxRgkOeZSVfSE13RQWEg6njB+itsFzGVSJv+O//2hvNXZuxVIRyNzrgsZ37SPDdGJJw==", + "requires": { + "b4a": "^1.0.1", + "sha256-wasm": "^2.2.1" + } + }, + "sha256-wasm": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/sha256-wasm/-/sha256-wasm-2.2.2.tgz", + "integrity": "sha512-qKSGARvao+JQlFiA+sjJZhJ/61gmW/3aNLblB2rsgIxDlDxsJPHo8a1seXj12oKtuHVgJSJJ7QEGBUYQN741lQ==", + "requires": { + "b4a": "^1.0.1", + "nanoassert": "^2.0.0" + } + }, + "sha512-universal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sha512-universal/-/sha512-universal-1.2.1.tgz", + "integrity": "sha512-kehYuigMoRkIngCv7rhgruLJNNHDnitGTBdkcYbCbooL8Cidj/bS78MDxByIjcc69M915WxcQTgZetZ1JbeQTQ==", + "requires": { + "b4a": "^1.0.1", + "sha512-wasm": "^2.3.1" + } + }, + "sha512-wasm": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/sha512-wasm/-/sha512-wasm-2.3.4.tgz", + "integrity": "sha512-akWoxJPGCB3aZCrZ+fm6VIFhJ/p8idBv7AWGFng/CZIrQo51oQNsvDbTSRXWAzIiZJvpy16oIDiCCPqTe21sKg==", + "requires": { + "b4a": "^1.0.1", + "nanoassert": "^2.0.0" + } + }, "shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -24943,6 +25879,14 @@ } } }, + "siphash24": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/siphash24/-/siphash24-1.3.1.tgz", + "integrity": "sha512-moemC3ZKiTzH29nbFo3Iw8fbemWWod4vNs/WgKbQ54oEs6mE6XVlguxvinYjB+UmaE0PThgyED9fUkWvirT8hA==", + "requires": { + "nanoassert": "^2.0.0" + } + }, "sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -25124,6 +26068,20 @@ "resolved": "https://registry.npmjs.org/sodium-chloride/-/sodium-chloride-1.1.2.tgz", "integrity": "sha512-8AVzr9VHueXqfzfkzUA0aXe/Q4XG3UTmhlP6Pt+HQc5bbAPIJFo7ZIMh9tvn+99QuiMcyDJdYumegGAczl0N+g==" }, + "sodium-javascript": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/sodium-javascript/-/sodium-javascript-0.8.0.tgz", + "integrity": "sha512-rEBzR5mPxPES+UjyMDvKPIXy9ImF17KOJ32nJNi9uIquWpS/nfj+h6m05J5yLJaGXjgM72LmQoUbWZVxh/rmGg==", + "requires": { + "blake2b": "^2.1.1", + "chacha20-universal": "^1.0.4", + "nanoassert": "^2.0.0", + "sha256-universal": "^1.1.0", + "sha512-universal": "^1.1.0", + "siphash24": "^1.0.1", + "xsalsa20": "^1.0.0" + } + }, "sodium-native": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-2.2.3.tgz", @@ -25143,6 +26101,51 @@ } } }, + "sodium-universal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-3.1.0.tgz", + "integrity": "sha512-N2gxk68Kg2qZLSJ4h0NffEhp4BjgWHCHXVlDi1aG1hA3y+ZeWEmHqnpml8Hy47QzfL1xLy5nwr9LcsWAg2Ep0A==", + "requires": { + "blake2b": "^2.1.1", + "chacha20-universal": "^1.0.4", + "nanoassert": "^2.0.0", + "resolve": "^1.17.0", + "sha256-universal": "^1.1.0", + "sha512-universal": "^1.1.0", + "siphash24": "^1.0.1", + "sodium-javascript": "~0.8.0", + "sodium-native": "^3.2.0", + "xsalsa20": "^1.0.0" + }, + "dependencies": { + "is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "requires": { + "has": "^1.0.3" + } + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "sodium-native": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-3.4.1.tgz", + "integrity": "sha512-PaNN/roiFWzVVTL6OqjzYct38NSXewdl2wz8SRB51Br/MLIJPrbM3XexhVWkq7D3UWMysfrhKVf1v1phZq6MeQ==", + "requires": { + "node-gyp-build": "^4.3.0" + } + } + } + }, "sort-keys": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", @@ -25308,6 +26311,155 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "ssb-bfe": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/ssb-bfe/-/ssb-bfe-3.6.0.tgz", + "integrity": "sha512-yvGFGZTWB0S/gMTI+CC2kQDveujid3Y4it829w6gES1BNw4QTfwyU/Rtkq2o01ITanZ2fvm3g7f0326yaNDZRg==", + "requires": { + "is-canonical-base64": "^1.1.1", + "ssb-bfe-spec": "~0.7.0", + "ssb-ref": "^2.16.0", + "ssb-uri2": "^2.1.0" + }, + "dependencies": { + "ssb-uri2": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ssb-uri2/-/ssb-uri2-2.1.0.tgz", + "integrity": "sha512-s7+gH8385NiWC8+P99TnW/t0tN+Wj5tZ9DJ8u7Ay8nkBPzNuOFvjk8o07P6QvHwLKa5tAh/pBCjv6QKIBI10vg==", + "requires": { + "ssb-typescript": "^2.5.0" + } + } + } + }, + "ssb-bfe-spec": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/ssb-bfe-spec/-/ssb-bfe-spec-0.7.0.tgz", + "integrity": "sha512-7Ab2lsbGXbVD0p8UQpqbekk7ENcioA8rmS+e1iMNhntROrR6ThdxS7TY8Q910UBNdtRKRXtDpqImA7fMN8W8LA==" + }, + "ssb-box": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ssb-box/-/ssb-box-1.0.1.tgz", + "integrity": "sha512-/lZOqFr5glmzKTmpXZ8/QbvYA6/mVQ6dDPT/+zsYQkKKEHaloMkMPRRXlK86xG+/Bsuw2HGjcm78W09aWshS+g==", + "requires": { + "chloride": "^2.4.1", + "private-box": "^0.3.1", + "ssb-ref": "^2.16.0", + "ssb-uri2": "^2.0.2" + }, + "dependencies": { + "chloride": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chloride/-/chloride-2.4.1.tgz", + "integrity": "sha512-ZiID87W2o2llvuF4C7Fvt9GJisazSdMsSkjAq4WaMed9zn77nlkcy08ZfrPtOGAXyaxTDj0VjnuyD97EdJLz3g==", + "requires": { + "sodium-browserify": "^1.2.7", + "sodium-browserify-tweetnacl": "^0.2.5", + "sodium-chloride": "^1.1.2", + "sodium-native": "^3.0.0" + } + }, + "libsodium-wrappers": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.10.tgz", + "integrity": "sha512-pO3F1Q9NPLB/MWIhehim42b/Fwb30JNScCNh8TcQ/kIc+qGLQch8ag8wb0keK3EP5kbGakk1H8Wwo7v+36rNQg==", + "requires": { + "libsodium": "^0.7.0" + } + }, + "sodium-browserify": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sodium-browserify/-/sodium-browserify-1.3.0.tgz", + "integrity": "sha512-1KRS6Oew3X13AIZhbmGF0YBdt2pQdafJMfv83OZHWbzxG92YBBnN8HYx/VKmYB4xCe90eidNaDJWBEFw/o3ahw==", + "requires": { + "libsodium-wrappers": "^0.7.4", + "sha.js": "2.4.5", + "sodium-browserify-tweetnacl": "^0.2.5", + "tweetnacl": "^0.14.1" + } + }, + "sodium-browserify-tweetnacl": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/sodium-browserify-tweetnacl/-/sodium-browserify-tweetnacl-0.2.6.tgz", + "integrity": "sha512-ZnEI26hdluilpYY28Xc4rc1ALfmEp2TWihkJX6Mdtw0z9RfHfpZJU7P8DoKbN1HcBdU9aJmguFZs7igE8nLJPg==", + "requires": { + "chloride-test": "^1.1.0", + "ed2curve": "^0.1.4", + "sha.js": "^2.4.8", + "tweetnacl": "^1.0.1", + "tweetnacl-auth": "^0.3.0" + }, + "dependencies": { + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + } + } + }, + "sodium-native": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-3.4.1.tgz", + "integrity": "sha512-PaNN/roiFWzVVTL6OqjzYct38NSXewdl2wz8SRB51Br/MLIJPrbM3XexhVWkq7D3UWMysfrhKVf1v1phZq6MeQ==", + "optional": true, + "requires": { + "node-gyp-build": "^4.3.0" + } + }, + "ssb-uri2": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ssb-uri2/-/ssb-uri2-2.1.0.tgz", + "integrity": "sha512-s7+gH8385NiWC8+P99TnW/t0tN+Wj5tZ9DJ8u7Ay8nkBPzNuOFvjk8o07P6QvHwLKa5tAh/pBCjv6QKIBI10vg==", + "requires": { + "ssb-typescript": "^2.5.0" + } + } + } + }, + "ssb-box2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ssb-box2/-/ssb-box2-2.3.0.tgz", + "integrity": "sha512-oPtupvneFUUb5IItf/Y4Et4ZYL8iU5t3VyH70v7vgrxZeDFmDhwUtsFiRU8+526Av99ztyhEONx/UQOimgGXig==", + "requires": { + "envelope-js": "^1.3.0", + "private-group-spec": "^1.1.2", + "ssb-bfe": "^3.3.0", + "ssb-keyring": "^2.0.1", + "ssb-private-group-keys": "^0.4.1", + "ssb-ref": "^2.16.0", + "ssb-uri2": "^2.0.0" + }, + "dependencies": { + "ssb-uri2": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ssb-uri2/-/ssb-uri2-2.1.0.tgz", + "integrity": "sha512-s7+gH8385NiWC8+P99TnW/t0tN+Wj5tZ9DJ8u7Ay8nkBPzNuOFvjk8o07P6QvHwLKa5tAh/pBCjv6QKIBI10vg==", + "requires": { + "ssb-typescript": "^2.5.0" + } + } + } + }, + "ssb-classic": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ssb-classic/-/ssb-classic-1.0.3.tgz", + "integrity": "sha512-0CwKmGggnqBsnxJ5KZKapWK4NTOEQaYmogrw9d9+hHDbosFmhGiLmzurVA6Y/ZyGJ5wSGJzTm83eUCv8f+26xg==", + "requires": { + "bipf": "^1.9.0", + "is-canonical-base64": "^1.1.1", + "ssb-keys": "^8.1.0", + "ssb-ref": "^2.16.0" + } + }, "ssb-conn-db": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/ssb-conn-db/-/ssb-conn-db-1.0.4.tgz", @@ -25403,6 +26555,93 @@ } } }, + "ssb-db2": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ssb-db2/-/ssb-db2-5.2.0.tgz", + "integrity": "sha512-1S3BpDqCmPZQqgDGLc+Sppla96u/GE+UxQKq3OAhhfXAW0WY1j1n6+6vCmFtVdIdOmP01rIm5Ocws9eTkFnsEQ==", + "requires": { + "async-append-only-log": "^4.3.2", + "atomic-file-rw": "^0.3.0", + "binary-search-bounds": "^2.0.4", + "bipf": "^1.9.0", + "clarify-error": "^1.0.0", + "debug": "^4.3.1", + "fastintcompression": "0.0.4", + "flumecodec": "0.0.1", + "flumelog-offset": "3.4.4", + "hoox": "0.0.1", + "jitdb": "^7.0.0", + "level": "^6.0.1", + "level-codec": "^9.0.2", + "lodash.debounce": "^4.0.8", + "mkdirp": "^1.0.4", + "multicb": "1.2.2", + "mutexify": "^1.3.1", + "obz": "^1.1.0", + "p-defer": "^3.0.0", + "pull-cat": "^1.1.11", + "pull-drain-gently": "^1.1.0", + "pull-level": "^2.0.4", + "pull-notify": "^0.1.2", + "pull-paramap": "^1.2.2", + "pull-stream": "^3.6.14", + "push-stream": "^11.0.0", + "rimraf": "^3.0.2", + "ssb-box": "^1.0.0", + "ssb-box2": "^2.0.2", + "ssb-classic": "^1.0.3", + "ssb-keys": "^8.4.0", + "ssb-ref": "^2.14.3", + "ssb-uri2": "^2.0.0", + "too-hot": "^1.0.0", + "typedarray-to-buffer": "^4.0.0" + }, + "dependencies": { + "atomic-file-rw": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/atomic-file-rw/-/atomic-file-rw-0.3.0.tgz", + "integrity": "sha512-XMFpe/ub9Mwdlyq3DUdOc/g2sdutDMdYw0XNFSvNGQpYdmxqVmLbeklu5KhemUYyrAj1kIrwoHOx6IxA3a7w3A==", + "requires": { + "idb-kv-store": "^4.5.0", + "mutexify": "^1.3.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "pull-notify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/pull-notify/-/pull-notify-0.1.2.tgz", + "integrity": "sha512-oooAxYEUGNbOVsUrmqqTWWsAUMRIs4sYglnxgleiVcWyvrWgOuk/WUoZDajPTsYix2/rd+z5xSclzHLA7QygcQ==", + "requires": { + "pull-pushable": "^2.0.0" + } + }, + "ssb-uri2": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ssb-uri2/-/ssb-uri2-2.1.0.tgz", + "integrity": "sha512-s7+gH8385NiWC8+P99TnW/t0tN+Wj5tZ9DJ8u7Ay8nkBPzNuOFvjk8o07P6QvHwLKa5tAh/pBCjv6QKIBI10vg==", + "requires": { + "ssb-typescript": "^2.5.0" + } + } + } + }, "ssb-deweird": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/ssb-deweird/-/ssb-deweird-1.0.0.tgz", @@ -25426,6 +26665,138 @@ } } }, + "ssb-keyring": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ssb-keyring/-/ssb-keyring-2.1.2.tgz", + "integrity": "sha512-GcZjL51CWDQT2iRtrg1y/R8V7IVNvuHOYHyrGXatSWkLjxedUQA/oOWCgAyPCS8e6ZQqyzZ/Q4ThqgZ7DRD3gA==", + "requires": { + "charwise": "^3.0.1", + "level": "^6.0.1", + "mkdirp": "^1.0.4", + "private-group-spec": "^1.1.3", + "pull-level": "^2.0.4", + "pull-stream": "^3.6.14", + "sodium-universal": "^3.1.0", + "ssb-private-group-keys": "^1.0.0", + "ssb-ref": "^2.16.0", + "ssb-uri2": "^2.0.2" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "ssb-private-group-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ssb-private-group-keys/-/ssb-private-group-keys-1.0.0.tgz", + "integrity": "sha512-pWKmRWKIf+DJ7dH3bEhIz+hrWNf5umBJj9JOYAWe3l86CJi5hEzS7HMcctt4neu/dB6Nt3p9GzIOi2PKOyvkew==", + "requires": { + "envelope-js": "^1.3.2", + "futoin-hkdf": "^1.5.1", + "private-group-spec": "^1.1.3", + "sodium-universal": "^3.1.0", + "ssb-bfe": "^3.5.0" + } + }, + "ssb-uri2": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ssb-uri2/-/ssb-uri2-2.1.0.tgz", + "integrity": "sha512-s7+gH8385NiWC8+P99TnW/t0tN+Wj5tZ9DJ8u7Ay8nkBPzNuOFvjk8o07P6QvHwLKa5tAh/pBCjv6QKIBI10vg==", + "requires": { + "ssb-typescript": "^2.5.0" + } + } + } + }, + "ssb-keys": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ssb-keys/-/ssb-keys-8.5.0.tgz", + "integrity": "sha512-Fdgnz5QQ/oK/bMf5Hkaqss/INqiKHFHG4RKDk3StWrQC4fUKMSL/GfnkxFlcLFGhVomzxUmhtAnhJQx2WecEKQ==", + "requires": { + "chloride": "~2.4.1", + "mkdirp": "~0.5.0", + "private-box": "~0.3.0", + "ssb-uri2": "^2.1.0" + }, + "dependencies": { + "chloride": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chloride/-/chloride-2.4.1.tgz", + "integrity": "sha512-ZiID87W2o2llvuF4C7Fvt9GJisazSdMsSkjAq4WaMed9zn77nlkcy08ZfrPtOGAXyaxTDj0VjnuyD97EdJLz3g==", + "requires": { + "sodium-browserify": "^1.2.7", + "sodium-browserify-tweetnacl": "^0.2.5", + "sodium-chloride": "^1.1.2", + "sodium-native": "^3.0.0" + } + }, + "libsodium-wrappers": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.10.tgz", + "integrity": "sha512-pO3F1Q9NPLB/MWIhehim42b/Fwb30JNScCNh8TcQ/kIc+qGLQch8ag8wb0keK3EP5kbGakk1H8Wwo7v+36rNQg==", + "requires": { + "libsodium": "^0.7.0" + } + }, + "sodium-browserify": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sodium-browserify/-/sodium-browserify-1.3.0.tgz", + "integrity": "sha512-1KRS6Oew3X13AIZhbmGF0YBdt2pQdafJMfv83OZHWbzxG92YBBnN8HYx/VKmYB4xCe90eidNaDJWBEFw/o3ahw==", + "requires": { + "libsodium-wrappers": "^0.7.4", + "sha.js": "2.4.5", + "sodium-browserify-tweetnacl": "^0.2.5", + "tweetnacl": "^0.14.1" + } + }, + "sodium-browserify-tweetnacl": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/sodium-browserify-tweetnacl/-/sodium-browserify-tweetnacl-0.2.6.tgz", + "integrity": "sha512-ZnEI26hdluilpYY28Xc4rc1ALfmEp2TWihkJX6Mdtw0z9RfHfpZJU7P8DoKbN1HcBdU9aJmguFZs7igE8nLJPg==", + "requires": { + "chloride-test": "^1.1.0", + "ed2curve": "^0.1.4", + "sha.js": "^2.4.8", + "tweetnacl": "^1.0.1", + "tweetnacl-auth": "^0.3.0" + }, + "dependencies": { + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + } + } + }, + "sodium-native": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-3.4.1.tgz", + "integrity": "sha512-PaNN/roiFWzVVTL6OqjzYct38NSXewdl2wz8SRB51Br/MLIJPrbM3XexhVWkq7D3UWMysfrhKVf1v1phZq6MeQ==", + "optional": true, + "requires": { + "node-gyp-build": "^4.3.0" + } + }, + "ssb-uri2": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ssb-uri2/-/ssb-uri2-2.1.0.tgz", + "integrity": "sha512-s7+gH8385NiWC8+P99TnW/t0tN+Wj5tZ9DJ8u7Ay8nkBPzNuOFvjk8o07P6QvHwLKa5tAh/pBCjv6QKIBI10vg==", + "requires": { + "ssb-typescript": "^2.5.0" + } + } + } + }, "ssb-keys-mnemonic": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ssb-keys-mnemonic/-/ssb-keys-mnemonic-1.0.1.tgz", @@ -25511,6 +26882,18 @@ } } }, + "ssb-private-group-keys": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/ssb-private-group-keys/-/ssb-private-group-keys-0.4.1.tgz", + "integrity": "sha512-Npl9NpUZvHho10h18/tphMfuyMlj+6lLW0mm+u8ooIRgVh5+hyoOtgJL22VmTEyD8KQVJG6SOjiv6MiGXzIL3g==", + "requires": { + "envelope-js": "^1.1.2", + "futoin-hkdf": "^1.3.2", + "private-group-spec": "^1.1.0", + "sodium-universal": "^3.0.4", + "ssb-bfe": "^3.1.1" + } + }, "ssb-ref": { "version": "2.16.0", "resolved": "https://registry.npmjs.org/ssb-ref/-/ssb-ref-2.16.0.tgz", @@ -25571,23 +26954,19 @@ } }, "ssb-threads": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/ssb-threads/-/ssb-threads-7.0.0.tgz", - "integrity": "sha512-/skrjR360Ltimw//PRJS5tgCJIYzYa7guhzxaDQ4aBJeVrVnI9KKl0yJE3bjtcPUx4XefSbfEdbXvuJaEaLIfg==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ssb-threads/-/ssb-threads-10.1.0.tgz", + "integrity": "sha512-RPb8dl+xZi/BDQwFFLiLh2/wQLLYdRykZEMEst6J01Qu/dCQA2a6wKqtlFZ9gZ8g5NL7aFhWqKuGuZoVBdkG6g==", "requires": { + "bipf": "^1.5.1", "pull-cat": "^1.1.11", + "pull-level": "^2.0.4", "pull-stream": "^3.6.2", "secret-stack-decorators": "1.1.0", - "ssb-ref": "^2.11.0", + "ssb-db2": ">=3.4.1 <=5", + "ssb-ref": "^2.13.0", "ssb-sort": "1.1.x", - "ssb-typescript": "~2.2.0" - }, - "dependencies": { - "ssb-typescript": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ssb-typescript/-/ssb-typescript-2.2.0.tgz", - "integrity": "sha512-2xdkB0FyJqjOkmv7r7SOTRP934r2Kz/bHPZlUFk5qStDVekMuTeeOkP+czTXHTgp0GYYKIQmq2ChZroz1C8AJA==" - } + "ssb-typescript": "^2.5.0" } }, "ssb-typescript": { @@ -26115,8 +27494,7 @@ "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, "symbol-observable": { "version": "2.0.3", @@ -26708,6 +28086,14 @@ } } }, + "too-hot": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/too-hot/-/too-hot-1.0.1.tgz", + "integrity": "sha512-ymyiJ8bM8e2wKfJpxbq4Fi7GwLy9w7P8PKHnsWlDgbRIampbMtjv8eFrvpMIC0bK5dKybYrYqvbLUVu5/sDQbw==", + "requires": { + "cpu-percentage": "~1.0.3" + } + }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -26729,6 +28115,11 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" }, + "traverse": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", + "integrity": "sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw==" + }, "tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -26760,7 +28151,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", - "dev": true, "requires": { "utf8-byte-length": "^1.0.1" } @@ -26908,6 +28298,11 @@ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-4.0.0.tgz", "integrity": "sha512-6dOYeZfS3O9RtRD1caom0sMxgK59b27+IwoNy8RDPsmslSGOyU+mpTamlaIW7aNKi90ZQZ9DFaZL3YRoiSCULQ==" }, + "typedfastbitset": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/typedfastbitset/-/typedfastbitset-0.2.1.tgz", + "integrity": "sha512-B2B+wo5gC7VRAqcFEiUCjS6CJ1vmeYZ7uzY3Jsu6UNStHiF+W0vkhZAmQaj5m9sC2KVrpyHGRzGuhz3M6+n/8A==" + }, "typescript": { "version": "4.5.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", @@ -26940,6 +28335,11 @@ } } }, + "uint48be": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/uint48be/-/uint48be-2.0.1.tgz", + "integrity": "sha512-LQvWofTo3RCz+XaQR3VNch+dDFwpIvWr/98imhQne++vFhpQP16YAC/a8w9N00Heqqra00ACjHT18cgvn5H+bg==" + }, "ultron": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", @@ -27354,8 +28754,7 @@ "utf8-byte-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", - "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=", - "dev": true + "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=" }, "util": { "version": "0.10.4", @@ -28423,6 +29822,11 @@ "sax": "^1.2.1" } }, + "xsalsa20": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/xsalsa20/-/xsalsa20-1.2.0.tgz", + "integrity": "sha512-FIr/DEeoHfj7ftfylnoFt3rAIRoWXpx2AoDfrT2qD2wtp7Dp+COajvs/Icb7uHqRW9m60f5iXZwdsJJO3kvb7w==" + }, "xstream": { "version": "11.14.0", "resolved": "https://registry.npmjs.org/xstream/-/xstream-11.14.0.tgz", @@ -28707,4 +30111,4 @@ "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==" } } -} \ No newline at end of file +} diff --git a/package.json b/package.json index fa8e40a9c..5581e5766 100644 --- a/package.json +++ b/package.json @@ -81,10 +81,10 @@ "@sentry/electron": "4.0.2", "@sentry/react-native": "4.5.0", "@staltz/react-native-audio-toolkit": "2.0.3-1", - "@staltz/react-native-image-viewing": "0.2.1-1", "@staltz/react-native-image-crop-picker": "0.37.5", - "buffer": "5.6.0", + "@staltz/react-native-image-viewing": "0.2.1-1", "blurhash": "1.1.x", + "buffer": "5.6.0", "byte-size": "8.1.0", "cycle-native-asyncstorage": "3.2.0", "cycle-native-clipboard": "1.0.0", @@ -107,7 +107,7 @@ "nuka-carousel": "4.8.4", "path": "0.12.7", "promisify-tuple": "1.2.0", - "pull-flat-list": "2.19.0", + "pull-flat-list": "2.20.0", "pull-pushable": "2.2.0", "pull-sorted-interleave": "1.0.0", "pull-stream": "3.6.14", @@ -153,7 +153,7 @@ "ssb-ref": "2.16.0", "ssb-room-client": "0.2.0", "ssb-serve-blobs": "3.1.1", - "ssb-threads": "7.0.0", + "ssb-threads": "^10.1.0", "ssb-typescript": "2.8.0", "ssb-uri2": "1.7.2", "strip-markdown-oneline": "1.0.3", @@ -221,4 +221,4 @@ "react-native": { "os": "react-native-os-staltz" } -} \ No newline at end of file +} diff --git a/src/frontend/components/Pill.ts b/src/frontend/components/Pill.ts new file mode 100644 index 000000000..96131c9ca --- /dev/null +++ b/src/frontend/components/Pill.ts @@ -0,0 +1,106 @@ +// SPDX-FileCopyrightText: 2022 The Manyverse Authors +// +// SPDX-License-Identifier: MPL-2.0 + +import {PureComponent} from 'react'; +import { + AccessibilityRole, + Platform, + Text, + View, + StyleSheet, + Pressable, + GestureResponderEvent, +} from 'react-native'; +import {h} from '@cycle/react'; +import {Palette} from '~frontend/global-styles/palette'; +import {Typography} from '~frontend/global-styles/typography'; +import {Dimensions} from '~frontend/global-styles/dimens'; + +const styles = StyleSheet.create({ + container: { + flexDirection: 'row', + alignItems: 'center', + alignSelf: 'flex-start', + justifyContent: 'center', + minWidth: 42, + paddingHorizontal: Dimensions.horizontalSpaceNormal, + paddingVertical: Dimensions.verticalSpaceTiny, + borderRadius: 50, + backgroundColor: Palette.backgroundText, + borderColor: Palette.textVeryWeak, + borderWidth: 1, + }, + + containerSelected: { + backgroundColor: Palette.backgroundText, + borderColor: Palette.textBrand, + borderWidth: 1, + }, + + containerHovered: { + backgroundColor: Palette.backgroundTextWeak, + }, + + textContainer: { + flexDirection: 'row', + flex: Platform.OS === 'web' ? 1 : 0, + justifyContent: 'center', + // Needed for mobile for now, probably a smarter way of preventing overflow + maxWidth: 200, + userSelect: Platform.OS === 'web' ? 'none' : undefined, + }, + + text: { + fontSize: Typography.fontSizeSmall, + fontFamily: Typography.fontFamilyReadableText, + fontWeight: 'bold', + color: Palette.textWeak, + }, + + textSelected: { + color: Palette.textBrand, + fontWeight: 'bold', + }, +}); + +interface Props { + content: string; + onPress?: (event: GestureResponderEvent) => void; + selected?: boolean; + accessibilityLabel?: string; + accessibilityRole?: AccessibilityRole; +} + +export default class Pill extends PureComponent { + public render() { + const {content, onPress, selected, accessibilityLabel, accessibilityRole} = + this.props; + + return h( + Pressable, + { + style: ({pressed, hovered}: {pressed: boolean; hovered?: boolean}) => [ + styles.container, + selected && styles.containerSelected, + (hovered || pressed) && styles.containerHovered, + ], + accessibilityLabel, + accessibilityRole, + onPress, + }, + [ + h(View, {style: styles.textContainer}, [ + h( + Text, + { + numberOfLines: 2, + style: [styles.text, selected && styles.textSelected], + }, + content, + ), + ]), + ], + ); + } +} diff --git a/src/frontend/drivers/ssb/index.ts b/src/frontend/drivers/ssb/index.ts index a5f6744ef..489c87234 100644 --- a/src/frontend/drivers/ssb/index.ts +++ b/src/frontend/drivers/ssb/index.ts @@ -75,8 +75,6 @@ export class SSBSource { private ssb$: MemoryStream; public selfFeedId$: MemoryStream; public publicRawFeed$: Stream | null>; - public publicFeed$: Stream | null>; - public publicLiveUpdates$: Stream; public privateFeed$: Stream > | null>; @@ -109,14 +107,6 @@ export class SSBSource { isReady(ssb) ? () => ssb.threadsUtils.publicRawFeed() : null, ); - this.publicFeed$ = this.ssb$.map((ssb) => - isReady(ssb) ? (opts?: any) => ssb.threadsUtils.publicFeed(opts) : null, - ); - - this.publicLiveUpdates$ = this.fromPullStream((ssb) => - isReady(ssb) ? ssb.threadsUtils.publicUpdates() : pull.empty(), - ).mapTo(null); - this.privateFeed$ = this.ssb$.map((ssb) => isReady(ssb) ? (opts?: any) => ssb.threadsUtils.privateFeed(opts) : null, ); @@ -230,6 +220,28 @@ export class SSBSource { ); } + public publicFeed$( + onlyFollowing: boolean, + ): Stream | null> { + return this.ssb$.map((ssb) => + isReady(ssb) + ? (opts?: any) => + ssb.threadsUtils.publicFeed({ + ...opts, + following: onlyFollowing, + }) + : null, + ); + } + + public publicLiveUpdates$(onlyFollowing: boolean): Stream { + return this.fromPullStream((ssb) => + isReady(ssb) + ? ssb.threadsUtils.publicUpdates(onlyFollowing) + : pull.empty(), + ).mapTo(null); + } + public threadUpdates$( rootMsgId: MsgId, privately: boolean, diff --git a/src/frontend/global-styles/dimens.ts b/src/frontend/global-styles/dimens.ts index 85bfcd21a..90e410307 100644 --- a/src/frontend/global-styles/dimens.ts +++ b/src/frontend/global-styles/dimens.ts @@ -63,6 +63,7 @@ export const Dimensions = { iconSizeNormal: 24, iconSizeSmall: 18, toolbarHeight, + filtersRowHeight: 38, // Warning: this is an ESTIMATE, not a prescribed value tabBarHeight, iosBottomSpacer, tabBarPaddingTop: Platform.select({ diff --git a/src/frontend/screens/central/index.ts b/src/frontend/screens/central/index.ts index d4a82b1c1..ab215cb0e 100644 --- a/src/frontend/screens/central/index.ts +++ b/src/frontend/screens/central/index.ts @@ -84,11 +84,6 @@ export const navOptions = { }; export function central(sources: Sources): Sinks { - const topBarSinks: TBSinks = isolate(topBar, { - '*': 'topBar', - state: topBarLens, - })(sources); - const state$ = sources.state.stream; const actions = intent(sources.screen, sources.globalEventBus, state$); @@ -97,13 +92,21 @@ export function central(sources: Sources): Sinks { .select('fab') .events('pressItem'); + const topBarSinks = isolate(topBar, { + '*': 'topBar', + state: topBarLens, + })(sources) as TBSinks; + const publicTabSinks = isolate(publicTab, { state: publicTabLens, '*': 'publicTab', })({ ...sources, fab: fabPress$, - scrollToTop: actions.scrollToPublicTop$, + scrollToTop: xs.merge( + actions.scrollToPublicTop$, + topBarSinks.scrollToPublicTop$, + ), }) as PublicTabSinks; const privateTabSinks = isolate(privateTab, { @@ -159,6 +162,7 @@ export function central(sources: Sources): Sinks { const reducer$ = xs.merge( centralReducer$, + topBarSinks.state, publicTabSinks.state, privateTabSinks.state, activityTabSinks.state, @@ -177,9 +181,12 @@ export function central(sources: Sources): Sinks { const toast$ = xs.merge(publicTabSinks.toast); - const ssb$ = xs.merge(publicTabSinks.ssb); + const ssb$ = publicTabSinks.ssb; - const storageCommand$ = publicTabSinks.asyncstorage; + const storageCommand$ = xs.merge( + topBarSinks.asyncstorage, + publicTabSinks.asyncstorage, + ); const globalEvent$ = xs.merge( state$ diff --git a/src/frontend/screens/central/model.ts b/src/frontend/screens/central/model.ts index 7091724a2..50eda35b1 100644 --- a/src/frontend/screens/central/model.ts +++ b/src/frontend/screens/central/model.ts @@ -12,7 +12,7 @@ import progressCalculation, { State as ProgressState, INITIAL_STATE as INITIAL_PROGRESS_STATE, } from '~frontend/components/progressCalculation'; -import {State as TopBarState} from './top-bar'; +import {State as TopBarState} from './top-bar/model'; import {State as PublicTabState} from './public-tab/model'; import {State as PrivateTabState} from './private-tab/model'; import {State as ActivityTabState} from './activity-tab/model'; @@ -35,6 +35,7 @@ export interface State extends ProgressState { hasNewVersion: boolean; canPublishSSB: boolean; isDrawerOpen: boolean; + publicTabFollowingOnly: boolean | null; } /** @@ -46,21 +47,26 @@ export const topBarLens: Lens = { }, set: (parent: State, child: TopBarState): State => { - return parent; + return { + ...parent, + publicTabFollowingOnly: child.publicTabFollowingOnly, + }; }, }; export const publicTabLens: Lens = { get: (parent: State): PublicTabState => { const isVisible = parent.currentTab === 'public'; - const {selfFeedId, selfAvatarUrl, canPublishSSB} = parent; + const {selfFeedId, selfAvatarUrl, canPublishSSB, publicTabFollowingOnly} = + parent; if (parent.publicTab) { const prev = parent.publicTab; if ( prev.isVisible === isVisible && prev.selfFeedId === selfFeedId && prev.selfAvatarUrl === selfAvatarUrl && - prev.canPublishSSB === canPublishSSB + prev.canPublishSSB === canPublishSSB && + prev.followingOnly === publicTabFollowingOnly ) { // Optimization: nothing changed return prev; @@ -71,6 +77,7 @@ export const publicTabLens: Lens = { selfFeedId, selfAvatarUrl, canPublishSSB, + followingOnly: publicTabFollowingOnly, }; } } else { @@ -87,6 +94,7 @@ export const publicTabLens: Lens = { hasComposeDraft: false, canPublishSSB, scrollHeaderBy: parent.scrollHeaderBy, + followingOnly: publicTabFollowingOnly, }; } }, @@ -96,6 +104,7 @@ export const publicTabLens: Lens = { parent.initializedSSB === child.initializedSSB && parent.numOfPublicUpdates === child.numOfUpdates && parent.lastSessionTimestamp === child.lastSessionTimestamp && + parent.publicTabFollowingOnly === child.followingOnly && deepEquals(parent.publicTab, child) ) { // Optimization: nothing changed in the child, so don't update the parent @@ -106,6 +115,7 @@ export const publicTabLens: Lens = { initializedSSB: child.initializedSSB, numOfPublicUpdates: child.numOfUpdates, lastSessionTimestamp: child.lastSessionTimestamp, + publicTabFollowingOnly: child.followingOnly, publicTab: child, }; } @@ -303,6 +313,7 @@ export default function model( scrollHeaderBy: new Animated.Value(0), isDrawerOpen: false, canPublishSSB: true, + publicTabFollowingOnly: null, }; } }); diff --git a/src/frontend/screens/central/public-tab/index.ts b/src/frontend/screens/central/public-tab/index.ts index 8a26efdf5..c55c5de4a 100644 --- a/src/frontend/screens/central/public-tab/index.ts +++ b/src/frontend/screens/central/public-tab/index.ts @@ -60,7 +60,12 @@ export function publicTab(sources: Sources): Sinks { const actionsPlus = {...actions, goToRawMsg$: messageEtcSinks.goToRawMsg$}; const vdom$ = view(sources.state.stream, sources.ssb, sources.scrollToTop); const command$ = navigation(actionsPlus, sources.state.stream); - const reducer$ = model(actionsPlus, sources.asyncstorage, sources.ssb); + const reducer$ = model( + actionsPlus, + sources.asyncstorage, + sources.ssb, + sources.state.stream, + ); const fabProps$ = floatingAction(sources.state.stream); const newContent$ = ssb(actionsPlus); const storageCommand$ = asyncStorage(actionsPlus, sources.asyncstorage); diff --git a/src/frontend/screens/central/public-tab/model.ts b/src/frontend/screens/central/public-tab/model.ts index a4f727924..b9db212b3 100644 --- a/src/frontend/screens/central/public-tab/model.ts +++ b/src/frontend/screens/central/public-tab/model.ts @@ -3,6 +3,7 @@ // SPDX-License-Identifier: MPL-2.0 import xs, {Stream} from 'xstream'; +import dropRepeats from 'xstream/extra/dropRepeats'; import {Reducer} from '@cycle/state'; import {Animated} from 'react-native'; import {AsyncStorageSource} from 'cycle-native-asyncstorage'; @@ -22,6 +23,7 @@ export interface State { isVisible: boolean; canPublishSSB: boolean; scrollHeaderBy: Animated.Value; + followingOnly: boolean | null; } export interface Actions { @@ -34,13 +36,23 @@ export default function model( actions: Actions, asyncStorageSource: AsyncStorageSource, ssbSource: SSBSource, + state$: Stream, ): Stream> { - const setPublicFeedReducer$ = ssbSource.publicFeed$.map( - (getReadable) => - function setPublicFeedReducer(prev: State): State { - return {...prev, getPublicFeedReadable: getReadable}; - }, - ); + const followingOnlyChanged$ = state$ + .compose(dropRepeats((x, y) => x.followingOnly === y.followingOnly)) + .filter((state) => state.followingOnly !== null) as Stream< + State & {followingOnly: boolean} + >; + + const setPublicFeedReducer$ = followingOnlyChanged$ + .map((state) => ssbSource.publicFeed$(state.followingOnly)) + .flatten() + .map( + (getReadable) => + function setPublicFeedReducer(prev: State): State { + return {...prev, getPublicFeedReadable: getReadable}; + }, + ); const updatePreferredReactionsReducer$ = ssbSource.preferredReactions$.map( (preferredReactions) => @@ -49,11 +61,12 @@ export default function model( }, ); - const incUpdatesReducer$ = ssbSource.publicLiveUpdates$.mapTo( - function incUpdatesReducer(prev: State): State { + const incUpdatesReducer$ = followingOnlyChanged$ + .map((state) => ssbSource.publicLiveUpdates$(state.followingOnly)) + .flatten() + .mapTo(function incUpdatesReducer(prev: State): State { return {...prev, numOfUpdates: prev.numOfUpdates + 1}; - }, - ); + }); const initializationDoneReducer$ = actions.initializationDone$.mapTo( function initializationDoneReducer(prev: State): State { @@ -94,6 +107,19 @@ export default function model( }, ); + const initialFollowingOnlyReducer$ = asyncStorageSource + .getItem('followingOnly') + .map( + (resultStr) => + function initialPublicTabFiltersReducer(prev: State): State { + const parsed = resultStr && JSON.parse(resultStr); + return { + ...prev, + followingOnly: parsed === null ? false : parsed, + }; + }, + ); + return xs.merge( setPublicFeedReducer$, incUpdatesReducer$, @@ -102,5 +128,6 @@ export default function model( loadLastSessionTimestampReducer$, getComposeDraftReducer$, resetUpdatesReducer$, + initialFollowingOnlyReducer$, ); } diff --git a/src/frontend/screens/central/public-tab/styles.ts b/src/frontend/screens/central/public-tab/styles.ts index 4ff85dd45..4da0c3bad 100644 --- a/src/frontend/screens/central/public-tab/styles.ts +++ b/src/frontend/screens/central/public-tab/styles.ts @@ -32,8 +32,12 @@ export const styles = StyleSheet.create({ paddingBottom: Dimensions.tabBarHeight + ThreadCard.HEIGHT * 0.5, ...Platform.select({ web: { - // Dirty hack to fix positioning of the scrollbar - marginTop: -Dimensions.toolbarHeight, + marginTop: + // The negative part is a hack to fix positioning of the scrollbar + -Dimensions.toolbarHeight + Dimensions.filtersRowHeight, + }, + default: { + marginTop: Dimensions.filtersRowHeight, }, }), }, diff --git a/src/frontend/screens/central/top-bar/asyncstorage.ts b/src/frontend/screens/central/top-bar/asyncstorage.ts new file mode 100644 index 000000000..cf40008f9 --- /dev/null +++ b/src/frontend/screens/central/top-bar/asyncstorage.ts @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: 2018-2022 The Manyverse Authors +// +// SPDX-License-Identifier: MPL-2.0 + +import {Stream} from 'xstream'; +import {Command} from 'cycle-native-asyncstorage'; +import {FeedFilter} from './model'; + +interface Actions { + updatePublicTabFilters$: Stream; +} + +export default function asyncStorage(actions: Actions) { + const publicFilters$ = actions.updatePublicTabFilters$.map((feedFilter) => { + const followingOnly = feedFilter === 'following'; + return { + type: 'setItem', + key: `followingOnly`, + value: JSON.stringify(followingOnly), + } as Command; + }); + + return publicFilters$; +} diff --git a/src/frontend/screens/central/top-bar/index.ts b/src/frontend/screens/central/top-bar/index.ts index b152513df..d119676ae 100644 --- a/src/frontend/screens/central/top-bar/index.ts +++ b/src/frontend/screens/central/top-bar/index.ts @@ -2,258 +2,47 @@ // // SPDX-License-Identifier: MPL-2.0 -import xs, {Stream} from 'xstream'; -import dropRepeatsByKeys from 'xstream-drop-repeats-by-keys'; +import {Stream} from 'xstream'; import {ReactSource} from '@cycle/react'; -import {h} from '@cycle/react'; -import {StateSource} from '@cycle/state'; +import {Reducer, StateSource} from '@cycle/state'; import {ReactElement} from 'react'; -import {StyleSheet, Platform, Animated, View} from 'react-native'; -import {getStatusBarHeight} from 'react-native-status-bar-height'; -import {Palette} from '~frontend/global-styles/palette'; -import {Dimensions} from '~frontend/global-styles/dimens'; -import {Typography} from '~frontend/global-styles/typography'; -import {IconNames} from '~frontend/global-styles/icons'; -import HeaderMenuButton from '~frontend/components/HeaderMenuButton'; -import HeaderButton from '~frontend/components/HeaderButton'; -import {t} from '~frontend/drivers/localization'; - -export interface State { - currentTab: 'public' | 'private' | 'activity' | 'connections'; - scrollHeaderBy: Animated.Value; - hasNewVersion: boolean; -} +import { + AsyncStorageSource, + Command as StorageCommand, +} from 'cycle-native-asyncstorage'; +import view from './view'; +import model, {State} from './model'; +import intent from './intent'; +import asyncStorage from './asyncstorage'; export interface Sources { screen: ReactSource; state: StateSource; + asyncstorage: AsyncStorageSource; } export interface Sinks { screen: Stream>; menuPress: Stream; + state: Stream>; publicSearch: Stream; -} - -export const styles = StyleSheet.create({ - container: { - zIndex: 30, - position: 'absolute', - top: 0, - left: 0, - right: 0, - height: Dimensions.toolbarHeight, - paddingTop: getStatusBarHeight(true), - alignSelf: 'stretch', - backgroundColor: Palette.backgroundText, - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'flex-start', - borderBottomWidth: StyleSheet.hairlineWidth, - borderBottomColor: Palette.textLine, - ...Platform.select({ - web: { - '-webkit-app-region': 'drag', - }, - }), - }, - - innerContainer: { - flex: 1, - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'flex-start', - paddingHorizontal: Dimensions.horizontalSpaceBig, - ...Platform.select({ - web: { - width: Dimensions.desktopMiddleWidth.px, - maxWidth: Dimensions.desktopMiddleWidth.px, - }, - }), - }, - - publicRightSide: { - flex: 1, - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'flex-end', - }, - - publicRightSideShown: { - display: 'flex', - }, - - publicRightSideHidden: { - display: 'none', - }, - - title: { - color: Palette.text, - fontSize: Typography.fontSizeLarge, - fontFamily: Typography.fontFamilyReadableText, - fontWeight: 'bold', - ...Platform.select({ - ios: { - position: 'absolute', - top: Dimensions.verticalSpaceTiny, - bottom: 0, - left: 40, - right: 40, - textAlign: 'center', - marginLeft: 0, - }, - web: { - marginLeft: 0, - }, - default: { - marginLeft: Dimensions.horizontalSpaceLarge, - }, - }), - }, - - updateDot: { - position: 'absolute', - top: 4, - right: 0, - backgroundColor: Palette.backgroundCTA, - width: Dimensions.dotSize, - height: Dimensions.dotSize, - borderRadius: Dimensions.dotSize * 0.5, - }, -}); - -function intent(reactSource: ReactSource) { - return { - menu$: xs.merge( - reactSource.select('menuButton').events('press'), - reactSource.select('menuProgress').events('press'), - ), - - publicSearch$: reactSource.select('search').events('press'), - }; -} - -function tabTitle(tab: State['currentTab']) { - if (tab === 'public') { - return t('central.tab_headers.public'); - } - if (tab === 'private') { - return t('central.tab_headers.private'); - } - if (tab === 'activity') { - return t('central.tab_headers.activity'); - } - if (tab === 'connections') { - return t('central.tab_headers.connections'); - } - return ''; -} - -function calcTranslateY(scrollY: Animated.Value) { - if (Platform.OS === 'web') return new Animated.Value(0); - if (Platform.OS === 'ios') return new Animated.Value(0); - const minScroll = -getStatusBarHeight(true); - const clampedScrollY = scrollY.interpolate({ - inputRange: [minScroll, minScroll + 1], - outputRange: [0, 1], - extrapolateLeft: 'clamp', - }); - const translateY = Animated.diffClamp( - clampedScrollY, - 0, - Dimensions.toolbarHeight - getStatusBarHeight(true), - ); - return Animated.multiply(translateY, -1); -} - -/** - * TODO: Disabled for all platforms. This originally was meant for iOS only, - * but we have issue #811. We should fix #811 and *then* re-enable this. - */ -function calcOpacity(scrollY: Animated.AnimatedMultiplication) { - if (Platform.OS === 'ios') return new Animated.Value(1); - if (Platform.OS === 'web') return new Animated.Value(1); - if (Platform.OS === 'android') return new Animated.Value(1); - - return scrollY.interpolate({ - inputRange: [-getStatusBarHeight(true), 0], - outputRange: [0, 1], - extrapolate: 'clamp', - }); -} - -function view(state$: Stream) { - let hideYWhenScrolling: Animated.AnimatedMultiplication | null = null; - let hideOpacityWhenScrolling: Animated.AnimatedMultiplication | null = null; - - return state$ - .compose( - dropRepeatsByKeys(['scrollHeaderBy', 'currentTab', 'hasNewVersion']), - ) - .map((state) => { - // Avoid re-instantiating a new animated value on every stream emission - if (!hideYWhenScrolling) { - hideYWhenScrolling = calcTranslateY(state.scrollHeaderBy); - } - if (!hideOpacityWhenScrolling) { - hideOpacityWhenScrolling = calcOpacity(hideYWhenScrolling); - } - - const translateY = state.currentTab === 'public' ? hideYWhenScrolling : 0; - const opacity = - state.currentTab === 'public' ? hideOpacityWhenScrolling : 1; - - return h( - Animated.View, - {style: [styles.container, {transform: [{translateY}]}]}, - [ - h(View, {style: styles.innerContainer}, [ - Platform.OS === 'web' - ? null - : h(Animated.View, {style: {opacity}}, [ - HeaderMenuButton('menuButton'), - state.hasNewVersion - ? h(View, {style: styles.updateDot}) - : null, - ]), - h( - Animated.Text, - {style: [styles.title, {opacity}]}, - tabTitle(state.currentTab), - ), - h( - Animated.View, - { - style: [ - styles.publicRightSide, - state.currentTab === 'public' - ? styles.publicRightSideShown - : styles.publicRightSideHidden, - {opacity}, - ], - }, - [ - h(HeaderButton, { - sel: 'search', - icon: IconNames.search, - side: 'right', - accessibilityLabel: t('public.search.accessibility_label'), - }), - ], - ), - ]), - ], - ); - }); + asyncstorage: Stream; + scrollToPublicTop$: Stream; } export function topBar(sources: Sources): Sinks { - const actions = intent(sources.screen); - const vdom$ = view(sources.state.stream); + const state$ = sources.state.stream; + const actions = intent(sources.screen, state$); + const reducer$ = model(actions, sources.asyncstorage); + const vdom$ = view(state$); + const storageCommand$ = asyncStorage(actions); return { screen: vdom$, + state: reducer$, menuPress: actions.menu$, publicSearch: actions.publicSearch$, + asyncstorage: storageCommand$, + scrollToPublicTop$: actions.scrollToPublicTop$, }; } diff --git a/src/frontend/screens/central/top-bar/intent.ts b/src/frontend/screens/central/top-bar/intent.ts new file mode 100644 index 000000000..9b911a19c --- /dev/null +++ b/src/frontend/screens/central/top-bar/intent.ts @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: 2022 The Manyverse Authors +// +// SPDX-License-Identifier: MPL-2.0 + +import xs, {Stream} from 'xstream'; +import {ReactSource} from '@cycle/react'; +import {FeedFilter, State} from './model'; +import sampleCombine from 'xstream/extra/sampleCombine'; + +export default function intent( + reactSource: ReactSource, + state$: Stream, +) { + const updatePublicTabFilters$ = reactSource + .select('filtersRow') + .events('filterPress'); + + const updatePublicTabFiltersWithState$ = updatePublicTabFilters$.compose( + sampleCombine(state$), + ); + + const scrollToPublicTop$ = xs.merge( + updatePublicTabFiltersWithState$ + .filter( + ([feedFilter, state]) => + (feedFilter === 'following') === state.publicTabFollowingOnly, + ) + .mapTo(null), + ); + + return { + menu$: xs.merge( + reactSource.select('menuButton').events('press'), + reactSource.select('menuProgress').events('press'), + ), + + publicSearch$: reactSource.select('search').events('press'), + + updatePublicTabFilters$, + scrollToPublicTop$, + }; +} diff --git a/src/frontend/screens/central/top-bar/model.ts b/src/frontend/screens/central/top-bar/model.ts new file mode 100644 index 000000000..ae38c3aa9 --- /dev/null +++ b/src/frontend/screens/central/top-bar/model.ts @@ -0,0 +1,62 @@ +// SPDX-FileCopyrightText: 2022 The Manyverse Authors +// +// SPDX-License-Identifier: MPL-2.0 + +import xs, {Stream} from 'xstream'; +import {Animated} from 'react-native'; +import {Reducer} from '@cycle/state'; +import {AsyncStorageSource} from 'cycle-native-asyncstorage'; + +export type FeedFilter = 'all' | 'following'; + +export interface State { + currentTab: 'public' | 'private' | 'activity' | 'connections'; + scrollHeaderBy: Animated.Value; + hasNewVersion: boolean; + publicTabFollowingOnly: boolean | null; +} + +export interface Actions { + menu$: Stream; + publicSearch$: Stream; + updatePublicTabFilters$: Stream; +} + +export default function model( + actions: Actions, + asyncStorageSource: AsyncStorageSource, +): Stream> { + const initialPublicTabFiltersReducer$ = asyncStorageSource + .getItem('followingOnly') + .map( + (resultStr) => + function initialPublicTabFiltersReducer(prev: State): State { + const parsed = resultStr && JSON.parse(resultStr); + return { + ...prev, + publicTabFollowingOnly: parsed === null ? false : parsed, + }; + }, + ); + + const updatePublicTabFiltersReducer$ = actions.updatePublicTabFilters$.map( + (feedFilter) => + function updatePublicTabFiltersReducer(prev: State): State { + const publicTabFollowingOnly = feedFilter === 'following'; + + if (publicTabFollowingOnly === prev.publicTabFollowingOnly) { + return prev; + } else { + return { + ...prev, + publicTabFollowingOnly, + }; + } + }, + ); + + return xs.merge( + initialPublicTabFiltersReducer$, + updatePublicTabFiltersReducer$, + ); +} diff --git a/src/frontend/screens/central/top-bar/view.ts b/src/frontend/screens/central/top-bar/view.ts new file mode 100644 index 000000000..f7e08016c --- /dev/null +++ b/src/frontend/screens/central/top-bar/view.ts @@ -0,0 +1,415 @@ +// SPDX-FileCopyrightText: 2022 The Manyverse Authors +// +// SPDX-License-Identifier: MPL-2.0 + +import {Stream} from 'xstream'; +import dropRepeatsByKeys from 'xstream-drop-repeats-by-keys'; +import {h} from '@cycle/react'; +import {Fragment, PureComponent, createElement as $} from 'react'; +import { + StyleSheet, + Platform, + Animated, + View, + ViewStyle, + Image, + TouchableOpacity, + TouchableHighlight, +} from 'react-native'; +import {getStatusBarHeight} from 'react-native-status-bar-height'; +import {t} from '~frontend/drivers/localization'; +import {Palette} from '~frontend/global-styles/palette'; +import {Dimensions} from '~frontend/global-styles/dimens'; +import {Typography} from '~frontend/global-styles/typography'; +import {IconNames} from '~frontend/global-styles/icons'; +import HeaderButton from '~frontend/components/HeaderButton'; +import Pill from '~frontend/components/Pill'; +import {FeedFilter, State} from './model'; +import {getImg} from '~frontend/global-styles/utils'; + +const Touchable = Platform.select({ + ios: TouchableOpacity, + default: TouchableHighlight, +}); + +const Z_INDEX = 30; +const APP_LOGO_SIZE = Dimensions.iconSizeBig; +const MENU_BUTTON_SIZE = Dimensions.iconSizeLarge; + +export const styles = StyleSheet.create({ + container: { + position: 'absolute', + zIndex: Z_INDEX, + top: 0, + left: 0, + right: 0, + height: Dimensions.toolbarHeight, + paddingTop: getStatusBarHeight(true), + alignSelf: 'stretch', + backgroundColor: Palette.backgroundText, + flexDirection: 'column', + justifyContent: 'flex-start', + alignItems: 'stretch', + borderBottomWidth: StyleSheet.hairlineWidth, + borderBottomColor: Palette.textLine, + ...Platform.select({ + web: { + '-webkit-app-region': 'drag', + }, + android: { + elevation: 3, + shadowColor: '#000000', + shadowOffset: {width: 0, height: -1}, + shadowOpacity: 0.2, + shadowRadius: 3, + }, + ios: { + shadowColor: '#000000', + shadowOffset: {width: 0, height: -1}, + shadowOpacity: 0.2, + shadowRadius: 3, + }, + }), + }, + + innerContainer: { + flex: 1, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'flex-start', + paddingHorizontal: Dimensions.horizontalSpaceBig, + ...Platform.select({ + web: { + width: Dimensions.desktopMiddleWidth.px, + maxWidth: Dimensions.desktopMiddleWidth.px, + }, + }), + }, + + publicRightSide: { + flex: 1, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'flex-end', + }, + + title: { + color: Palette.text, + fontSize: Typography.fontSizeLarge, + fontFamily: Typography.fontFamilyReadableText, + fontWeight: 'bold', + ...Platform.select({ + ios: { + position: 'absolute', + top: Dimensions.verticalSpaceTiny, + bottom: 0, + left: 40, + right: 40, + textAlign: 'center', + marginLeft: 0, + }, + web: { + marginLeft: 0, + }, + default: { + marginLeft: Dimensions.horizontalSpaceLarge, + }, + }), + }, + + appLogoTouchable: { + width: MENU_BUTTON_SIZE, + height: MENU_BUTTON_SIZE, + borderRadius: MENU_BUTTON_SIZE * 0.5, + marginLeft: -(MENU_BUTTON_SIZE - APP_LOGO_SIZE) * 0.5, + flexDirection: 'row', + justifyContent: 'center', + alignItems: 'center', + }, + + appLogo: { + width: APP_LOGO_SIZE, + height: APP_LOGO_SIZE, + }, + + updateDot: { + position: 'absolute', + top: 1, + right: -1, + backgroundColor: Palette.backgroundCTA, + width: Dimensions.dotSize, + height: Dimensions.dotSize, + borderRadius: Dimensions.dotSize * 0.5, + }, + + filtersRowContainer: { + zIndex: Z_INDEX, + position: 'absolute', + top: Dimensions.toolbarHeight, + height: Dimensions.filtersRowHeight, + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + ...Platform.select({ + web: { + alignSelf: 'stretch', + left: Dimensions.desktopMiddleWidth.px, + transformOrigin: 'left', + transform: 'scaleX(-1)', + justifyContent: 'flex-start', + } as React.CSSProperties & ViewStyle, + default: { + right: 0, + justifyContent: 'flex-end', + }, + }), + }, + + filtersRow: { + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'flex-start', + paddingHorizontal: Dimensions.horizontalSpaceBig, + ...Platform.select({ + web: { + // alignSelf: 'flex-end', + backgroundColor: 'transparent', + transform: 'scaleX(-1)', + } as React.CSSProperties & ViewStyle, + }), + }, + + filtersRowSpacer: { + height: 1, + width: Dimensions.horizontalSpaceSmall, + }, +}); + +function tabTitle(tab: State['currentTab']) { + if (tab === 'public') { + return t('central.tab_headers.public'); + } + if (tab === 'private') { + return t('central.tab_headers.private'); + } + if (tab === 'activity') { + return t('central.tab_headers.activity'); + } + if (tab === 'connections') { + return t('central.tab_headers.connections'); + } + return ''; +} + +function calcTranslateY(scrollY: Animated.Value, isPublicTab: Animated.Value) { + if (Platform.OS === 'web') return new Animated.Value(0); + if (Platform.OS === 'ios') return new Animated.Value(0); + const minScroll = -getStatusBarHeight(true); + const clampedScrollY = scrollY.interpolate({ + inputRange: [minScroll, minScroll + 1], + outputRange: [0, 1], + extrapolateLeft: 'clamp', + }); + const translateY = Animated.diffClamp( + clampedScrollY, + 0, + Dimensions.toolbarHeight - getStatusBarHeight(true), + ); + return Animated.multiply(isPublicTab, Animated.multiply(translateY, -1)); +} + +function calcOpacity(scrollY: Animated.AnimatedMultiplication) { + if (Platform.OS !== 'ios') return new Animated.Value(1); + + return scrollY.interpolate({ + inputRange: [-getStatusBarHeight(true), 0], + outputRange: [0, 1], + extrapolate: 'clamp', + }); +} + +class AppLogoButton extends PureComponent<{onPress?: () => void}> { + private _onPress = () => { + this.props.onPress?.(); + }; + + public render() { + return $( + Touchable, + { + style: styles.appLogoTouchable, + onPress: this._onPress, + hitSlop: {top: 8, bottom: 8, left: 8, right: 8}, + underlayColor: Palette.transparencyDarkWeak, + activeOpacity: 0.4, + }, + + $(Image, { + style: styles.appLogo, + source: getImg(require('~images/app-logo-30.png')), + accessible: true, + accessibilityRole: 'button', + accessibilityLabel: t('call_to_action.open_menu.accessibility_label'), + }), + ); + } +} + +class FiltersRow extends PureComponent<{ + followingOnly: boolean; + onFilterPress?: (feedFilter: FeedFilter) => void; +}> { + private _onPressAll = () => { + this.props.onFilterPress?.('all'); + }; + + private _onPressFollowing = () => { + this.props.onFilterPress?.('following'); + }; + + public render() { + const {followingOnly} = this.props; + return $( + View, + {style: styles.filtersRow}, + $(Pill, { + onPress: this._onPressAll, + selected: !followingOnly, + content: t('central.filters_row.all.label'), + accessibilityLabel: t('central.filters_row.all.accessibility_label'), + accessibilityRole: 'button', + }), + $(View, {style: styles.filtersRowSpacer}), + $(Pill, { + onPress: this._onPressFollowing, + selected: followingOnly, + content: t('central.filters_row.following.label'), + accessibilityLabel: t( + 'central.filters_row.following.accessibility_label', + ), + accessibilityRole: 'button', + }), + ); + } +} + +export default function view(state$: Stream) { + let hideYWhenScrolling: Animated.AnimatedMultiplication | null = null; + let hideOpacityWhenScrolling: Animated.AnimatedMultiplication | null = null; + let isPublicTab = new Animated.Value(1); + + return state$ + .compose( + dropRepeatsByKeys([ + 'scrollHeaderBy', + 'currentTab', + 'hasNewVersion', + 'publicTabFollowingOnly', + ]), + ) + .map((state) => { + isPublicTab.setValue(state.currentTab === 'public' ? 1 : 0); + // Avoid re-instantiating a new animated value on every stream emission + if (!hideYWhenScrolling) { + hideYWhenScrolling = calcTranslateY(state.scrollHeaderBy, isPublicTab); + } + if (!hideOpacityWhenScrolling) { + hideOpacityWhenScrolling = calcOpacity(hideYWhenScrolling); + } + + const translateY = hideYWhenScrolling; + const opacity = hideOpacityWhenScrolling; + + const menuButton = h(Animated.View, {key: 'mb', style: {opacity}}, [ + h(AppLogoButton, {key: 'alb', sel: 'menuButton'}), + state.hasNewVersion + ? h(View, {key: 'ud', style: styles.updateDot}) + : null, + ]); + + const title = h( + Animated.Text, + {key: 't', style: [styles.title, {opacity}]}, + tabTitle(state.currentTab), + ); + + const rightSide = h( + Animated.View, + { + key: 'rs', + style: [styles.publicRightSide, {opacity}], + }, + [ + h(HeaderButton, { + sel: 'search', + icon: IconNames.search, + side: 'right', + accessibilityLabel: t('public.search.accessibility_label'), + }), + ], + ); + + const filtersRow = h( + View, + {key: 'fr', style: styles.filtersRowContainer}, + [ + h(FiltersRow, { + sel: 'filtersRow', + followingOnly: !!state.publicTabFollowingOnly, + }), + ], + ); + + if (state.currentTab === 'public') { + if (Platform.OS === 'web') { + return h(Fragment, [ + h( + Animated.View, + { + key: 'tb', + style: [styles.container, {transform: [{translateY}]}], + }, + [ + h(View, {key: 'ic', style: styles.innerContainer}, [ + title, + rightSide, + ]), + ], + ), + filtersRow, + ]); + } else { + return h( + Animated.View, + { + key: 'tb', + style: [styles.container, {transform: [{translateY}]}], + }, + [ + h(View, {key: 'ic', style: styles.innerContainer}, [ + menuButton, + title, + rightSide, + ]), + filtersRow, + ], + ); + } + } else { + return h( + Animated.View, + { + key: 'tb', + style: [styles.container, {transform: [{translateY}]}], + }, + [ + h(View, {key: 'ic', style: styles.innerContainer}, [ + Platform.OS === 'web' ? null : menuButton, + title, + ]), + ], + ); + } + }); +} diff --git a/src/frontend/ssb/plugins/threadsUtils.ts b/src/frontend/ssb/plugins/threadsUtils.ts index cfaee6b31..6c8396a45 100644 --- a/src/frontend/ssb/plugins/threadsUtils.ts +++ b/src/frontend/ssb/plugins/threadsUtils.ts @@ -7,7 +7,7 @@ import xsFromCallback from 'xstream-from-callback'; import xsFromPullStream from 'xstream-from-pull-stream'; const pull = require('pull-stream'); const Ref = require('ssb-ref'); -import {Thread as ThreadData} from 'ssb-threads/types'; +import {Thread as ThreadData} from 'ssb-threads/lib/types'; import { Msg, Content, @@ -280,8 +280,11 @@ const threadsUtils = { ); }, - publicUpdates() { - return ssb.threads.publicUpdates({allowlist: publicAllowlist}); + publicUpdates(followingOnly: boolean) { + return ssb.threads.publicUpdates({ + allowlist: publicAllowlist, + following: followingOnly, + }); }, hashtagFeed(hashtag: string) { diff --git a/typings/i18n-js.d.ts b/typings/i18n-js.d.ts index a19ff1f2f..ea2f970b4 100644 --- a/typings/i18n-js.d.ts +++ b/typings/i18n-js.d.ts @@ -103,6 +103,10 @@ declare module 'i18n-js' { | 'central.tabs.private.accessibility_label' | 'central.tabs.activity.accessibility_label' | 'central.tabs.connections.accessibility_label' + | 'central.filters_row.all.label' + | 'central.filters_row.all.accessibility_label' + | 'central.filters_row.following.label' + | 'central.filters_row.following.accessibility_label' | 'public.floating_action_button.compose' | 'public.empty.title' | 'public.empty.description'