Add user settings
This commit is contained in:
parent
defb16aa1c
commit
b4baef215a
4 changed files with 70 additions and 8 deletions
|
|
@ -45,7 +45,7 @@ import {
|
||||||
nip44EncryptToSelf,
|
nip44EncryptToSelf,
|
||||||
loadRelay,
|
loadRelay,
|
||||||
} from "@welshman/app"
|
} from "@welshman/app"
|
||||||
import {tagRoom, userMembership, MEMBERSHIPS, INDEXER_RELAYS, loadMembership} from "@app/state"
|
import {tagRoom, userMembership, MEMBERSHIPS, INDEXER_RELAYS, loadMembership, loadSettings} from "@app/state"
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
|
|
||||||
|
|
@ -86,6 +86,7 @@ export const loadUserData = (
|
||||||
const promise = Promise.all([
|
const promise = Promise.all([
|
||||||
loadInboxRelaySelections(pubkey, request),
|
loadInboxRelaySelections(pubkey, request),
|
||||||
loadMembership(pubkey, request),
|
loadMembership(pubkey, request),
|
||||||
|
loadSettings(pubkey, request),
|
||||||
loadProfile(pubkey, request),
|
loadProfile(pubkey, request),
|
||||||
loadFollows(pubkey, request),
|
loadFollows(pubkey, request),
|
||||||
loadMutes(pubkey, request),
|
loadMutes(pubkey, request),
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
import ContentQuote from "@app/components/ContentQuote.svelte"
|
import ContentQuote from "@app/components/ContentQuote.svelte"
|
||||||
import ContentTopic from "@app/components/ContentTopic.svelte"
|
import ContentTopic from "@app/components/ContentTopic.svelte"
|
||||||
import ContentMention from "@app/components/ContentMention.svelte"
|
import ContentMention from "@app/components/ContentMention.svelte"
|
||||||
import {entityLink} from "@app/state"
|
import {entityLink, userSettings} from "@app/state"
|
||||||
|
|
||||||
export let event
|
export let event
|
||||||
export let minLength = 500
|
export let minLength = 500
|
||||||
|
|
@ -69,7 +69,9 @@
|
||||||
warning = null
|
warning = null
|
||||||
}
|
}
|
||||||
|
|
||||||
let warning = event.tags.find(nthEq(0, "content-warning"))?.[1]
|
let warning =
|
||||||
|
$userSettings?.values.hide_sensitive &&
|
||||||
|
event.tags.find(nthEq(0, "content-warning"))?.[1]
|
||||||
|
|
||||||
$: shortContent = showEntire
|
$: shortContent = showEntire
|
||||||
? fullContent
|
? fullContent
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,13 @@ import {
|
||||||
pushToMapKey,
|
pushToMapKey,
|
||||||
nthEq,
|
nthEq,
|
||||||
shuffle,
|
shuffle,
|
||||||
|
parseJson,
|
||||||
} from "@welshman/lib"
|
} from "@welshman/lib"
|
||||||
import {
|
import {
|
||||||
getIdFilters,
|
getIdFilters,
|
||||||
WRAP,
|
WRAP,
|
||||||
RELAYS,
|
RELAYS,
|
||||||
|
APP_DATA,
|
||||||
REACTION,
|
REACTION,
|
||||||
ZAP_RESPONSE,
|
ZAP_RESPONSE,
|
||||||
DIRECT_MESSAGE,
|
DIRECT_MESSAGE,
|
||||||
|
|
@ -56,6 +58,7 @@ import {
|
||||||
pull,
|
pull,
|
||||||
createSearch,
|
createSearch,
|
||||||
userFollows,
|
userFollows,
|
||||||
|
ensurePlaintext,
|
||||||
} from "@welshman/app"
|
} from "@welshman/app"
|
||||||
import type {AppSyncOpts} from "@welshman/app"
|
import type {AppSyncOpts} from "@welshman/app"
|
||||||
import type {SubscribeRequestWithHandlers} from "@welshman/net"
|
import type {SubscribeRequestWithHandlers} from "@welshman/net"
|
||||||
|
|
@ -240,6 +243,42 @@ export const deriveEventsForUrl = (url: string, kinds: number[]) =>
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
|
||||||
|
export const SETTINGS = "nostr-engine/User/settings/v1"
|
||||||
|
|
||||||
|
export type Settings = {
|
||||||
|
event: TrustedEvent,
|
||||||
|
values: {
|
||||||
|
hide_sensitive: boolean
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultSettings = {
|
||||||
|
hide_sensitive: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const settings = deriveEventsMapped<Settings>(repository, {
|
||||||
|
filters: [{kinds: [APP_DATA], '#d': [SETTINGS]}],
|
||||||
|
itemToEvent: item => item.event,
|
||||||
|
eventToItem: async (event: TrustedEvent) =>
|
||||||
|
({event, values: {...defaultSettings, ...parseJson(await ensurePlaintext(event))}})
|
||||||
|
})
|
||||||
|
|
||||||
|
export const {
|
||||||
|
indexStore: settingsByPubkey,
|
||||||
|
deriveItem: deriveSettings,
|
||||||
|
loadItem: loadSettings,
|
||||||
|
} = collection({
|
||||||
|
name: "settings",
|
||||||
|
store: settings,
|
||||||
|
getKey: settings => settings.event.pubkey,
|
||||||
|
load: (pubkey: string, request: Partial<SubscribeRequestWithHandlers> = {}) =>
|
||||||
|
load({...request, filters: [{kinds: [APP_DATA], '#d': [SETTINGS], authors: [pubkey]}]}),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Membership
|
// Membership
|
||||||
|
|
||||||
export const getMembershipUrls = (list?: List) => sort(getRelayTagValues(getListTags(list)))
|
export const getMembershipUrls = (list?: List) => sort(getRelayTagValues(getListTags(list)))
|
||||||
|
|
@ -418,6 +457,16 @@ export const roomsByUrl = derived(channels, $channels => {
|
||||||
|
|
||||||
// User stuff
|
// User stuff
|
||||||
|
|
||||||
|
export const userSettings = withGetter(
|
||||||
|
derived([pubkey, settingsByPubkey], ([$pubkey, $settingsByPubkey]) => {
|
||||||
|
if (!$pubkey) return undefined
|
||||||
|
|
||||||
|
loadSettings($pubkey)
|
||||||
|
|
||||||
|
return $settingsByPubkey.get($pubkey)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
export const userMembership = withGetter(
|
export const userMembership = withGetter(
|
||||||
derived([pubkey, membershipByPubkey], ([$pubkey, $membershipByPubkey]) => {
|
derived([pubkey, membershipByPubkey], ([$pubkey, $membershipByPubkey]) => {
|
||||||
if (!$pubkey) return undefined
|
if (!$pubkey) return undefined
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,27 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {ctx} from "@welshman/lib"
|
import {ctx} from "@welshman/lib"
|
||||||
import {getListTags, createEvent, getPubkeyTagValues, MUTES} from "@welshman/util"
|
import {getListTags, createEvent, getPubkeyTagValues, MUTES, APP_DATA} from "@welshman/util"
|
||||||
import {userMutes, tagPubkey, publishThunk} from "@welshman/app"
|
import {pubkey, signer, userMutes, tagPubkey, publishThunk} from "@welshman/app"
|
||||||
import Field from "@lib/components/Field.svelte"
|
import Field from "@lib/components/Field.svelte"
|
||||||
import FieldInline from "@lib/components/FieldInline.svelte"
|
import FieldInline from "@lib/components/FieldInline.svelte"
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
import ProfileMultiSelect from "@app/components/ProfileMultiSelect.svelte"
|
import ProfileMultiSelect from "@app/components/ProfileMultiSelect.svelte"
|
||||||
import {pushToast} from "@app/toast"
|
import {pushToast} from "@app/toast"
|
||||||
|
import {SETTINGS, userSettings} from "@app/state"
|
||||||
let mutedPubkeys = getPubkeyTagValues(getListTags($userMutes))
|
|
||||||
|
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
mutedPubkeys = getPubkeyTagValues(getListTags($userMutes))
|
mutedPubkeys = getPubkeyTagValues(getListTags($userMutes))
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
|
publishThunk({
|
||||||
|
event: createEvent(APP_DATA, {
|
||||||
|
content: await $signer!.nip04.encrypt($pubkey!, JSON.stringify(settings)),
|
||||||
|
tags: [["d", SETTINGS]]
|
||||||
|
}),
|
||||||
|
relays: ctx.app.router.WriteRelays().getUrls(),
|
||||||
|
})
|
||||||
|
|
||||||
publishThunk({
|
publishThunk({
|
||||||
event: createEvent(MUTES, {tags: mutedPubkeys.map(tagPubkey)}),
|
event: createEvent(MUTES, {tags: mutedPubkeys.map(tagPubkey)}),
|
||||||
relays: ctx.app.router.WriteRelays().getUrls(),
|
relays: ctx.app.router.WriteRelays().getUrls(),
|
||||||
|
|
@ -22,6 +29,9 @@
|
||||||
|
|
||||||
pushToast({message: "Your settings have been saved!"})
|
pushToast({message: "Your settings have been saved!"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let settings = {...$userSettings?.values}
|
||||||
|
let mutedPubkeys = getPubkeyTagValues(getListTags($userMutes))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form class="content column gap-4" on:submit|preventDefault={onSubmit}>
|
<form class="content column gap-4" on:submit|preventDefault={onSubmit}>
|
||||||
|
|
@ -34,7 +44,7 @@
|
||||||
</Field>
|
</Field>
|
||||||
<FieldInline>
|
<FieldInline>
|
||||||
<p slot="label">Hide sensitive content?</p>
|
<p slot="label">Hide sensitive content?</p>
|
||||||
<input slot="input" type="checkbox" class="toggle toggle-primary" checked="checked" />
|
<input slot="input" type="checkbox" class="toggle toggle-primary" bind:checked={settings.hide_sensitive} />
|
||||||
<p slot="info">If content is marked by the author as sensitive, flotilla will hide it by default.</p>
|
<p slot="info">If content is marked by the author as sensitive, flotilla will hide it by default.</p>
|
||||||
</FieldInline>
|
</FieldInline>
|
||||||
<div class="mt-4 flex flex-row items-center justify-between gap-4">
|
<div class="mt-4 flex flex-row items-center justify-between gap-4">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue