diff --git a/.changeset/nervous-ladybugs-drop.md b/.changeset/nervous-ladybugs-drop.md
new file mode 100644
index 000000000..808d87fd3
--- /dev/null
+++ b/.changeset/nervous-ladybugs-drop.md
@@ -0,0 +1,5 @@
+---
+"nostrudel": minor
+---
+
+Show host emojis when writing stream chat message
diff --git a/src/providers/emoji-provider.tsx b/src/providers/emoji-provider.tsx
index 627e5fddd..836ba663d 100644
--- a/src/providers/emoji-provider.tsx
+++ b/src/providers/emoji-provider.tsx
@@ -23,9 +23,9 @@ export function DefaultEmojiProvider({ children }: PropsWithChildren) {
return {children};
}
-export function UserEmojiProvider({ children }: PropsWithChildren) {
+export function UserEmojiProvider({ children, pubkey }: PropsWithChildren & { pubkey?: string }) {
const account = useCurrentAccount();
- const userPacks = useUserEmojiPacks(account?.pubkey);
+ const userPacks = useUserEmojiPacks(pubkey || account?.pubkey);
const events = useReplaceableEvents(userPacks?.packs);
const emojis = events
@@ -34,8 +34,6 @@ export function UserEmojiProvider({ children }: PropsWithChildren) {
)
.flat();
- console.log(userPacks, emojis);
-
return {children};
}
diff --git a/src/views/streams/stream/index.tsx b/src/views/streams/stream/index.tsx
index 95baea8ed..1482a1db3 100644
--- a/src/views/streams/stream/index.tsx
+++ b/src/views/streams/stream/index.tsx
@@ -35,6 +35,7 @@ import RelaySelectionProvider from "../../../providers/relay-selection-provider"
import StreamerCards from "../components/streamer-cards";
import { useAppTitle } from "../../../hooks/use-app-title";
import StreamSatsPerMinute from "../components/stream-sats-per-minute";
+import { UserEmojiProvider } from "../../../providers/emoji-provider";
function StreamPage({ stream, displayMode }: { stream: ParsedStream; displayMode?: ChatDisplayMode }) {
useAppTitle(stream.title);
@@ -194,7 +195,9 @@ export default function StreamView() {
return (
// add snort and damus relays so zap.stream will always see zaps
-
+
+
+
);
}
diff --git a/src/views/streams/stream/stream-chat/chat-message-form.tsx b/src/views/streams/stream/stream-chat/chat-message-form.tsx
new file mode 100644
index 000000000..9e5542944
--- /dev/null
+++ b/src/views/streams/stream/stream-chat/chat-message-form.tsx
@@ -0,0 +1,95 @@
+import { useMemo } from "react";
+import { Box, Button, IconButton, useDisclosure, useToast } from "@chakra-ui/react";
+import { useForm } from "react-hook-form";
+
+import { ParsedStream, buildChatMessage } from "../../../../helpers/nostr/stream";
+import { useRelaySelectionRelays } from "../../../../providers/relay-selection-provider";
+import { useUserRelays } from "../../../../hooks/use-user-relays";
+import { RelayMode } from "../../../../classes/relay";
+import { unique } from "../../../../helpers/array";
+import { LightningIcon } from "../../../../components/icons";
+import useUserLNURLMetadata from "../../../../hooks/use-user-lnurl-metadata";
+import ZapModal from "../../../../components/zap-modal";
+import { useInvoiceModalContext } from "../../../../providers/invoice-modal";
+import { useSigningContext } from "../../../../providers/signing-provider";
+import NostrPublishAction from "../../../../classes/nostr-publish-action";
+import { createEmojiTags, ensureNotifyContentMentions } from "../../../../helpers/nostr/post";
+import { useContextEmojis } from "../../../../providers/emoji-provider";
+import MagicTextArea from "../../../../components/magic-textarea";
+
+export default function ChatMessageForm({ stream }: { stream: ParsedStream }) {
+ const toast = useToast();
+ const emojis = useContextEmojis();
+ const streamRelays = useRelaySelectionRelays();
+ const hostReadRelays = useUserRelays(stream.host)
+ .filter((r) => r.mode & RelayMode.READ)
+ .map((r) => r.url);
+
+ const relays = useMemo(() => unique([...streamRelays, ...hostReadRelays]), [hostReadRelays, streamRelays]);
+
+ const { requestSignature } = useSigningContext();
+ const { setValue, handleSubmit, formState, reset, getValues, watch } = useForm({
+ defaultValues: { content: "" },
+ });
+ const sendMessage = handleSubmit(async (values) => {
+ try {
+ let draft = buildChatMessage(stream, values.content);
+ draft = ensureNotifyContentMentions(draft);
+ draft = createEmojiTags(draft, emojis);
+ const signed = await requestSignature(draft);
+ new NostrPublishAction("Send Chat", relays, signed);
+ reset();
+ } catch (e) {
+ if (e instanceof Error) toast({ description: e.message, status: "error" });
+ }
+ });
+
+ const { requestPay } = useInvoiceModalContext();
+ const zapModal = useDisclosure();
+ const zapMetadata = useUserLNURLMetadata(stream.host);
+
+ watch("content");
+
+ return (
+ <>
+
+ setValue("content", e.target.value)}
+ rows={1}
+ />
+
+ {zapMetadata.metadata?.allowsNostr && (
+ }
+ aria-label="Zap stream"
+ borderColor="yellow.400"
+ variant="outline"
+ onClick={zapModal.onOpen}
+ />
+ )}
+
+
+ {zapModal.isOpen && (
+ {
+ reset();
+ zapModal.onClose();
+ await requestPay(invoice);
+ }}
+ onClose={zapModal.onClose}
+ initialComment={getValues().content}
+ additionalRelays={relays}
+ />
+ )}
+ >
+ );
+}
diff --git a/src/views/streams/stream/stream-chat/index.tsx b/src/views/streams/stream/stream-chat/index.tsx
index c1a1ff723..bc68841d0 100644
--- a/src/views/streams/stream/stream-chat/index.tsx
+++ b/src/views/streams/stream/stream-chat/index.tsx
@@ -1,47 +1,24 @@
import { useCallback, useMemo, useRef } from "react";
-import {
- Box,
- Button,
- Card,
- CardBody,
- CardHeader,
- CardProps,
- Flex,
- Heading,
- IconButton,
- Input,
- useDisclosure,
- useToast,
-} from "@chakra-ui/react";
+import { Card, CardBody, CardHeader, CardProps, Flex, Heading } from "@chakra-ui/react";
+import { css } from "@emotion/react";
+import { Kind } from "nostr-tools";
-import { ParsedStream, STREAM_CHAT_MESSAGE_KIND, buildChatMessage, getATag } from "../../../../helpers/nostr/stream";
-import { useUserRelays } from "../../../../hooks/use-user-relays";
-import { RelayMode } from "../../../../classes/relay";
-import ZapModal from "../../../../components/zap-modal";
-import { LightningIcon } from "../../../../components/icons";
+import { ParsedStream, STREAM_CHAT_MESSAGE_KIND, getATag } from "../../../../helpers/nostr/stream";
import ChatMessage from "./chat-message";
import ZapMessage from "./zap-message";
import { LightboxProvider } from "../../../../components/lightbox-provider";
import IntersectionObserverProvider from "../../../../providers/intersection-observer";
-import useUserLNURLMetadata from "../../../../hooks/use-user-lnurl-metadata";
-import { useInvoiceModalContext } from "../../../../providers/invoice-modal";
-import { unique } from "../../../../helpers/array";
-import { useForm } from "react-hook-form";
-import { useSigningContext } from "../../../../providers/signing-provider";
import { useTimelineCurserIntersectionCallback } from "../../../../hooks/use-timeline-cursor-intersection-callback";
import useSubject from "../../../../hooks/use-subject";
import useTimelineLoader from "../../../../hooks/use-timeline-loader";
import { truncatedId } from "../../../../helpers/nostr/events";
-import { css } from "@emotion/react";
import TopZappers from "./top-zappers";
import { parseZapEvent } from "../../../../helpers/zaps";
-import { Kind } from "nostr-tools";
import { useRelaySelectionRelays } from "../../../../providers/relay-selection-provider";
import useUserMuteList from "../../../../hooks/use-user-mute-list";
import { NostrEvent, isPTag } from "../../../../types/nostr-event";
import { useCurrentAccount } from "../../../../hooks/use-current-account";
-import NostrPublishAction from "../../../../classes/nostr-publish-action";
-import { ensureNotifyContentMentions } from "../../../../helpers/nostr/post";
+import ChatMessageForm from "./chat-message-form";
const hideScrollbar = css`
scrollbar-width: 0;
@@ -59,14 +36,8 @@ export default function StreamChat({
displayMode,
...props
}: CardProps & { stream: ParsedStream; actions?: React.ReactNode; displayMode?: ChatDisplayMode }) {
- const toast = useToast();
const account = useCurrentAccount();
const streamRelays = useRelaySelectionRelays();
- const hostReadRelays = useUserRelays(stream.host)
- .filter((r) => r.mode & RelayMode.READ)
- .map((r) => r.url);
-
- const relays = useMemo(() => unique([...streamRelays, ...hostReadRelays]), [hostReadRelays, streamRelays]);
const hostMuteList = useUserMuteList(stream.host);
const muteList = useUserMuteList(account?.pubkey);
@@ -101,106 +72,45 @@ export default function StreamChat({
const scrollBox = useRef(null);
const callback = useTimelineCurserIntersectionCallback(timeline);
- const { requestSignature } = useSigningContext();
- const { register, handleSubmit, formState, reset, getValues } = useForm({
- defaultValues: { content: "" },
- });
- const sendMessage = handleSubmit(async (values) => {
- try {
- const draft = buildChatMessage(stream, values.content);
- const signed = await requestSignature(draft);
- new NostrPublishAction("Send Chat", relays, signed);
- reset();
- } catch (e) {
- if (e instanceof Error) toast({ description: e.message, status: "error" });
- }
- });
-
- const zapModal = useDisclosure();
- const { requestPay } = useInvoiceModalContext();
- const zapMetadata = useUserLNURLMetadata(stream.host);
-
const isPopup = !!displayMode;
const isChatLog = displayMode === "log";
return (
- <>
-
-
-
- {!isPopup && (
-
- Stream Chat
- {actions}
-
- )}
-
-
-
- {events.map((event) =>
- event.kind === STREAM_CHAT_MESSAGE_KIND ? (
-
- ) : (
-
- ),
- )}
-
- {!isChatLog && (
-
-
-
- {zapMetadata.metadata?.allowsNostr && (
- }
- aria-label="Zap stream"
- borderColor="yellow.400"
- variant="outline"
- onClick={zapModal.onOpen}
- />
- )}
-
+
+
+
+ {!isPopup && (
+
+ Stream Chat
+ {actions}
+
+ )}
+
+
+
+ {events.map((event) =>
+ event.kind === STREAM_CHAT_MESSAGE_KIND ? (
+
+ ) : (
+
+ ),
)}
-
-
-
-
- {zapModal.isOpen && (
- {
- reset();
- zapModal.onClose();
- await requestPay(invoice);
- }}
- onClose={zapModal.onClose}
- initialComment={getValues().content}
- additionalRelays={relays}
- />
- )}
- >
+
+ {!isChatLog && }
+
+
+
+
);
}