chats working.

This commit is contained in:
fiatjaf 2021-12-18 20:56:13 -03:00
parent a514c5a8fc
commit 155571e319
8 changed files with 188 additions and 93 deletions

View File

@ -11,9 +11,8 @@
"dependencies": {
"@quasar/extras": "^1.0.0",
"core-js": "^3.6.5",
"crypto": "^1.0.1",
"identicon.js": "^2.3.3",
"nostr-tools": "^0.10.3",
"nostr-tools": "^0.11.0",
"pouchdb-adapter-idb": "6",
"pouchdb-core": "6",
"pouchdb-mapreduce": "6",

View File

@ -92,6 +92,39 @@ export function onNewHomeFeedNote(onNewEvent = () => {}) {
return changes
}
export async function dbGetMessages(peerPubKey, limit = 50, since) {
let result = await db.query('main/messages', {
include_docs: true,
descending: false,
startkey: [peerPubKey, since],
endkey: [peerPubKey, {}],
limit
})
return result.rows.map(r => r.doc)
}
export function onNewMessage(peerPubKey, onNewEvent = () => {}) {
// listen for changes
let changes = db.changes({
live: true,
since: 'now',
include_docs: true,
filter: '_view',
view: 'main/messages'
})
changes.on('change', change => {
if (
change.doc.pubkey === peerPubKey ||
change.doc.tags.find(([t, v]) => t === 'p' && v === peerPubKey)
) {
onNewEvent(change.doc)
}
})
return changes
}
export async function dbGetMentions(ourPubKey, limit = 20, skip = 0) {
let result = await db.query('main/mentions', {
include_docs: true,
@ -104,18 +137,6 @@ export async function dbGetMentions(ourPubKey, limit = 20, skip = 0) {
return result.rows.map(r => r.doc)
}
export async function dbGetMessages(peerPubKey, limit = 50, skip = 0) {
let result = await db.query('main/messages', {
include_docs: true,
descending: true,
startkey: [peerPubKey, {}],
endkey: [peerPubKey],
limit,
skip
})
return result.rows.map(r => r.doc)
}
export async function dbGetProfile(pubkey) {
let result = await db.query('main/profiles', {
include_docs: true,

View File

@ -119,7 +119,7 @@
</div>
</q-form>
<div class="text-lg">Following</div>
<q-list>
<q-list v-if="$store.state.following.length">
<q-item
v-for="pubkey in $store.state.following"
:key="pubkey"
@ -138,6 +138,9 @@
</q-item-section>
</q-item>
</q-list>
<div v-else class="my-3">
When you follow someone they will show up here.
</div>
</q-card-section>
</q-card>
</div>

View File

@ -1,5 +1,5 @@
<template>
<q-page class="px-4 py-6 relative">
<q-page class="px-4 pt-6 relative">
<div class="text-xl">
Chat with
<span class="text-secondary">
@ -9,15 +9,13 @@
<q-separator class="my-6" />
<div class="flex-col justify-end absolute left-5 bottom-12 right-5">
<q-scroll-area
<div class="flex-col justify-end absolute left-5 bottom-5 right-5">
<q-infinite-scroll
ref="chatScroll"
:thumb-style="{
left: '102%',
backgroundColor: 'red',
width: '10px',
opacity: 0.35
}"
reverse
:disable="reachedEnd"
:offset="250"
@load="loadMore"
>
<div v-for="event in messages" :key="event.id">
<q-chat-message
@ -32,33 +30,30 @@
>
</q-chat-message>
</div>
</q-scroll-area>
<q-toolbar>
<q-toolbar-title>
<q-form @submit="submitMessage" @reset="text = ''">
<div class="flex w-full">
<q-input v-model="text" class="w-full" filled>
<template #append>
<q-btn
unelevated
class="mx-4"
label="Send"
type="submit"
color="secondary"
/>
</template>
</q-input>
</div>
</q-form>
</q-toolbar-title>
</q-toolbar>
</q-infinite-scroll>
<q-form @submit="submitMessage" @reset="text = ''">
<div class="flex w-full mt-4">
<q-input v-model="text" class="w-full" filled>
<template #append>
<q-btn
unelevated
class="mx-4"
label="Send"
type="submit"
color="secondary"
@click="submitMessage"
/>
</template>
</q-input>
</div>
</q-form>
</div>
</q-page>
</template>
<script>
import helpersMixin from '../utils/mixin'
import {dbGetMessages} from '../db'
import {dbGetMessages, onNewMessage} from '../db'
export default {
name: 'Chat',
@ -66,7 +61,9 @@ export default {
data() {
return {
listener: null,
messages: [],
reachedEnd: false,
text: ''
}
},
@ -82,16 +79,22 @@ export default {
this.restart()
},
async beforeUnmount() {
if (this.listener) this.listener.cancel()
},
methods: {
async restart() {
if (this.listener) this.listener.cancel()
this.messages = await dbGetMessages(this.$route.params.pubkey, 100)
this.listener = onNewMessage(this.$route.params.pubkey, event => {
this.messages.push(event)
this.scroll()
})
},
async scroll() {
const scrollArea = this.$refs.chatScroll
const scrollTarget = scrollArea.getScrollTarget()
const duration = 350
scrollArea.setScrollPosition(scrollTarget.scrollHeight, duration)
scroll() {
this.$refs.chatScroll.scroll({top: 10000, left: 0, behavior: 'smooth'})
},
async submitMessage() {
@ -101,7 +104,24 @@ export default {
})
this.text = ''
this.scroll()
},
async loadMore(_, done) {
if (this.messages.length === 0) {
this.reachedEnd = true
done()
return
}
let newMessages = await dbGetMessages(
100,
this.messages[0].created_at - 1
)
if (newMessages.length === 0) {
this.reachedEnd = true
}
this.messages = newMessages.concat(this.messages)
done()
}
}
}

View File

@ -41,18 +41,20 @@ export default {
methods: {
async loadMore(_, done) {
if (this.homeFeed.length > 0) {
let newNotes = await dbGetHomeFeedNotes(
50,
this.homeFeed[this.homeFeed.length - 1].created_at - 1
)
if (newNotes.length === 0) {
this.reachedEnd = true
}
this.homeFeed = this.homeFeed.concat(newNotes)
if (this.messages.length === 0) {
this.reachedEnd = true
done()
return
}
let newNotes = await dbGetHomeFeedNotes(
50,
this.homeFeed[this.homeFeed.length - 1].created_at - 1
)
if (newNotes.length === 0) {
this.reachedEnd = true
}
this.homeFeed = this.homeFeed.concat(newNotes)
done()
}
}

View File

@ -2,9 +2,7 @@
<q-page class="px-4 py-6">
<div class="text-xl">Encrypted Chat</div>
<q-separator class="my-6" />
<q-list>
<q-list v-if="$store.state.following.length" class="my-4">
<q-item
v-for="followedKey in $store.state.following"
:key="followedKey"
@ -18,11 +16,15 @@
</q-avatar>
</q-item-section>
<q-item-section>{{
$store.getters.displayName(followedKey)
}}</q-item-section>
<q-item-section>
{{ $store.getters.displayName(followedKey) }}
</q-item-section>
</q-item>
</q-list>
<div v-else class="m-8 text-base">
<p>Start following some people to initiate chats.</p>
</div>
</q-page>
</template>

View File

@ -5,7 +5,7 @@
</div>
<div class="flex justify-left items-center mt-4">
<q-avatar size="64px" round>
<q-avatar round>
<img round :src="$store.getters.avatar($route.params.pubkey)" />
</q-avatar>
<div class="ml-4">

View File

@ -1971,6 +1971,37 @@ braces@^3.0.1, braces@~3.0.2:
dependencies:
fill-range "^7.0.1"
browserify-aes@^1.0.4:
version "1.2.0"
resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==
dependencies:
buffer-xor "^1.0.3"
cipher-base "^1.0.0"
create-hash "^1.1.0"
evp_bytestokey "^1.0.3"
inherits "^2.0.1"
safe-buffer "^5.0.1"
browserify-cipher@>=1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0"
integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==
dependencies:
browserify-aes "^1.0.4"
browserify-des "^1.0.0"
evp_bytestokey "^1.0.0"
browserify-des@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c"
integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==
dependencies:
cipher-base "^1.0.1"
des.js "^1.0.0"
inherits "^2.0.1"
safe-buffer "^5.1.2"
browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.0, browserslist@^4.16.6, browserslist@^4.17.5, browserslist@^4.18.1:
version "4.18.1"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.18.1.tgz#60d3920f25b6860eb917c6c7b185576f4d8b017f"
@ -2004,6 +2035,19 @@ buffer-indexof@^1.0.0:
resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c"
integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==
buffer-xor@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=
buffer@>=5:
version "6.0.3"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
dependencies:
base64-js "^1.3.1"
ieee754 "^1.2.1"
buffer@^5.5.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
@ -2012,14 +2056,6 @@ buffer@^5.5.0:
base64-js "^1.3.1"
ieee754 "^1.1.13"
buffer@^6.0.3:
version "6.0.3"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
dependencies:
base64-js "^1.3.1"
ieee754 "^1.2.1"
bufferutil@^4.0.1:
version "4.0.5"
resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.5.tgz#da9ea8166911cc276bf677b8aed2d02d31f59028"
@ -2138,7 +2174,7 @@ ci-info@3.3.0:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2"
integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==
cipher-base@^1.0.1, cipher-base@^1.0.3:
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==
@ -2411,7 +2447,7 @@ create-hash@^1.1.0, create-hash@^1.1.2:
ripemd160 "^2.0.1"
sha.js "^2.4.0"
create-hmac@^1.1.4, create-hmac@^1.1.7:
create-hmac@>=1, create-hmac@^1.1.4:
version "1.1.7"
resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff"
integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==
@ -2432,11 +2468,6 @@ cross-spawn@7.0.3, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
crypto@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/crypto/-/crypto-1.0.1.tgz#2af1b7cad8175d24c8a1b0778255794a21803037"
integrity sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==
css-declaration-sorter@^6.0.3:
version "6.1.3"
resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.1.3.tgz#e9852e4cf940ba79f509d9425b137d1f94438dc2"
@ -2677,6 +2708,14 @@ depd@~1.1.2:
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
des.js@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843"
integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==
dependencies:
inherits "^2.0.1"
minimalistic-assert "^1.0.0"
destroy@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
@ -3115,6 +3154,14 @@ events@^3.2.0:
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==
dependencies:
md5.js "^1.3.4"
safe-buffer "^5.1.1"
execa@^5.0.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
@ -4679,17 +4726,18 @@ normalize-url@^6.0.1:
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
nostr-tools@^0.10.3:
version "0.10.3"
resolved "https://registry.yarnpkg.com/nostr-tools/-/nostr-tools-0.10.3.tgz#1b855b5a5002adc56cfcd9db25846351e48cbb5c"
integrity sha512-xXO2gYFTTMfHYZYtsJJdn92PoEd++B/+nbcDGtl3w+IjNmv06uLLmbg5f3p3BVurXuXMgwDv7kJ91AS51IVkoA==
nostr-tools@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/nostr-tools/-/nostr-tools-0.11.0.tgz#245734848d3ee07f43002dde0a2cb0dedfffcfbd"
integrity sha512-m6xfrt9T3qPVteALE6Q4O/P0EHENWe0IKxKaojrPprhMiMV4UaZvUf9dbT1cy/lTJpjgcfSe+sjZFuOxMmR8mw==
dependencies:
"@noble/secp256k1" "^1.3.0"
bip39 "^3.0.4"
buffer "^6.0.3"
create-hmac "^1.1.7"
browserify-cipher ">=1"
buffer ">=5"
create-hmac ">=1"
dns-packet "^5.2.4"
randombytes "^2.1.0"
randombytes ">=2"
websocket-polyfill "^0.0.3"
npm-run-path@^4.0.1:
@ -5596,7 +5644,7 @@ quick-lru@^5.1.1:
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
randombytes@^2.0.1, randombytes@^2.1.0:
randombytes@>=2, randombytes@^2.0.1, randombytes@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
@ -5859,7 +5907,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0:
safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==