diff --git a/.env.basspistol b/.env.basspistol deleted file mode 100644 index 23ba89d..0000000 --- a/.env.basspistol +++ /dev/null @@ -1,2 +0,0 @@ -VITE_COMMUNITY_RELAYS="wss://basspistol.org/favorites,wss://basspistol.org/popular,wss://basspistol.org/uppermost,wss://basspistol.org/personal" -VITE_COMMUNITY_RELAY_SETS=[{"id": "basspistol", "name": "Basspistol", "relayUrls": ["wss://basspistol.org","wss://drops.basspistol.org"]},{"id": "member", "name": "Backstage", "relayUrls": ["wss://basspistol.org/internal"]},{"id": "hood", "name": "Hood", "relayUrls": ["wss://nestr.nedao.ch","wss://pyramid.fiatjaf.com","wss://spatia-arcana.com","wss://lightning.red","wss://inner.sebastix.social"]}] diff --git a/README.md b/README.md index f4d76bd..c23365e 100644 --- a/README.md +++ b/README.md @@ -2,19 +2,15 @@ Jumble Logo - +

logo designed by Daniel David

-# Bpistle +# Jumble -A community fork of [Jumble](https://github.com/CodyTseng/jumble), the user-friendly Nostr client for exploring relay feeds, made by and for music lovers. - -Experience Bpistle at [https://nostr.basspistol.org](https://nostr.basspistol.org) +A user-friendly Nostr client for exploring relay feeds Experience Jumble at [https://jumble.social](https://jumble.social) -Upstream code: https://github.com/CodyTseng/jumble - ## Forks > Some interesting forks of Jumble. diff --git a/index.html b/index.html index 9e3c8c8..8677d1e 100644 --- a/index.html +++ b/index.html @@ -4,29 +4,29 @@ - Bpistle - + Jumble + - + - + - + - + diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png index 722a661..8d0a6c0 100644 Binary files a/public/apple-touch-icon.png and b/public/apple-touch-icon.png differ diff --git a/public/favicon-96x96.png b/public/favicon-96x96.png index 1028f7f..d3b391c 100644 Binary files a/public/favicon-96x96.png and b/public/favicon-96x96.png differ diff --git a/public/favicon.ico b/public/favicon.ico index 20047ec..23976c6 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/favicon.svg b/public/favicon.svg index 60940dc..0cb187d 100644 --- a/public/favicon.svg +++ b/public/favicon.svg @@ -1,7 +1 @@ - - - - - - - + \ No newline at end of file diff --git a/public/pwa-192x192.png b/public/pwa-192x192.png index 124c881..e6c6e4f 100644 Binary files a/public/pwa-192x192.png and b/public/pwa-192x192.png differ diff --git a/public/pwa-512x512.png b/public/pwa-512x512.png index 1543ecd..6c5a8d0 100644 Binary files a/public/pwa-512x512.png and b/public/pwa-512x512.png differ diff --git a/public/pwa-monochrome.svg b/public/pwa-monochrome.svg index 60940dc..c4b9a85 100644 --- a/public/pwa-monochrome.svg +++ b/public/pwa-monochrome.svg @@ -1,7 +1,9 @@ - - - - - - + + + + + + + + diff --git a/resources/icon-rounded.svg b/resources/icon-rounded.svg index a4e1e38..0cb187d 100644 --- a/resources/icon-rounded.svg +++ b/resources/icon-rounded.svg @@ -1,10 +1 @@ - - - - - - - - - - + \ No newline at end of file diff --git a/resources/icon.svg b/resources/icon.svg index 4e9c4ff..8f20e6a 100644 --- a/resources/icon.svg +++ b/resources/icon.svg @@ -1,5 +1,10 @@ - - - - + + + + + + + + + diff --git a/resources/logo-dark.svg b/resources/logo-dark.svg index 795a64a..1840617 100644 --- a/resources/logo-dark.svg +++ b/resources/logo-dark.svg @@ -1,2 +1 @@ - - + \ No newline at end of file diff --git a/resources/logo-light.svg b/resources/logo-light.svg index d628dc2..f1e3c92 100644 --- a/resources/logo-light.svg +++ b/resources/logo-light.svg @@ -1,2 +1 @@ - - + \ No newline at end of file diff --git a/src/assets/Icon.tsx b/src/assets/Icon.tsx index 9439ddb..0fdb8d6 100644 --- a/src/assets/Icon.tsx +++ b/src/assets/Icon.tsx @@ -17,7 +17,7 @@ export default function Icon({ className }: { className?: string }) { > ) diff --git a/src/assets/Logo.tsx b/src/assets/Logo.tsx index 769b736..0887faf 100644 --- a/src/assets/Logo.tsx +++ b/src/assets/Logo.tsx @@ -17,7 +17,7 @@ export default function Logo({ className }: { className?: string }) { > ) diff --git a/src/assets/favicon.svg b/src/assets/favicon.svg index 5482668..0cb187d 100644 --- a/src/assets/favicon.svg +++ b/src/assets/favicon.svg @@ -1,9 +1 @@ - - - - - - - - - + \ No newline at end of file diff --git a/src/components/ContentPreview/MusicTrackPreview.tsx b/src/components/ContentPreview/MusicTrackPreview.tsx deleted file mode 100644 index dba954f..0000000 --- a/src/components/ContentPreview/MusicTrackPreview.tsx +++ /dev/null @@ -1,24 +0,0 @@ - -import { useTranslation } from 'react-i18next' -import { Event } from 'nostr-tools' - -export default function MusicTrackPreview({ event }: { event: Event }) { - const { t } = useTranslation() - - const title = event.tags.find(tag => tag[0] === 'title')?.[1] - const artist = event.tags.find(tag => tag[0] === 'artist')?.[1] - - return ( -
- 🎵 - - {title || t('music.untitled')} - - {artist && ( - - {t('music.by')} {artist} - - )} -
- ) -} diff --git a/src/components/ContentPreview/index.tsx b/src/components/ContentPreview/index.tsx index fbf1cfa..bc0f402 100644 --- a/src/components/ContentPreview/index.tsx +++ b/src/components/ContentPreview/index.tsx @@ -18,7 +18,6 @@ import PictureNotePreview from './PictureNotePreview' import PollPreview from './PollPreview' import ReactionPreview from './ReactionPreview' import VideoNotePreview from './VideoNotePreview' -import MusicTrackPreview from './MusicTrackPreview' export default function ContentPreview({ event, @@ -121,10 +120,6 @@ export default function ContentPreview({ return } - if (event.kind === ExtendedKind.MUSIC_TRACK) { - return - } - return (
[ diff --git a/src/components/KindFilter/index.tsx b/src/components/KindFilter/index.tsx index f745e64..a22fa97 100644 --- a/src/components/KindFilter/index.tsx +++ b/src/components/KindFilter/index.tsx @@ -20,7 +20,6 @@ const KIND_FILTER_OPTIONS = [ { kindGroup: [ExtendedKind.POLL], label: 'Polls' }, { kindGroup: [ExtendedKind.VOICE, ExtendedKind.VOICE_COMMENT], label: 'Voice Posts' }, { kindGroup: [ExtendedKind.PICTURE], label: 'Photo Posts' }, - { kindGroup: [ExtendedKind.MUSIC_TRACK], label: 'Music Posts' }, { kindGroup: [ ExtendedKind.VIDEO, diff --git a/src/components/Note/MusicTrackNote/index.tsx b/src/components/Note/MusicTrackNote/index.tsx deleted file mode 100644 index aabd3ab..0000000 --- a/src/components/Note/MusicTrackNote/index.tsx +++ /dev/null @@ -1,173 +0,0 @@ -import { useMemo } from 'react' -import { useTranslation } from 'react-i18next' -import dayjs from 'dayjs' -import { Event } from 'nostr-tools' -import AudioPlayer from '@/components/AudioPlayer' - -interface MusicTrackNoteProps { - event: Event - className?: string -} - -export default function MusicTrackNote({ event, className }: MusicTrackNoteProps) { - const { t } = useTranslation() - - const metadata = useMemo(() => { - const getTagValue = (tagName: string) => { - const tag = event.tags.find(tag => tag[0] === tagName) - return tag?.[1] || null - } - - const getTagValues = (tagName: string) => { - return event.tags - .filter(tag => tag[0] === tagName) - .map(tag => tag[1]) - .filter(Boolean) - } - - - let lyrics = null - let credits = null - - if (event.content) { - const creditsMatch = event.content.match(/Credits:\s*\n([\s\S]*)/i) - if (creditsMatch) { - credits = creditsMatch[1].trim() - - const lyricsMatch = event.content.match(/^([\s\S]*?)Credits:/i) - lyrics = lyricsMatch ? lyricsMatch[1].trim() : null - } else { - - lyrics = event.content - } - } - - return { - title: getTagValue('title') || t('music.untitled'), - url: getTagValue('url'), - image: getTagValue('image'), - license: getTagValue('license'), - alt: getTagValue('alt'), - releaseDate: getTagValue('released'), - artist: getTagValue('artist'), - album: getTagValue('album'), - trackNumber: getTagValue('track_number'), - duration: getTagValue('duration'), - genres: getTagValues('t').filter(tag => - !['music', 'electronic', 'lofi pop'].includes(tag) - ), - lyrics, - credits - } - }, [event, t]) - - if (!metadata.url) { - return ( -
- {t('music.noAudioUrl')} -
- ) - } - - return ( -
- {/* Main track container */} -
- {/* Cover Art */} - {metadata.image && ( -
- {metadata.alt -
- )} - - {/* Track Info */} -
-

{metadata.title}

- - {metadata.artist && ( -

- {t('music.by')} {metadata.artist} -

- )} - - {metadata.album && ( -

- {t('music.album')}: {metadata.album} - {metadata.trackNumber && ` • ${t('music.track')} ${metadata.trackNumber}`} -

- )} - - {metadata.releaseDate && ( -

- {t('music.released')}: {dayjs(metadata.releaseDate).format('MMMM D, YYYY')} -

- )} - - {/* Audio Player */} -
- -
- - {/* Show lyrics if they exist */} - {metadata.lyrics && ( -
-

- {metadata.lyrics} -

-
- )} - - {/* Show credits if they exist */} - {metadata.credits && ( -
-

- {t('music.credits')}:
- {metadata.credits} -

-
- )} - - - -
-
- - - {/* License and Metadata Footer */} -
- {metadata.license && ( -

- {t('music.license')}: {metadata.license} -

- )} - - {/* Only show alt if it's different from what we've shown - {metadata.alt && !metadata.credits && ( -

- {t('music.altText')}: {metadata.alt} -

- )} - */} - {metadata.genres.length > 0 && ( -
- {metadata.genres.map((genre, index) => ( - - {genre} - - ))} -
- )} -
-
- ) -} diff --git a/src/components/Note/index.tsx b/src/components/Note/index.tsx index 5ba064f..0d53b7a 100644 --- a/src/components/Note/index.tsx +++ b/src/components/Note/index.tsx @@ -38,7 +38,6 @@ import Reaction from './Reaction' import RelayReview from './RelayReview' import UnknownNote from './UnknownNote' import VideoNote from './VideoNote' -import MusicTrackNote from './MusicTrackNote' export default function Note({ event, @@ -125,8 +124,6 @@ export default function Note({ event.kind === ExtendedKind.ADDRESSABLE_SHORT_VIDEO ) { content = - } else if (event.kind === ExtendedKind.MUSIC_TRACK) { - content = } else if (event.kind === ExtendedKind.RELAY_REVIEW) { content = } else if (event.kind === kinds.Emojisets) { diff --git a/src/components/RelayInfo/index.tsx b/src/components/RelayInfo/index.tsx index ca18caf..0764117 100644 --- a/src/components/RelayInfo/index.tsx +++ b/src/components/RelayInfo/index.tsx @@ -148,7 +148,7 @@ function RelayControls({ url }: { url: string }) { } const handleCopyShareableUrl = () => { - navigator.clipboard.writeText(`https://nostr.basspistol.org/?r=${url}`) + navigator.clipboard.writeText(`https://jumble.social/?r=${url}`) setCopiedShareableUrl(true) toast.success('Shareable URL copied to clipboard') setTimeout(() => setCopiedShareableUrl(false), 2000) diff --git a/src/components/RelaySetCard/index.tsx b/src/components/RelaySetCard/index.tsx index 531cb04..7367bc5 100644 --- a/src/components/RelaySetCard/index.tsx +++ b/src/components/RelaySetCard/index.tsx @@ -1,6 +1,6 @@ import { cn } from '@/lib/utils' import { TRelaySet } from '@/types' -import { ChevronDown, FolderClosed, Music, Radio, Trees, DoorOpen } from 'lucide-react' +import { ChevronDown, FolderClosed } from 'lucide-react' import { useState } from 'react' import { useTranslation } from 'react-i18next' import RelayIcon from '../RelayIcon' @@ -17,21 +17,6 @@ export default function RelaySetCard({ const { t } = useTranslation() const [expand, setExpand] = useState(false) - const getRelaySetIcon = (name: string) => { - const nameLower = name.toLowerCase() - - - if (nameLower.includes('feed')) return Radio - if (nameLower.includes('music')) return Music - if (nameLower.includes('backstage')) return DoorOpen - if (nameLower.includes('hood')) return Trees - - - return FolderClosed - } - - const IconComponent = getRelaySetIcon(relaySet.name) - return (
onSelectChange(!select)} - > -
-
-
- {/* Use the dynamic icon component instead of hardcoded FolderClosed */} - -
-
{relaySet.name}
+ onClick={() => onSelectChange(!select)} + > +
+
+
+
+
{relaySet.name}
+
{t('n relays', { n: relaySet.relayUrls.length })} diff --git a/src/constants.ts b/src/constants.ts index 53a1b77..3434311 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -4,7 +4,7 @@ import { TRelaySet } from './types' export const JUMBLE_API_BASE_URL = 'https://api.jumble.social' export const RECOMMENDED_BLOSSOM_SERVERS = [ - 'https://basspistol.org', + 'https://blossom.band/', 'https://blossom.primal.net/', 'https://nostr.media/' ] @@ -78,9 +78,9 @@ export const BIG_RELAY_URLS = [ 'wss://offchain.pub/' ] -export const SEARCHABLE_RELAY_URLS = ['wss://basspistol.org/','wss://pyramid.fiatjaf.com/','wss://spatia-arcana.com/'] +export const SEARCHABLE_RELAY_URLS = ['wss://search.nos.today/', 'wss://relay.nostr.band/'] -export const TRENDING_NOTES_RELAY_URLS = ['wss://basspistol.org/uppermost'] +export const TRENDING_NOTES_RELAY_URLS = ['wss://trending.relays.land/'] export const GROUP_METADATA_EVENT_KIND = 39000 @@ -101,8 +101,7 @@ export const ExtendedKind = { RELAY_REVIEW: 31987, GROUP_METADATA: 39000, ADDRESSABLE_NORMAL_VIDEO: 34235, - ADDRESSABLE_SHORT_VIDEO: 34236, - MUSIC_TRACK: 36787 + ADDRESSABLE_SHORT_VIDEO: 34236 } export const ALLOWED_FILTER_KINDS = [ @@ -119,8 +118,7 @@ export const ALLOWED_FILTER_KINDS = [ kinds.Highlights, kinds.LongFormArticle, ExtendedKind.ADDRESSABLE_NORMAL_VIDEO, - ExtendedKind.ADDRESSABLE_SHORT_VIDEO, - ExtendedKind.MUSIC_TRACK + ExtendedKind.ADDRESSABLE_SHORT_VIDEO ] export const SUPPORTED_KINDS = [ @@ -204,16 +202,16 @@ export const PRIMARY_COLORS = { DEFAULT: { name: 'Default', light: { - primary: '30 100% 50%', - 'primary-hover': '30 100% 60%', + primary: '259 43% 56%', + 'primary-hover': '259 43% 65%', 'primary-foreground': '0 0% 98%', - ring: '30 100% 50%' + ring: '259 43% 56%' }, dark: { - primary: '30 100% 50%', - 'primary-hover': '30 100% 60%', + primary: '259 43% 56%', + 'primary-hover': '259 43% 65%', 'primary-foreground': '240 5.9% 10%', - ring: '30 100% 50%' + ring: '259 43% 56%' } }, RED: { @@ -232,18 +230,18 @@ export const PRIMARY_COLORS = { } }, ORANGE: { - name: 'Lavender', + name: 'Orange', light: { - primary: '259 43% 56%', - 'primary-hover': '259 43% 65%', + primary: '30 100% 50%', + 'primary-hover': '30 100% 60%', 'primary-foreground': '0 0% 98%', - ring: '259 43% 56%' + ring: '30 100% 50%' }, dark: { - primary: '259 43% 56%', - 'primary-hover': '259 43% 65%', + primary: '30 100% 50%', + 'primary-hover': '30 100% 60%', 'primary-foreground': '240 5.9% 10%', - ring: '259 43% 56%' + ring: '30 100% 50%' } }, AMBER: { diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts index 8703149..6e3c18f 100644 --- a/src/i18n/locales/en.ts +++ b/src/i18n/locales/en.ts @@ -686,18 +686,6 @@ export default { 'Allow insecure connections description': 'Allow loading http:// resources and connecting to ws:// relays. May trigger browser mixed content warnings.', 'reacted to': 'reacted to', - Reaction: 'Reaction', - music: { - untitled: 'Untitled Track', - by: 'by', - album: 'Album', - track: 'Track', - released: 'Released', - license: 'License', - altText: 'Credit', - credits: 'Credits', // Add this - showLyrics: 'Show Lyrics', // Add this (optional) - noAudioUrl: 'No audio URL provided for this track', - } + Reaction: 'Reaction' } } diff --git a/src/index.css b/src/index.css index 07b6650..7f5901a 100644 --- a/src/index.css +++ b/src/index.css @@ -133,12 +133,12 @@ --radius: 0.75rem; } .dark { - --surface-background: 276, 61.404%, 9%; - --background: 276, 61.404%, 11.176%; + --surface-background: 240 10% 3.9%; + --background: 0 0% 9%; --foreground: 0 0% 98%; - --card: 276, 61.404%, 10%; + --card: 0 0% 12%; --card-foreground: 0 0% 98%; - --popover: 276, 61.404%, 10%; + --popover: 0 0% 12%; --popover-foreground: 0 0% 98%; --primary: 259 43% 56%; --primary-hover: 259 43% 65%; diff --git a/src/lib/link.ts b/src/lib/link.ts index c84b2a5..c7c868d 100644 --- a/src/lib/link.ts +++ b/src/lib/link.ts @@ -9,7 +9,7 @@ export const toNote = (eventOrId: Event | string) => { return `/notes/${nevent}` } export const toJumbleNote = (eventOrId: Event | string) => { - return `https://nostr.basspistol.org${toNote(eventOrId)}` + return `https://jumble.social${toNote(eventOrId)}` } export const toNoteList = ({ hashtag, diff --git a/src/pages/primary/NoteListPage/FeedButton.tsx b/src/pages/primary/NoteListPage/FeedButton.tsx index f5463e5..42dfa76 100644 --- a/src/pages/primary/NoteListPage/FeedButton.tsx +++ b/src/pages/primary/NoteListPage/FeedButton.tsx @@ -8,7 +8,7 @@ import { cn } from '@/lib/utils' import { useFavoriteRelays } from '@/providers/FavoriteRelaysProvider' import { useFeed } from '@/providers/FeedProvider' import { useScreenSize } from '@/providers/ScreenSizeProvider' -import { ChevronDown, Server, Star, UsersRound, Music, Radio, Trees, DoorOpen } from 'lucide-react' +import { ChevronDown, Server, Star, UsersRound } from 'lucide-react' import { forwardRef, HTMLAttributes, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -90,25 +90,13 @@ const FeedSwitcherTrigger = forwardRef { if (feedInfo?.feedType === 'following') return - if (feedInfo?.feedType === 'pinned') return - if (feedInfo?.feedType === 'relay' && feedInfo.id) { - return - } - if (feedInfo?.feedType === 'relays') { - const relaySetName = feedInfo.name ?? activeRelaySet?.name ?? activeRelaySet?.id ?? '' - const nameLower = relaySetName.toLowerCase() + if (feedInfo?.feedType === 'pinned') return + if (feedInfo?.feedType === 'relay' && feedInfo.id) { + return + } - // Custom icons for your relay sets - if (nameLower.includes('feed')) return - if (nameLower.includes('music')) return - if (nameLower.includes('backstage')) return - if (nameLower.includes('hood')) return - - // Default relay set icon - return - } - return - }, [feedInfo, activeRelaySet]) + return + }, [feedInfo]) const clickable = !IS_COMMUNITY_MODE || COMMUNITY_RELAY_SETS.length + COMMUNITY_RELAYS.length > 1 diff --git a/vite.config.ts b/vite.config.ts index a81cdfa..18130c3 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -59,8 +59,8 @@ export default defineConfig(({ mode }) => { enabled: true }, manifest: { - name: 'Bpistle', - short_name: 'Bpistle', + name: 'Jumble', + short_name: 'Jumble', icons: [ { src: '/pwa-512x512.png',