mirror of
https://github.com/lumina-rocks/lumina.git
synced 2026-06-05 18:21:34 +02:00
feat: enhance layout and configuration
* Added reactStrictMode to next.config.mjs for improved performance. * Refactored RootLayout to use ClientProviders for better structure and removed unused state management for relay URLs. * Introduced metadata for the application in RootLayout. * Cleaned up Home component by removing unnecessary useEffect for document title. * Added new ProfilePageComponent and providers.tsx for better component organization. * Updated TrendingImagesNew and Search components for improved functionality and code clarity.
This commit is contained in:
0
components/ProfilePageComponent.tsx
Normal file
0
components/ProfilePageComponent.tsx
Normal file
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { queryProfile } from "nostr-tools/nip05"
|
||||
@@ -18,20 +20,17 @@ export function Search() {
|
||||
let value = inputValue.trim();
|
||||
value = value.replaceAll('nostr:', '');
|
||||
|
||||
if (value.startsWith('npub')) { // npub Search
|
||||
// window.location.href = `/profile/${inputValue}`;
|
||||
if (value.startsWith('npub')) {
|
||||
router.push(`/profile/${value}`);
|
||||
} else if (value.startsWith('#')) { // Hashtag Search
|
||||
// window.location.href = `/tag/${inputValue.replaceAll('#', '')}`;
|
||||
} else if (value.startsWith('#')) {
|
||||
router.push(`/tag/${value.replaceAll('#', '')}`);
|
||||
} else if(value.includes('@')) { // NIP-05 Search
|
||||
// if inputValue starts with @, then add a "_" at the beginning
|
||||
} else if(value.includes('@')) {
|
||||
if(value.startsWith('@')) {
|
||||
setInputValue('_' + value);
|
||||
}
|
||||
|
||||
let profile = await queryProfile(value);
|
||||
if(profile?.pubkey !== undefined) { // Only redirect if profile is found
|
||||
if(profile?.pubkey !== undefined) {
|
||||
router.push(`/profile/${nip19.npubEncode(profile?.pubkey)}`);
|
||||
}
|
||||
} else {
|
||||
@@ -55,9 +54,8 @@ export function Search() {
|
||||
onChange={(e) => setInputValue(e.target.value)}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
{/* <Button type="submit" onClick={calculateAndRedirect}>Search</Button> */}
|
||||
<Button type="submit" onClick={calculateAndRedirect}>
|
||||
{isLoading ? <ReloadIcon className="mr-2 h-4 w-4 animate-spin" /> : 'Search'} {/* Spinner-Komponente anzeigen, wenn geladen wird */}
|
||||
{isLoading ? <ReloadIcon className="mr-2 h-4 w-4 animate-spin" /> : 'Search'}
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { useProfile } from "nostr-react";
|
||||
import { nip19 } from "nostr-tools";
|
||||
@@ -29,10 +31,7 @@ const TrendingImageNew: React.FC<TrendingImageNewProps> = ({ event }) => {
|
||||
pubkey: event.pubkey,
|
||||
});
|
||||
|
||||
// Check if the event has nsfw or sexy tags
|
||||
const hasNsfwTag = hasNsfwContent(event.tags);
|
||||
|
||||
// State to control image blur
|
||||
const [showSensitiveContent, setShowSensitiveContent] = useState(false);
|
||||
|
||||
const npubShortened = (() => {
|
||||
@@ -44,7 +43,6 @@ const TrendingImageNew: React.FC<TrendingImageNewProps> = ({ event }) => {
|
||||
const title = userData?.username || userData?.display_name || userData?.name || userData?.npub || npubShortened;
|
||||
const text = event.content.replaceAll('\n', ' ');
|
||||
|
||||
// Get image URL from imeta tags
|
||||
const imageUrl = event.tags.find(tag => tag[0] === 'imeta' && tag[1]?.startsWith('url '))
|
||||
?.slice(1)[0]?.replace('url ', '');
|
||||
|
||||
@@ -52,7 +50,6 @@ const TrendingImageNew: React.FC<TrendingImageNewProps> = ({ event }) => {
|
||||
const hrefNote = `/note/${nip19.noteEncode(event.id)}`;
|
||||
const profileImageSrc = userData?.picture || "https://robohash.org/" + event.pubkey;
|
||||
|
||||
// Toggle sensitive content visibility
|
||||
const toggleSensitiveContent = (e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import TrendingImage from '@/components/TrendingImageNew';
|
||||
import { Spinner } from '@/components/spinner';
|
||||
@@ -6,7 +8,6 @@ export function TrendingImagesNew() {
|
||||
const [events, setEvents] = useState<any[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
// TODO: Fetch trending images from luminas own relay via http call
|
||||
fetch('https://relay.lumina.rocks/api/trending/kind20')
|
||||
.then(res => res.json())
|
||||
.then(data => setEvents(data.trending))
|
||||
@@ -20,7 +21,7 @@ export function TrendingImagesNew() {
|
||||
<h1 className="text-3xl font-bold">Currently Trending</h1>
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 mt-6">
|
||||
{events && events.length > 0 ? (
|
||||
events.map((event, index) => (
|
||||
events.map((event) => (
|
||||
<TrendingImage key={event.id} event={event} />
|
||||
))
|
||||
) : (
|
||||
|
||||
67
components/providers.tsx
Normal file
67
components/providers.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
"use client";
|
||||
|
||||
import { ReactNode, useEffect, useState } from "react";
|
||||
import { NostrProvider } from "nostr-react";
|
||||
import { ThemeProvider } from "@/components/theme-provider";
|
||||
import { TopNavigation } from "@/components/headerComponents/TopNavigation";
|
||||
import BottomBar from "@/components/BottomBar";
|
||||
import { Toaster } from "@/components/ui/toaster";
|
||||
import Umami from "@/components/Umami";
|
||||
|
||||
type ClientProvidersProps = {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
export default function ClientProviders({ children }: ClientProvidersProps) {
|
||||
const [relayUrls, setRelayUrls] = useState<string[]>([
|
||||
"wss://relay.nostr.band",
|
||||
"wss://relay.damus.io",
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
try {
|
||||
const stored = localStorage.getItem("customRelays");
|
||||
const customRelays: unknown = stored ? JSON.parse(stored) : [];
|
||||
if (Array.isArray(customRelays) && customRelays.length > 0) {
|
||||
const sanitizedRelays = customRelays
|
||||
.filter((r): r is string => typeof r === "string")
|
||||
.map((relay) => (relay.endsWith("/") ? relay.slice(0, -1) : relay));
|
||||
setRelayUrls((prev) => Array.from(new Set([...prev, ...sanitizedRelays])));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error loading custom relays:", error);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
attribute="class"
|
||||
defaultTheme="dark"
|
||||
enableSystem
|
||||
disableTransitionOnChange
|
||||
themes={[
|
||||
"light",
|
||||
"dark",
|
||||
"purple-light",
|
||||
"purple-dark",
|
||||
"vintage-light",
|
||||
"vintage-dark",
|
||||
"neo-brutalism-light",
|
||||
"neo-brutalism-dark",
|
||||
"nature-light",
|
||||
"nature-dark",
|
||||
"system",
|
||||
]}
|
||||
>
|
||||
<Umami />
|
||||
<div className="main-content pb-14">
|
||||
<NostrProvider relayUrls={relayUrls} debug={false}>
|
||||
<TopNavigation />
|
||||
<Toaster />
|
||||
{children}
|
||||
</NostrProvider>
|
||||
</div>
|
||||
<BottomBar />
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user