mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-18 19:23:40 +00:00
Add filter summary to feeds
This commit is contained in:
parent
a40b9268f6
commit
d65aa309db
@ -2,7 +2,10 @@
|
||||
|
||||
# 0.2.31
|
||||
|
||||
- [x] Added the ability to view and write reviews on relays, with ratings
|
||||
- [x] Add the ability to view and write reviews on relays, with ratings
|
||||
- [x] Add support for parsing and displaying lnurl invoices
|
||||
- [x] Add advanced search to feeds with a summary of the filter applied
|
||||
- [x] Improve url parsing
|
||||
|
||||
# 0.2.30
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
- [ ] Fix unauthenticated experience. Going to an npub just spins
|
||||
- [ ] Convert app store to nip 89
|
||||
- [ ] Put search icon in header or hover button, open in modal
|
||||
- [ ] Advanced search
|
||||
|
||||
# Core
|
||||
|
||||
|
@ -160,6 +160,7 @@ class PublishableEvent {
|
||||
}
|
||||
async publish(relays, onProgress = null, verb = "EVENT") {
|
||||
const event = await this.getSignedEvent()
|
||||
// console.log(event); return
|
||||
const promise = pool.publish({relays, event, onProgress, verb})
|
||||
|
||||
// Copy the event since loki mutates it to add metadata
|
||||
|
@ -10,6 +10,7 @@
|
||||
import Spinner from "src/partials/Spinner.svelte"
|
||||
import Modal from "src/partials/Modal.svelte"
|
||||
import Content from "src/partials/Content.svelte"
|
||||
import FilterSummary from "src/app/shared/FilterSummary.svelte"
|
||||
import FeedAdvanced from "src/app/shared/FeedAdvanced.svelte"
|
||||
import RelayFeed from "src/app/shared/RelayFeed.svelte"
|
||||
import Note from "src/app/shared/Note.svelte"
|
||||
@ -36,6 +37,7 @@
|
||||
|
||||
$: searchNotes = debounce(300, fuzzy(notes, {keys: ["content"]}))
|
||||
$: filteredNotes = search ? searchNotes(search) : notes
|
||||
$: mergedFilter = mergeFilter(filter, overrides)
|
||||
|
||||
const since = now()
|
||||
const maxNotes = 100
|
||||
@ -121,14 +123,12 @@
|
||||
// If we have a search term we need to use only relays that support search
|
||||
const getRelays = () => (overrides?.search ? [{url: "wss://relay.nostr.band"}] : relays)
|
||||
|
||||
const getFilter = () => mergeFilter(filter, {since, ...overrides})
|
||||
|
||||
const loadMore = async () => {
|
||||
const _key = key
|
||||
|
||||
// Wait for this page to load before trying again
|
||||
await cursor.loadPage({
|
||||
filter: getFilter(),
|
||||
filter: mergedFilter,
|
||||
onChunk: chunk => {
|
||||
// Stack promises to avoid too many concurrent subscriptions
|
||||
p = p.then(() => key === _key && onChunk(chunk))
|
||||
@ -157,7 +157,7 @@
|
||||
if (!filter.until) {
|
||||
sub = network.listen({
|
||||
relays: getRelays(),
|
||||
filter: getFilter(),
|
||||
filter: mergeFilter(mergedFilter, {since}),
|
||||
onChunk: chunk => {
|
||||
p = p.then(() => _key === key && onChunk(chunk))
|
||||
},
|
||||
@ -192,7 +192,10 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<FeedAdvanced onChange={start} hide={Object.keys(filter)} />
|
||||
<div class="flex justify-between gap-4">
|
||||
<FilterSummary filter={mergedFilter} />
|
||||
<FeedAdvanced onChange={start} hide={Object.keys(filter)} />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
{#each filteredNotes as note (note.id)}
|
||||
|
@ -55,7 +55,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex justify-end gap-2" in:fly={{y: 20}}>
|
||||
<div class="flex justify-end gap-2 p-2" in:fly={{y: 20}}>
|
||||
<i
|
||||
class="fa fa-search cursor-pointer"
|
||||
on:click={() => {
|
||||
|
56
src/app/shared/FilterSummary.svelte
Normal file
56
src/app/shared/FilterSummary.svelte
Normal file
@ -0,0 +1,56 @@
|
||||
<script lang="ts">
|
||||
import {formatTimestampAsDate} from "src/util/misc"
|
||||
import {displayPerson} from "src/util/nostr"
|
||||
import Chip from "src/partials/Chip.svelte"
|
||||
import {getPersonWithFallback} from "src/agent/db"
|
||||
|
||||
export let filter
|
||||
|
||||
const displayPeople = pubkeys =>
|
||||
pubkeys.length === 1
|
||||
? displayPerson(getPersonWithFallback(pubkeys[0]))
|
||||
: `${pubkeys.length} people`
|
||||
|
||||
const displayTopics = topics => (topics.length === 1 ? topics[0] : `${topics.length} topics`)
|
||||
|
||||
const getFilterParts = f => {
|
||||
const parts = []
|
||||
|
||||
if (filter.since && filter.until) {
|
||||
const since = formatTimestampAsDate(filter.since)
|
||||
const until = formatTimestampAsDate(filter.until)
|
||||
|
||||
parts.push(`Between ${since} and ${until}`)
|
||||
} else if (filter.since) {
|
||||
parts.push(`After ${formatTimestampAsDate(filter.since)}`)
|
||||
} else if (filter.until) {
|
||||
parts.push(`Before ${formatTimestampAsDate(filter.until)}`)
|
||||
}
|
||||
|
||||
if (filter.authors?.length > 0) {
|
||||
parts.push(`By ${displayPeople(filter.authors)}`)
|
||||
}
|
||||
|
||||
if (filter["#p"]?.length > 0) {
|
||||
parts.push(`Mentioning ${displayPeople(filter["#p"])}`)
|
||||
}
|
||||
|
||||
if (filter["#t"]?.length > 0) {
|
||||
parts.push(`Related to ${displayTopics(filter["#t"])}`)
|
||||
}
|
||||
|
||||
if (filter.search) {
|
||||
parts.push(`Matching ${filter.search}`)
|
||||
}
|
||||
|
||||
return parts
|
||||
}
|
||||
|
||||
$: parts = getFilterParts(filter)
|
||||
</script>
|
||||
|
||||
<div>
|
||||
{#each parts as part}
|
||||
<Chip class="mr-2 mb-2">{part}</Chip>
|
||||
{/each}
|
||||
</div>
|
@ -130,7 +130,7 @@
|
||||
</div>
|
||||
<div on:click|stopPropagation>
|
||||
{#each data.mentions as p}
|
||||
<Chip class="mr-1 mb-1" theme="dark" on:click={() => removeMention(p)}>
|
||||
<Chip class="mr-1 mb-1" theme="dark" onClick={() => removeMention(p)}>
|
||||
{displayPerson(getPersonWithFallback(p))}
|
||||
</Chip>
|
||||
{:else}
|
||||
|
@ -19,7 +19,6 @@
|
||||
["https://nostrplebs.com", "NostrPlebs", "Get verified at nostrplebs.com."],
|
||||
["https://nadar.tigerville.no", "Nadar", "Find out what relays know about your post."],
|
||||
["https://pinstr.app", "Pinstr", "Create and manage collections of notes."],
|
||||
["https://advancednostrsearch.vercel.app", "Advanced Search", "Find what you're looking for."],
|
||||
]
|
||||
|
||||
document.title = "Apps"
|
||||
|
@ -46,7 +46,7 @@
|
||||
relays = urls.length > 0 ? urls.map(objOf("url")) : sampleRelays(getUserReadRelays())
|
||||
}
|
||||
|
||||
filter = [{...filter, kinds: [1]}]
|
||||
filter = {...filter, kinds: [1, 1985]}
|
||||
}
|
||||
|
||||
const setActiveTab = tab => {
|
||||
|
@ -1,7 +1,8 @@
|
||||
<script lang="ts">
|
||||
import cx from "classnames"
|
||||
|
||||
export let theme
|
||||
export let theme = "dark"
|
||||
export let onClick = null
|
||||
|
||||
const className = cx($$props.class, "inline-block rounded-full border border-solid py-1 px-2", {
|
||||
"border-gray-1": theme === "dark",
|
||||
@ -11,7 +12,9 @@
|
||||
|
||||
<div class={className}>
|
||||
<div class="flex items-center gap-2">
|
||||
<i class="fa fa-times cursor-pointer" on:click|preventDefault />
|
||||
{#if onClick}
|
||||
<i class="fa fa-times cursor-pointer" on:click|preventDefault={onClick} />
|
||||
{/if}
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -59,7 +59,7 @@
|
||||
|
||||
<div class="text-sm">
|
||||
{#each value as item}
|
||||
<Chip class="mr-1 mb-1" theme="dark" on:click={() => remove(item)}>
|
||||
<Chip class="mr-1 mb-1" theme="dark" onClick={() => remove(item)}>
|
||||
<slot name="item" {item}>
|
||||
{item}
|
||||
</slot>
|
||||
|
Loading…
Reference in New Issue
Block a user