mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-30 00:41:12 +00:00
Move rooms/messages over to localforage
This commit is contained in:
parent
387649ee4c
commit
0cbc9874db
@ -54,12 +54,16 @@ If you like Coracle and want to support its development, you can donate sats via
|
|||||||
|
|
||||||
# Maintenance
|
# Maintenance
|
||||||
|
|
||||||
|
- [ ] Stop using until to paginate, we skip a ton of stuff. Or use until per relay?
|
||||||
|
- Or just stop doing loading and listen
|
||||||
|
- [ ] If the latest message in a dm was the user, don't show notification
|
||||||
- [ ] Normalize relay urls (lowercase, strip trailing slash)
|
- [ ] Normalize relay urls (lowercase, strip trailing slash)
|
||||||
- [ ] Use nip 56 for reporting
|
- [ ] Use nip 56 for reporting
|
||||||
- https://github.com/nostr-protocol/nips/pull/205#issuecomment-1419234230
|
- https://github.com/nostr-protocol/nips/pull/205#issuecomment-1419234230
|
||||||
- [ ] Change network tab to list relays the user is connected to
|
- [ ] Change network tab to list relays the user is connected to
|
||||||
- [ ] Sync mentions box and in-reply mentions
|
- [ ] Sync mentions box and in-reply mentions
|
||||||
- [ ] Channels
|
- [ ] Channels
|
||||||
|
- [ ] Damus has chats divided into DMs and requests
|
||||||
- [ ] Ability to leave/mute DM conversation
|
- [ ] Ability to leave/mute DM conversation
|
||||||
- [ ] Add petnames for channels
|
- [ ] Add petnames for channels
|
||||||
- [ ] Add notifications for chat messages
|
- [ ] Add notifications for chat messages
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Dexie, {liveQuery} from 'dexie'
|
import Dexie, {liveQuery} from 'dexie'
|
||||||
import {pick, isEmpty} from 'ramda'
|
import {pick, isEmpty} from 'ramda'
|
||||||
import {nip05} from 'nostr-tools'
|
import {nip05} from 'nostr-tools'
|
||||||
import {noop, ensurePlural, switcherFn} from 'hurdak/lib/hurdak'
|
import {noop, createMap, ensurePlural, switcherFn} from 'hurdak/lib/hurdak'
|
||||||
import {now} from 'src/util/misc'
|
import {now} from 'src/util/misc'
|
||||||
import {personKinds, Tags, roomAttrs, isRelay} from 'src/util/nostr'
|
import {personKinds, Tags, roomAttrs, isRelay} from 'src/util/nostr'
|
||||||
import database from 'src/agent/database'
|
import database from 'src/agent/database'
|
||||||
@ -19,8 +19,6 @@ export const db = new Dexie('agent/data/db')
|
|||||||
db.version(13).stores({
|
db.version(13).stores({
|
||||||
relays: '++url, name',
|
relays: '++url, name',
|
||||||
alerts: '++id, created_at',
|
alerts: '++id, created_at',
|
||||||
messages: '++id, pubkey, recipient',
|
|
||||||
rooms: '++id, joined',
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export const updatePeople = async updates => {
|
export const updatePeople = async updates => {
|
||||||
@ -132,7 +130,7 @@ const processRoomEvents = async events => {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const room = await db.table('rooms').get(roomId)
|
const room = await database.rooms.get(roomId)
|
||||||
|
|
||||||
// Merge edits but don't let old ones override new ones
|
// Merge edits but don't let old ones override new ones
|
||||||
if (room?.edited_at >= e.created_at) {
|
if (room?.edited_at >= e.created_at) {
|
||||||
@ -156,7 +154,7 @@ const processRoomEvents = async events => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isEmpty(updates)) {
|
if (!isEmpty(updates)) {
|
||||||
await db.table('rooms').bulkPut(Object.values(updates))
|
await database.rooms.bulkPut(updates)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,8 +163,9 @@ const processMessages = async events => {
|
|||||||
.filter(e => e.kind === 4)
|
.filter(e => e.kind === 4)
|
||||||
.map(e => ({...e, recipient: Tags.from(e).type("p").values().first()}))
|
.map(e => ({...e, recipient: Tags.from(e).type("p").values().first()}))
|
||||||
|
|
||||||
|
|
||||||
if (messages.length > 0) {
|
if (messages.length > 0) {
|
||||||
await db.table('messages').bulkPut(messages)
|
await database.messages.bulkPut(createMap('id', messages))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import {debounce} from 'throttle-debounce'
|
||||||
import {is, prop, without} from 'ramda'
|
import {is, prop, without} from 'ramda'
|
||||||
import {writable} from 'svelte/store'
|
import {writable} from 'svelte/store'
|
||||||
import {switcherFn, ensurePlural, first} from 'hurdak/lib/hurdak'
|
import {switcherFn, ensurePlural, first} from 'hurdak/lib/hurdak'
|
||||||
@ -14,7 +15,8 @@ type Table = {
|
|||||||
name: string
|
name: string
|
||||||
subscribe: (subscription: (value: any) => void) => (() => void)
|
subscribe: (subscription: (value: any) => void) => (() => void)
|
||||||
bulkPut: (data: object) => void
|
bulkPut: (data: object) => void
|
||||||
all: (where: object) => Promise<any>
|
bulkPatch: (data: object) => void
|
||||||
|
all: (where?: object) => Promise<any>
|
||||||
get: (key: string) => any
|
get: (key: string) => any
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +31,11 @@ class Channel {
|
|||||||
onMessage: (e: MessageEvent) => void
|
onMessage: (e: MessageEvent) => void
|
||||||
constructor({onMessage}) {
|
constructor({onMessage}) {
|
||||||
this.id = Math.random().toString().slice(2)
|
this.id = Math.random().toString().slice(2)
|
||||||
this.onMessage = e => onMessage(e.data as Message)
|
this.onMessage = e => {
|
||||||
|
if (e.data.channel === this.id) {
|
||||||
|
onMessage(e.data as Message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
worker.addEventListener('message', this.onMessage)
|
worker.addEventListener('message', this.onMessage)
|
||||||
}
|
}
|
||||||
@ -70,9 +76,10 @@ const callLocalforage = async (storeName, method, ...args) => {
|
|||||||
const getItem = (storeName, ...args) => callLocalforage(storeName, 'getItem', ...args)
|
const getItem = (storeName, ...args) => callLocalforage(storeName, 'getItem', ...args)
|
||||||
const setItem = (storeName, ...args) => callLocalforage(storeName, 'setItem', ...args)
|
const setItem = (storeName, ...args) => callLocalforage(storeName, 'setItem', ...args)
|
||||||
const removeItem = (storeName, ...args) => callLocalforage(storeName, 'removeItem', ...args)
|
const removeItem = (storeName, ...args) => callLocalforage(storeName, 'removeItem', ...args)
|
||||||
const length = (storeName) => callLocalforage(storeName, 'length')
|
|
||||||
const clear = (storeName) => callLocalforage(storeName, 'clear')
|
const length = storeName => callLocalforage(storeName, 'length')
|
||||||
const keys = (storeName) => callLocalforage(storeName, 'keys')
|
const clear = storeName => callLocalforage(storeName, 'clear')
|
||||||
|
const keys = storeName => callLocalforage(storeName, 'keys')
|
||||||
|
|
||||||
const iterate = (storeName, where = {}) => ({
|
const iterate = (storeName, where = {}) => ({
|
||||||
[Symbol.asyncIterator]() {
|
[Symbol.asyncIterator]() {
|
||||||
@ -90,6 +97,9 @@ const iterate = (storeName, where = {}) => ({
|
|||||||
promise.resolve()
|
promise.resolve()
|
||||||
channel.close()
|
channel.close()
|
||||||
},
|
},
|
||||||
|
default: () => {
|
||||||
|
throw new Error(`Invalid topic ${m.topic}`)
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -147,7 +157,11 @@ const defineTable = (name: string): Table => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bulkPut = newData => {
|
const bulkPut = (newData: Record<string, object>): void => {
|
||||||
|
if (is(Array, newData)) {
|
||||||
|
throw new Error(`Updates must be an object, not an array`)
|
||||||
|
}
|
||||||
|
|
||||||
setAndNotify({...data, ...newData})
|
setAndNotify({...data, ...newData})
|
||||||
|
|
||||||
// Sync to storage, keeping updates in order
|
// Sync to storage, keeping updates in order
|
||||||
@ -161,6 +175,19 @@ const defineTable = (name: string): Table => {
|
|||||||
}) as Promise<void>
|
}) as Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bulkPatch = (updates: Record<string, object>): void => {
|
||||||
|
if (is(Array, updates)) {
|
||||||
|
throw new Error(`Updates must be an object, not an array`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const newData = {}
|
||||||
|
for (const [k, v] of Object.entries(updates)) {
|
||||||
|
newData[k] = {...data[k], ...v}
|
||||||
|
}
|
||||||
|
|
||||||
|
bulkPut(newData)
|
||||||
|
}
|
||||||
|
|
||||||
const all = (where = {}) => asyncIterableToArray(iterate(name, where), prop('v'))
|
const all = (where = {}) => asyncIterableToArray(iterate(name, where), prop('v'))
|
||||||
const one = (where = {}) => first(all(where))
|
const one = (where = {}) => first(all(where))
|
||||||
const get = k => data[k]
|
const get = k => data[k]
|
||||||
@ -175,12 +202,14 @@ const defineTable = (name: string): Table => {
|
|||||||
setAndNotify(initialData)
|
setAndNotify(initialData)
|
||||||
})()
|
})()
|
||||||
|
|
||||||
registry[name] = {name, subscribe, bulkPut, all, one, get}
|
registry[name] = {name, subscribe, bulkPut, bulkPatch, all, one, get}
|
||||||
|
|
||||||
return registry[name]
|
return registry[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
const people = defineTable('people')
|
const people = defineTable('people')
|
||||||
|
const rooms = defineTable('rooms')
|
||||||
|
const messages = defineTable('messages')
|
||||||
|
|
||||||
// Helper to allow us to listen to changes of any given table
|
// Helper to allow us to listen to changes of any given table
|
||||||
|
|
||||||
@ -218,10 +247,13 @@ const watch = (names, f) => {
|
|||||||
store.set(initialValue)
|
store.set(initialValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Debounce refresh so we don't get UI lag
|
||||||
|
const refresh = debounce(300, async () => store.set(await f(...tables)))
|
||||||
|
|
||||||
// Listen for changes
|
// Listen for changes
|
||||||
listener.subscribe(async name => {
|
listener.subscribe(name => {
|
||||||
if (names.includes(name)) {
|
if (names.includes(name)) {
|
||||||
store.set(await f(...tables))
|
refresh()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -232,7 +264,9 @@ const watch = (names, f) => {
|
|||||||
|
|
||||||
const getPersonWithFallback = pubkey => people.get(pubkey) || {pubkey}
|
const getPersonWithFallback = pubkey => people.get(pubkey) || {pubkey}
|
||||||
|
|
||||||
|
const clearAll = () => Promise.all(Object.keys(registry).map(clear))
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getItem, setItem, removeItem, length, clear, keys, iterate,
|
getItem, setItem, removeItem, length, clear, keys, iterate,
|
||||||
watch, getPersonWithFallback, people,
|
watch, getPersonWithFallback, clearAll, people, rooms, messages,
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {pluck, reject} from 'ramda'
|
import {pluck, reject} from 'ramda'
|
||||||
import {get} from 'svelte/store'
|
import {get} from 'svelte/store'
|
||||||
import {synced, now, timedelta, batch} from 'src/util/misc'
|
import {synced, now, timedelta, batch} from 'src/util/misc'
|
||||||
import {listen as _listen, db, user} from 'src/agent'
|
import {listen as _listen, database, user} from 'src/agent'
|
||||||
import loaders from 'src/app/loaders'
|
import loaders from 'src/app/loaders'
|
||||||
|
|
||||||
let listener
|
let listener
|
||||||
@ -23,10 +23,7 @@ const listen = async (relays, pubkey) => {
|
|||||||
const $user = get(user)
|
const $user = get(user)
|
||||||
|
|
||||||
// Reload annotated messages, don't alert about messages to self
|
// Reload annotated messages, don't alert about messages to self
|
||||||
const messages = reject(
|
const messages = reject(e => e.pubkey === e.recipient, await database.messages.all())
|
||||||
e => e.pubkey === e.recipient,
|
|
||||||
await db.table('messages').toArray()
|
|
||||||
)
|
|
||||||
|
|
||||||
if (messages.length > 0) {
|
if (messages.length > 0) {
|
||||||
await loaders.loadPeople(relays, pluck('pubkey', messages))
|
await loaders.loadPeople(relays, pluck('pubkey', messages))
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<script>
|
<script>
|
||||||
import {without, assoc, uniq, sortBy} from 'ramda'
|
import {without, uniq, assoc, sortBy} from 'ramda'
|
||||||
import {onMount} from "svelte"
|
import {onMount} from "svelte"
|
||||||
import {nip19} from 'nostr-tools'
|
import {nip19} from 'nostr-tools'
|
||||||
import {navigate} from "svelte-routing"
|
import {navigate} from "svelte-routing"
|
||||||
import {fuzzy} from "src/util/misc"
|
import {fuzzy} from "src/util/misc"
|
||||||
import {getRelays, user, lq, database, listen, db} from 'src/agent'
|
import {getRelays, user, database, listen} from 'src/agent'
|
||||||
import {modal, messages} from 'src/app'
|
import {modal, messages} from 'src/app'
|
||||||
import loaders from 'src/app/loaders'
|
import loaders from 'src/app/loaders'
|
||||||
import Room from "src/partials/Room.svelte"
|
import Room from "src/partials/Room.svelte"
|
||||||
@ -18,9 +18,9 @@
|
|||||||
|
|
||||||
const {mostRecentByPubkey} = messages
|
const {mostRecentByPubkey} = messages
|
||||||
|
|
||||||
const rooms = lq(async () => {
|
const rooms = database.watch(['rooms', 'messages'], async () => {
|
||||||
const rooms = await db.table('rooms').where('joined').equals(1).toArray()
|
const rooms = await database.rooms.all({joined: 1})
|
||||||
const messages = await db.table('messages').toArray()
|
const messages = await database.messages.all()
|
||||||
const pubkeys = without([$user.pubkey], uniq(messages.flatMap(m => [m.pubkey, m.recipient])))
|
const pubkeys = without([$user.pubkey], uniq(messages.flatMap(m => [m.pubkey, m.recipient])))
|
||||||
|
|
||||||
await loaders.loadPeople(getRelays(), pubkeys)
|
await loaders.loadPeople(getRelays(), pubkeys)
|
||||||
@ -30,8 +30,8 @@
|
|||||||
.concat(rooms.map(room => ({type: 'note', ...room})))
|
.concat(rooms.map(room => ({type: 'note', ...room})))
|
||||||
})
|
})
|
||||||
|
|
||||||
const search = lq(async () => {
|
const search = database.watch('rooms', async () => {
|
||||||
const rooms = await db.table('rooms').where('joined').equals(0).toArray()
|
const rooms = await database.rooms.all({joined: 0})
|
||||||
|
|
||||||
roomsCount = rooms.length
|
roomsCount = rooms.length
|
||||||
|
|
||||||
@ -49,11 +49,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const joinRoom = id => {
|
const joinRoom = id => {
|
||||||
db.table('rooms').where('id').equals(id).modify({joined: 1})
|
database.rooms.bulkPatch({id, joined: 1})
|
||||||
}
|
}
|
||||||
|
|
||||||
const leaveRoom = id => {
|
const leaveRoom = id => {
|
||||||
db.table('rooms').where('id').equals(id).modify({joined: 0})
|
database.rooms.bulkPatch({id, joined: 0})
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
import {nip19} from 'nostr-tools'
|
import {nip19} from 'nostr-tools'
|
||||||
import {now, batch} from 'src/util/misc'
|
import {now, batch} from 'src/util/misc'
|
||||||
import Channel from 'src/partials/Channel.svelte'
|
import Channel from 'src/partials/Channel.svelte'
|
||||||
import {lq, getRelays, user, db, listen, load} from 'src/agent'
|
import {getRelays, user, database, listen, load} from 'src/agent'
|
||||||
import {modal} from 'src/app'
|
import {modal} from 'src/app'
|
||||||
import loaders from 'src/app/loaders'
|
import loaders from 'src/app/loaders'
|
||||||
import cmd from 'src/app/cmd'
|
import cmd from 'src/app/cmd'
|
||||||
@ -11,7 +11,7 @@
|
|||||||
export let entity
|
export let entity
|
||||||
|
|
||||||
let {data: roomId} = nip19.decode(entity) as {data: string}
|
let {data: roomId} = nip19.decode(entity) as {data: string}
|
||||||
let room = lq(() => db.table('rooms').where('id').equals(roomId).first())
|
let room = database.watch('rooms', rooms => rooms.get(roomId))
|
||||||
|
|
||||||
const getRoomRelays = $room => {
|
const getRoomRelays = $room => {
|
||||||
let relays = getRelays()
|
let relays = getRelays()
|
||||||
@ -24,9 +24,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const listenForMessages = async cb => {
|
const listenForMessages = async cb => {
|
||||||
// Make sure we have our room so we can calculate relays
|
const relays = getRoomRelays(database.rooms.get(roomId))
|
||||||
const $room = await db.table('rooms').where('id').equals(roomId).first()
|
|
||||||
const relays = getRoomRelays($room)
|
|
||||||
|
|
||||||
return listen(
|
return listen(
|
||||||
relays,
|
relays,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import {fly} from 'svelte/transition'
|
import {fly} from 'svelte/transition'
|
||||||
import Anchor from 'src/partials/Anchor.svelte'
|
import Anchor from 'src/partials/Anchor.svelte'
|
||||||
import Content from "src/partials/Content.svelte"
|
import Content from "src/partials/Content.svelte"
|
||||||
import {db} from 'src/agent'
|
import {db, database} from 'src/agent'
|
||||||
|
|
||||||
let confirmed = false
|
let confirmed = false
|
||||||
|
|
||||||
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
localStorage.clear()
|
localStorage.clear()
|
||||||
|
|
||||||
|
await database.clearAll()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await db.delete()
|
await db.delete()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
import {personKinds} from 'src/util/nostr'
|
import {personKinds} from 'src/util/nostr'
|
||||||
import {batch, now} from 'src/util/misc'
|
import {batch, now} from 'src/util/misc'
|
||||||
import Channel from 'src/partials/Channel.svelte'
|
import Channel from 'src/partials/Channel.svelte'
|
||||||
import {database, getRelays, user, db, listen, keys} from 'src/agent'
|
import {database, getRelays, user, listen, keys} from 'src/agent'
|
||||||
import {messages} from 'src/app'
|
import {messages} from 'src/app'
|
||||||
import {routes} from 'src/app/ui'
|
import {routes} from 'src/app/ui'
|
||||||
import cmd from 'src/app/cmd'
|
import cmd from 'src/app/cmd'
|
||||||
@ -36,15 +36,15 @@
|
|||||||
batch(300, async events => {
|
batch(300, async events => {
|
||||||
// Reload from db since we annotate messages there
|
// Reload from db since we annotate messages there
|
||||||
const messageIds = pluck('id', events.filter(e => e.kind === 4))
|
const messageIds = pluck('id', events.filter(e => e.kind === 4))
|
||||||
const messages = await db.table('messages').where('id').anyOf(messageIds).toArray()
|
const messages = await database.messages.all({id: messageIds})
|
||||||
|
|
||||||
cb(await decryptMessages(messages))
|
cb(await decryptMessages(messages))
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
const loadMessages = async ({until, limit}) => {
|
const loadMessages = async ({until, limit}) => {
|
||||||
const fromThem = await db.table('messages').where('pubkey').equals(pubkey).toArray()
|
const fromThem = await database.messages.all({pubkey})
|
||||||
const toThem = await db.table('messages').where('recipient').equals(pubkey).toArray()
|
const toThem = await database.messages.all({recipient: pubkey})
|
||||||
const events = fromThem.concat(toThem).filter(e => e.created_at < until)
|
const events = fromThem.concat(toThem).filter(e => e.created_at < until)
|
||||||
const messages = sortBy(e => -e.created_at, events).slice(0, limit)
|
const messages = sortBy(e => -e.created_at, events).slice(0, limit)
|
||||||
|
|
||||||
|
@ -105,8 +105,8 @@
|
|||||||
<i slot="before" class="fa-solid fa-search" />
|
<i slot="before" class="fa-solid fa-search" />
|
||||||
</Input>
|
</Input>
|
||||||
{/if}
|
{/if}
|
||||||
{#each (search(q) || []).slice(0, 50) as relay, i (relay.url)}
|
{#each (search(q) || []).slice(0, 50) as relay (relay.url)}
|
||||||
<RelayCard {relay} {i} />
|
<RelayCard {relay} />
|
||||||
{/each}
|
{/each}
|
||||||
<small class="text-center">
|
<small class="text-center">
|
||||||
Showing {Math.min(($knownRelays || []).length - relays.length, 50)}
|
Showing {Math.min(($knownRelays || []).length - relays.length, 50)}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
import Content from "src/partials/Content.svelte"
|
import Content from "src/partials/Content.svelte"
|
||||||
import Textarea from "src/partials/Textarea.svelte"
|
import Textarea from "src/partials/Textarea.svelte"
|
||||||
import Button from "src/partials/Button.svelte"
|
import Button from "src/partials/Button.svelte"
|
||||||
import {getRelays, db} from 'src/agent'
|
import {getRelays, database} from 'src/agent'
|
||||||
import {toast, modal} from "src/app"
|
import {toast, modal} from "src/app"
|
||||||
import cmd from "src/app/cmd"
|
import cmd from "src/app/cmd"
|
||||||
|
|
||||||
@ -34,11 +34,11 @@
|
|||||||
if (!room.name) {
|
if (!room.name) {
|
||||||
toast.show("error", "Please enter a name for your room.")
|
toast.show("error", "Please enter a name for your room.")
|
||||||
} else {
|
} else {
|
||||||
room.id
|
const event = room.id
|
||||||
? await cmd.updateRoom(getRelays(), room)
|
? await cmd.updateRoom(getRelays(), room)
|
||||||
: await cmd.createRoom(getRelays(), room)
|
: await cmd.createRoom(getRelays(), room)
|
||||||
|
|
||||||
await db.table('rooms').where('id').equals(room.id).modify({joined: 1})
|
await database.rooms.bulkPatch({id: room.id || event.id, joined: 1})
|
||||||
|
|
||||||
toast.show("info", `Your room has been ${room.id ? 'updated' : 'created'}!`)
|
toast.show("info", `Your room has been ${room.id ? 'updated' : 'created'}!`)
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import lf from 'localforage'
|
import lf from 'localforage'
|
||||||
import {complement, equals, isNil, pipe, prop, identity, allPass} from 'ramda'
|
import {is, complement, equals, isNil, pipe, prop, identity, allPass} from 'ramda'
|
||||||
import {switcherFn} from 'hurdak/lib/hurdak'
|
import {switcherFn} from 'hurdak/lib/hurdak'
|
||||||
|
|
||||||
const stores = {}
|
const stores = {}
|
||||||
@ -35,9 +35,11 @@ addEventListener('message', async ({data: {topic, payload, channel}}) => {
|
|||||||
modifier = complement
|
modifier = complement
|
||||||
}
|
}
|
||||||
|
|
||||||
if (operator === 'eq') {
|
if (operator === 'eq' && is(Array, value)) {
|
||||||
|
test = v => value.includes(v)
|
||||||
|
} else if (operator === 'eq') {
|
||||||
test = equals(value)
|
test = equals(value)
|
||||||
} if (operator === 'nil') {
|
} else if (operator === 'nil') {
|
||||||
test = isNil
|
test = isNil
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Invalid operator ${operator}`)
|
throw new Error(`Invalid operator ${operator}`)
|
||||||
|
Loading…
Reference in New Issue
Block a user