diff --git a/.changeset/cuddly-walls-fix.md b/.changeset/cuddly-walls-fix.md new file mode 100644 index 000000000..141e07b0f --- /dev/null +++ b/.changeset/cuddly-walls-fix.md @@ -0,0 +1,5 @@ +--- +"nostrudel": minor +--- + +Add nostrapp.link option in profile and note menus diff --git a/.changeset/quick-kiwis-peel.md b/.changeset/quick-kiwis-peel.md new file mode 100644 index 000000000..39bc23aca --- /dev/null +++ b/.changeset/quick-kiwis-peel.md @@ -0,0 +1,5 @@ +--- +"nostrudel": minor +--- + +add embeds for wavlake tracks diff --git a/src/components/embed-types/app-music.tsx b/src/components/embed-types/app-music.tsx deleted file mode 100644 index 4ef9e5716..000000000 --- a/src/components/embed-types/app-music.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { EmbedableContent, embedJSX } from "../../helpers/embeds"; - -// note1tvqk2mu829yr6asf7w5dgpp8t0mlp2ax5t26ctfdx8m0ptkssamqsleeux -// note1ygx9tec3af92704d92jwrj3zs7cws2jl29yvrlxzqlcdlykhwssqpupa7t -export function embedAppleMusic(content: EmbedableContent) { - return embedJSX(content, { - regexp: /https?:\/\/music\.apple\.com(?:\/[\+~%\/\.\w\-_]*)?(\??(?:[\?#\-\+=&;%@\.\w_]*)#?(?:[\-\.\!\/\\\w]*))?/, - render: (match) => ( - - ), - name: "Apple Music", - }); -} diff --git a/src/components/embed-types/index.ts b/src/components/embed-types/index.ts index 2999304af..953877606 100644 --- a/src/components/embed-types/index.ts +++ b/src/components/embed-types/index.ts @@ -1,9 +1,6 @@ export * from "./twitter"; export * from "./lightning"; -export * from "./app-music"; +export * from "./music"; export * from "./common"; -export * from "./spotify"; -export * from "./tidal"; export * from "./youtube"; -export * from "./spotify"; export * from "./nostr"; diff --git a/src/components/embed-types/music.tsx b/src/components/embed-types/music.tsx new file mode 100644 index 000000000..8f4266705 --- /dev/null +++ b/src/components/embed-types/music.tsx @@ -0,0 +1,75 @@ +import { EmbedableContent, embedJSX } from "../../helpers/embeds"; + +export function embedWavlakeTrack(content: EmbedableContent) { + return embedJSX(content, { + name: "Wavlake Track", + regexp: /https?:\/\/wavlake\.com\/track\/[\w-]+/i, + render: (match) => ( + + ), + }); +} + +// note1tvqk2mu829yr6asf7w5dgpp8t0mlp2ax5t26ctfdx8m0ptkssamqsleeux +// note1ygx9tec3af92704d92jwrj3zs7cws2jl29yvrlxzqlcdlykhwssqpupa7t +export function embedAppleMusic(content: EmbedableContent) { + return embedJSX(content, { + regexp: /https?:\/\/music\.apple\.com(?:\/[\+~%\/\.\w\-_]*)?(\??(?:[\?#\-\+=&;%@\.\w_]*)#?(?:[\-\.\!\/\\\w]*))?/, + render: (match) => ( + + ), + name: "Apple Music", + }); +} + +// nostr:nevent1qqs9r94qeqhqayvuz6q6u88spvuz0d25nhpyv0c39wympmfu646x4pgpz3mhxue69uhhyetvv9ujuerpd46hxtnfduq3samnwvaz7tmjv4kxz7fwwdhx7un59eek7cmfv9kqmhxhvq +export function embedSpotifyMusic(content: EmbedableContent) { + return embedJSX(content, { + regexp: + /https?:\/\/open\.spotify\.com\/(track|episode|album|playlist)\/(\w+)(\??(?:[\?#\-\+=&;%@\.\w_]*)#?(?:[\-\.\!\/\\\w]*))?/im, + render: (match) => { + const isList = match[1] === "album" || match[1] === "playlist"; + return ( + + ); + }, + name: "Spotify", + }); +} + +// note132m5xc3zhj7fap67vzwx5x3s8xqgz49k669htcn8kppr4m654tuq960tuu +export function embedTidalMusic(content: EmbedableContent) { + return embedJSX(content, { + regexp: /https?:\/\/tidal\.com(\/browse)?\/(track|album)\/(\d+)/im, + render: (match) => ( + + ), + name: "Tidal", + }); +} diff --git a/src/components/embed-types/spotify.tsx b/src/components/embed-types/spotify.tsx deleted file mode 100644 index 1e8c3c06e..000000000 --- a/src/components/embed-types/spotify.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { EmbedableContent, embedJSX } from "../../helpers/embeds"; - -// nostr:nevent1qqs9r94qeqhqayvuz6q6u88spvuz0d25nhpyv0c39wympmfu646x4pgpz3mhxue69uhhyetvv9ujuerpd46hxtnfduq3samnwvaz7tmjv4kxz7fwwdhx7un59eek7cmfv9kqmhxhvq -export function embedSpotifyMusic(content: EmbedableContent) { - return embedJSX(content, { - regexp: - /https?:\/\/open\.spotify\.com\/(track|episode|album|playlist)\/(\w+)(\??(?:[\?#\-\+=&;%@\.\w_]*)#?(?:[\-\.\!\/\\\w]*))?/im, - render: (match) => { - const isList = match[1] === "album" || match[1] === "playlist"; - return ( - - ); - }, - name: "Spotify", - }); -} diff --git a/src/components/embed-types/tidal.tsx b/src/components/embed-types/tidal.tsx deleted file mode 100644 index 68a7185ba..000000000 --- a/src/components/embed-types/tidal.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { EmbedableContent, embedJSX } from "../../helpers/embeds"; - -// note132m5xc3zhj7fap67vzwx5x3s8xqgz49k669htcn8kppr4m654tuq960tuu -export function embedTidalMusic(content: EmbedableContent) { - return embedJSX(content, { - regexp: /https?:\/\/tidal\.com(\/browse)?\/(track|album)\/(\d+)/im, - render: (match) => ( - - ), - name: "Tidal", - }); -} diff --git a/src/components/note/note-contents.tsx b/src/components/note/note-contents.tsx index fd8f8e117..397218926 100644 --- a/src/components/note/note-contents.tsx +++ b/src/components/note/note-contents.tsx @@ -19,6 +19,7 @@ import { embedNostrMentions, embedAppleMusic, embedNostrHashtags, + embedWavlakeTrack, } from "../embed-types"; import { ImageGalleryProvider } from "../image-gallery"; import { useTrusted } from "./trust"; @@ -31,6 +32,7 @@ function buildContents(event: NostrEvent | DraftNostrEvent, trusted = false) { content = embedYoutubeVideo(content); content = embedYoutubePlaylist(content); content = embedYoutubeMusic(content); + content = embedWavlakeTrack(content); content = embedTidalMusic(content); content = embedAppleMusic(content); content = embedSpotifyMusic(content); diff --git a/src/components/note/note-menu.tsx b/src/components/note/note-menu.tsx index 53d168e74..4c1f4c46b 100644 --- a/src/components/note/note-menu.tsx +++ b/src/components/note/note-menu.tsx @@ -18,7 +18,7 @@ import { Bech32Prefix, getSharableNoteId, normalizeToBech32 } from "../../helper import { NostrEvent } from "../../types/nostr-event"; import { MenuIconButton, MenuIconButtonProps } from "../menu-icon-button"; -import { ClipboardIcon, CodeIcon, LikeIcon, RepostIcon, TrashIcon } from "../icons"; +import { ClipboardIcon, CodeIcon, ExternalLinkIcon, LikeIcon, RepostIcon, TrashIcon } from "../icons"; import NoteReactionsModal from "./note-zaps-modal"; import NoteDebugModal from "../debug-modals/note-debug-modal"; import { useCurrentAccount } from "../../hooks/use-current-account"; @@ -68,6 +68,12 @@ export const NoteMenu = ({ event, ...props }: { event: NostrEvent } & Omit}> Zaps/Reactions + window.open(`https://nostrapp.link/#${getSharableNoteId(event.id)}?select=true`, "_blank")} + icon={} + > + View in app... + copyToClipboard("nostr:" + getSharableNoteId(event.id))} icon={}> Copy Share Link diff --git a/src/views/user/components/user-profile-menu.tsx b/src/views/user/components/user-profile-menu.tsx index ddc4c6b13..aec7dcef1 100644 --- a/src/views/user/components/user-profile-menu.tsx +++ b/src/views/user/components/user-profile-menu.tsx @@ -1,7 +1,7 @@ import { MenuItem, useDisclosure } from "@chakra-ui/react"; import { MenuIconButton, MenuIconButtonProps } from "../../../components/menu-icon-button"; -import { ClipboardIcon, CodeIcon, RelayIcon, SpyIcon } from "../../../components/icons"; +import { ClipboardIcon, CodeIcon, ExternalLinkIcon, RelayIcon, SpyIcon } from "../../../components/icons"; import accountService from "../../../services/account"; import { useUserMetadata } from "../../../hooks/use-user-metadata"; import { getUserDisplayName } from "../../../helpers/user-metadata"; @@ -41,6 +41,12 @@ export const UserProfileMenu = ({ } onClick={() => loginAsUser()}> Login as {getUserDisplayName(metadata, pubkey)} + window.open(`https://nostrapp.link/#${sharableId}?select=true`, "_blank")} + icon={} + > + View in app... + copyToClipboard("nostr:" + sharableId)} icon={}> Copy share link