diff --git a/src/i18n/locales/de.ts b/src/i18n/locales/de.ts index 8dedb3ef..56580dd8 100644 --- a/src/i18n/locales/de.ts +++ b/src/i18n/locales/de.ts @@ -728,6 +728,19 @@ export default { listImportATagFailed: 'Adress-Tag konnte nicht aufgelöst werden: {{preview}}…', listImportEventNotFound: 'Kein Event zu dieser Referenz gefunden.', 'REQ tag filters': 'REQ-Tag-Filter', + spellFormTagFiltersLabel: 'Tag-Filter auf passenden Events', + spellCreateIntro: + 'Zaubersprüche sind gespeicherte Relay-Filter (NIP-A7). Der Abschnitt „Abfrage“ ist die eigentliche Definition; der gestrichelte Kasten unten nur für Namen, Beschreibung und Katalog-Labels. Beim Ausführen: $me für deinen Pubkey, $contacts für deine Follow-Liste.', + spellFormSectionQueryTitle: 'Abfrage (Spell-Definition)', + spellFormSectionQueryHint: + 'Dieser Block ist die eigentliche Definition: Er wird zum Nostr-REQ-/COUNT-Filter (Kinds, Autoren, Zeitraum, Tag-Filter auf passenden Events, Relays usw.).', + spellFormSectionMetadataTitle: 'Anzeige & Beschriftung (optional)', + spellFormSectionMetadataBadge: 'Gehört nicht zur Abfrage', + spellFormSectionMetadataHint: + 'Name, Beschreibung und Themen-Labels dienen nur der Darstellung und in Zauberspruch-Listen. Sie werden beim Abrufen von Events nicht verwendet.', + spellFormCatalogTopicsLabel: 'Themen-Labels auf dem Zauberspruch (t-Tags)', + spellTopicsMetadataHint: + 'Ein Thema pro Zeile. Um Notes nach Thema zu filtern, nutze oben im Block „Abfrage“ die REQ-Tag-Filter (Buchstabe „t“).', spellTagFiltersHint: 'Optionale Filter auf abonnierte Events (NIP-01 Ein-Buchstaben-Tags). Beispiel: Buchstabe „t“, Werte „bitcoin“.', spellTagFiltersEmpty: diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts index 37e87ae2..5f4b277c 100644 --- a/src/i18n/locales/en.ts +++ b/src/i18n/locales/en.ts @@ -763,6 +763,19 @@ export default { listImportATagFailed: 'Failed to resolve address tag: {{preview}}…', listImportEventNotFound: 'No event found for that reference.', 'REQ tag filters': 'REQ tag filters', + spellFormTagFiltersLabel: 'Tag filters on matching events', + spellCreateIntro: + 'Spells are saved relay filters (NIP-A7). The “Spell query” section is the real definition; the dashed box at the bottom is only for names, descriptions, and catalog labels. Use $me for your pubkey and $contacts for your follow list when executing.', + spellFormSectionQueryTitle: 'Spell query', + spellFormSectionQueryHint: + 'This block is the actual spell definition: it becomes the Nostr REQ/COUNT filter (kinds, authors, time range, tag filters on matching events, relays, etc.).', + spellFormSectionMetadataTitle: 'Listing & labels (optional)', + spellFormSectionMetadataBadge: 'Not part of the query', + spellFormSectionMetadataHint: + 'Name, description, and topic labels are only for display and spell pickers. They are not used when the spell fetches events.', + spellFormCatalogTopicsLabel: 'Topic labels on this spell (t tags)', + spellTopicsMetadataHint: + 'One topic per row. To filter which notes you see, use “REQ tag filters” in the spell query above (letter “t”).', spellTagFiltersHint: 'Optional filters on subscribed events (NIP-01 single-letter tags). Example: letter “t”, values “bitcoin”.', spellTagFiltersEmpty: 'No tag filters yet. Add rows below or apply an event reference above.', diff --git a/src/pages/primary/SpellsPage/CreateSpellDialog.tsx b/src/pages/primary/SpellsPage/CreateSpellDialog.tsx index 179e3195..8394d98e 100644 --- a/src/pages/primary/SpellsPage/CreateSpellDialog.tsx +++ b/src/pages/primary/SpellsPage/CreateSpellDialog.tsx @@ -23,10 +23,10 @@ import { showPublishingError, showSimplePublishSuccess } from '@/lib/publishing- import client from '@/services/client.service' import indexedDb from '@/services/indexed-db.service' import { getRelaysForSpellCatalogSync } from '@/services/spell.service' -import { Minus, Plus, X } from 'lucide-react' +import { Info, Minus, Plus, X } from 'lucide-react' import { useTranslation } from 'react-i18next' import type { Event as NostrEvent } from 'nostr-tools' -import { useCallback, useEffect, useRef, useState } from 'react' +import { useCallback, useEffect, useRef, useState, type ReactNode } from 'react' import logger from '@/lib/logger' /** Arrow keys should control the control, not the dialog scroll */ @@ -140,6 +140,44 @@ function DynamicStringListField({ ) } +/** Bottom-of-form panel: name, description, catalog topics — not part of NIP-A7 REQ filter. */ +function SpellMetadataSection({ + title, + badge, + hint, + children +}: { + title: string + badge: string + hint: string + children: ReactNode +}) { + return ( +
+
+
+ +

+ {title} +

+ + {badge} + +
+

{hint}

+
+
{children}
+
+ ) +} + function TagFiltersEditor({ tagFilters, onChange @@ -156,7 +194,7 @@ function TagFiltersEditor({ } return (
- +

{t('spellTagFiltersHint')}

{tagFilters.length === 0 ? (

{t('spellTagFiltersEmpty')}

@@ -405,9 +443,7 @@ export default function CreateSpellDialog({

{spellToClone ? t('Clone spell intro') - : t( - 'Spells are saved relay filters (NIP-A7). Fill in the filter fields below. Use $me for your pubkey and $contacts for your follow list when executing.' - )} + : t('spellCreateIntro')}

@@ -458,153 +494,166 @@ export default function CreateSpellDialog({ ) : null} -
- - -

{t('REQ returns a feed; COUNT returns a number.')}

-
+
+
+

{t('spellFormSectionQueryTitle')}

+

{t('spellFormSectionQueryHint')}

+
-
- - setForm((f) => ({ ...f, name: e.target.value }))} - placeholder={t('Human-readable spell name')} - /> -
+
+ + +

{t('REQ returns a feed; COUNT returns a number.')}

+
-
- -