feat: Moved global and nsfw section to home page
This commit is contained in:
parent
f7b3dad4ac
commit
252612e7df
20
package.json
20
package.json
@ -12,36 +12,36 @@
|
|||||||
"analyze": "vite-bundle-visualizer"
|
"analyze": "vite-bundle-visualizer"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nostr-dev-kit/ndk": "^2.4.2",
|
"@nostr-dev-kit/ndk": "^2.5.0",
|
||||||
"@nostr-dev-kit/ndk-cache-dexie": "^2.2.6",
|
"@nostr-dev-kit/ndk-cache-dexie": "^2.2.7",
|
||||||
"@tanstack/react-query": "^5.22.2",
|
"@tanstack/react-query": "^5.24.8",
|
||||||
"bech32": "^2.0.0",
|
"bech32": "^2.0.0",
|
||||||
"jotai": "^2.6.5",
|
"jotai": "^2.7.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"nostr-tools": "^2.3.1",
|
"nostr-tools": "^2.3.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-lazy-load": "^4.0.1",
|
"react-lazy-load": "^4.0.1",
|
||||||
"react-router-dom": "^6.22.1",
|
"react-router-dom": "^6.22.2",
|
||||||
"react-swipeable": "^7.0.1"
|
"react-swipeable": "^7.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash": "^4.14.202",
|
"@types/lodash": "^4.14.202",
|
||||||
"@types/react": "^18.2.57",
|
"@types/react": "^18.2.63",
|
||||||
"@types/react-dom": "^18.2.19",
|
"@types/react-dom": "^18.2.19",
|
||||||
"@types/react-helmet": "^6.1.11",
|
"@types/react-helmet": "^6.1.11",
|
||||||
"@types/react-swipeable": "^5.2.0",
|
"@types/react-swipeable": "^5.2.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.0.2",
|
"@typescript-eslint/eslint-plugin": "^7.1.1",
|
||||||
"@typescript-eslint/parser": "^7.0.2",
|
"@typescript-eslint/parser": "^7.1.1",
|
||||||
"@vitejs/plugin-react": "^4.2.1",
|
"@vitejs/plugin-react": "^4.2.1",
|
||||||
"@webbtc/webln-types": "^3.0.0",
|
"@webbtc/webln-types": "^3.0.0",
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0",
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
"eslint-plugin-react-refresh": "^0.4.5",
|
"eslint-plugin-react-refresh": "^0.4.5",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"vite": "^5.1.4",
|
"vite": "^5.1.5",
|
||||||
"vite-bundle-visualizer": "^1.0.1"
|
"vite-bundle-visualizer": "^1.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,6 @@ h1 {
|
|||||||
button {
|
button {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
padding: 0.6em 1.2em;
|
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
|
@ -30,7 +30,6 @@ const GridView = ({ settings, images, currentImage, setCurrentImage, setViewMode
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onKeyDown = (event: KeyboardEvent) => {
|
const onKeyDown = (event: KeyboardEvent) => {
|
||||||
console.log(event);
|
|
||||||
|
|
||||||
if (event.key === 'ArrowRight') {
|
if (event.key === 'ArrowRight') {
|
||||||
showNextImage();
|
showNextImage();
|
||||||
|
@ -4,9 +4,11 @@ import './Home.css';
|
|||||||
import { useGlobalState } from '../../utils/globalState';
|
import { useGlobalState } from '../../utils/globalState';
|
||||||
import usePeopleLists from '../../utils/useLists';
|
import usePeopleLists from '../../utils/useLists';
|
||||||
import { createImgProxyUrl } from '../nostrImageDownload';
|
import { createImgProxyUrl } from '../nostrImageDownload';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
const { nav, currentSettings } = useNav();
|
const { nav, currentSettings } = useNav();
|
||||||
|
const [showAdult, setShowAdult] = useState(currentSettings.showAdult || false);
|
||||||
const [state] = useGlobalState();
|
const [state] = useGlobalState();
|
||||||
const topicKeys = Object.keys(topics);
|
const topicKeys = Object.keys(topics);
|
||||||
const lists = usePeopleLists(state.userNPub);
|
const lists = usePeopleLists(state.userNPub);
|
||||||
@ -18,17 +20,34 @@ const Home = () => {
|
|||||||
<div className="topics">
|
<div className="topics">
|
||||||
{topicKeys.map(tk => (
|
{topicKeys.map(tk => (
|
||||||
<div
|
<div
|
||||||
|
key={tk}
|
||||||
className="topic"
|
className="topic"
|
||||||
style={{
|
style={{
|
||||||
backgroundImage: `linear-gradient(170deg, rgba(0, 0, 0, .8) 0%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0) 100%), url(${createImgProxyUrl('https://slidestr.net/images/'+tk+'.jpg', 600, -1)})`,
|
backgroundImage: `linear-gradient(170deg, rgba(0, 0, 0, .8) 0%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0) 100%), url(${createImgProxyUrl('https://slidestr.net/images/' + tk + '.jpg', 600, -1)})`,
|
||||||
}}
|
}}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
nav({ ...currentSettings, topic: tk, npubs: [], tags: [], list: undefined, follows: false })
|
nav({ ...currentSettings, topic: tk, npubs: [], tags: [], list: undefined, follows: false, showAdult })
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="topic-title">{topics[tk].name || tk}</div>
|
<div className="topic-title">{topics[tk].name || tk}</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
<div
|
||||||
|
className="topic"
|
||||||
|
onClick={() =>
|
||||||
|
nav({
|
||||||
|
tags: [],
|
||||||
|
npubs: [],
|
||||||
|
showReplies: false,
|
||||||
|
showReposts: false,
|
||||||
|
follows: false,
|
||||||
|
showAdult,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div className="topic-title">Global</div>
|
||||||
|
<div>All content posted on nostr. Use with care!</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{state.userNPub && (
|
{state.userNPub && (
|
||||||
<>
|
<>
|
||||||
@ -47,6 +66,7 @@ const Home = () => {
|
|||||||
follows: true,
|
follows: true,
|
||||||
showReplies: false,
|
showReplies: false,
|
||||||
showReposts: true,
|
showReposts: true,
|
||||||
|
showAdult,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@ -60,18 +80,37 @@ const Home = () => {
|
|||||||
<div className="topics">
|
<div className="topics">
|
||||||
{lists.map(l => (
|
{lists.map(l => (
|
||||||
<div
|
<div
|
||||||
|
key={l.nevent}
|
||||||
className="topic"
|
className="topic"
|
||||||
style={{}}
|
style={{}}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
nav({ ...currentSettings, tags: [], npubs: [], list: l.nevent, topic: undefined, follows: false })
|
nav({
|
||||||
|
...currentSettings,
|
||||||
|
tags: [],
|
||||||
|
npubs: [],
|
||||||
|
list: l.nevent,
|
||||||
|
topic: undefined,
|
||||||
|
follows: false,
|
||||||
|
showAdult,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="topic-title">{l.name}</div>
|
<div className="topic-title">{l.name}</div>
|
||||||
|
{l.description && <div>{l.description}</div>}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
<div className={`content-warning ${showAdult ? 'active' : ''}`} style={{ marginTop: '5em' }}>
|
||||||
|
<div>
|
||||||
|
<input name="adult" type="checkbox" checked={showAdult} onChange={() => setShowAdult(sa => !sa)} />
|
||||||
|
</div>
|
||||||
|
<label htmlFor="adult" onClick={() => setShowAdult(sa => !sa)} style={{ userSelect: 'none' }}>
|
||||||
|
<div className="warning">NSFW / adult content</div>
|
||||||
|
Allow adult content to be shown and ignore content warnings.
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<div className="footer">
|
<div className="footer">
|
||||||
Made with 💜 by{' '}
|
Made with 💜 by{' '}
|
||||||
<a href="https://njump.me/npub1klr0dy2ul2dx9llk58czvpx73rprcmrvd5dc7ck8esg8f8es06qs427gxc" target="blank">
|
<a href="https://njump.me/npub1klr0dy2ul2dx9llk58czvpx73rprcmrvd5dc7ck8esg8f8es06qs427gxc" target="blank">
|
||||||
|
@ -55,16 +55,17 @@
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
.login-dialog .login-address button {
|
|
||||||
|
.login-dialog button,
|
||||||
|
.login-dialog button:visited,
|
||||||
|
.login-dialog button:active {
|
||||||
background-color: rgb(99, 19, 173);
|
background-color: rgb(99, 19, 173);
|
||||||
}
|
color: #fff;
|
||||||
.login-dialog .login-extension {
|
height: 3em;
|
||||||
align-self: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-dialog .login-extension button {
|
.login-dialog .login-extension {
|
||||||
height: 3em;
|
align-self: center;
|
||||||
background-color: rgb(99, 19, 173);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-dialog .close-button {
|
.login-dialog .close-button {
|
||||||
|
@ -82,7 +82,7 @@ const MasonryImage = ({ image, onClick, index }: MasonryImageProps) => {
|
|||||||
)}
|
)}
|
||||||
</a>
|
</a>
|
||||||
{(showAuthor || description || showTags.length > 0) && (
|
{(showAuthor || description || showTags.length > 0) && (
|
||||||
<div style={{ display: 'block', lineHeight: '1.4em', paddingBottom: '.5em', paddingTop: '.5em', position: 'relative' }}>
|
<div className="info-section">
|
||||||
<div className="time">{image.timestamp && timeDifference(now, image.timestamp)}</div>
|
<div className="time">{image.timestamp && timeDifference(now, image.timestamp)}</div>
|
||||||
{showAuthor && (
|
{showAuthor && (
|
||||||
<div style={{ paddingBottom: '.25em' }}>
|
<div style={{ paddingBottom: '.25em' }}>
|
||||||
|
@ -64,6 +64,14 @@
|
|||||||
outline: 1px solid #fff;
|
outline: 1px solid #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mason-imagegrid .info-section {
|
||||||
|
display: block;
|
||||||
|
line-height: 1.4em;
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
padding-top: 0.5em;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
.profile-header {
|
.profile-header {
|
||||||
padding: 1.2em;
|
padding: 1.2em;
|
||||||
padding-bottom: 0.6em;
|
padding-bottom: 0.6em;
|
||||||
@ -95,9 +103,9 @@
|
|||||||
.mason-imagegrid .time {
|
.mason-imagegrid .time {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
top:0px;
|
top: 0px;
|
||||||
color: #666;
|
color: #666;
|
||||||
padding-top: .5em;
|
padding-top: 0.5em;
|
||||||
background-color: #111;
|
background-color: #111;
|
||||||
padding-left: .4em;
|
padding-left: 0.4em;
|
||||||
}
|
}
|
@ -81,15 +81,25 @@
|
|||||||
.content-warning {
|
.content-warning {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
border: 1px solid #ff563f;
|
border: 1px solid #444;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.warning {
|
.content-warning.active {
|
||||||
|
border: 1px solid #ff563f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-warning.active .warning {
|
||||||
color: #ff563f;
|
color: #ff563f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-warning .warning {
|
||||||
|
color: #444;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings .replies,
|
.settings .replies,
|
||||||
|
@ -182,7 +182,7 @@ const SettingsDialog = ({ onClose, setViewMode }: SettingsProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<div className="content-warning">
|
<div className={`content-warning ${showAdult ? 'active' : ''}`}>
|
||||||
<div>
|
<div>
|
||||||
<input name="adult" type="checkbox" checked={showAdult} onChange={e => setShowAdult(e.target.checked)} />
|
<input name="adult" type="checkbox" checked={showAdult} onChange={e => setShowAdult(e.target.checked)} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -91,19 +91,34 @@ const SlideShow = () => {
|
|||||||
const listAuthors = useAuthorsFromList(settings.list);
|
const listAuthors = useAuthorsFromList(settings.list);
|
||||||
const [contacts] = useAtom(followsAtom);
|
const [contacts] = useAtom(followsAtom);
|
||||||
|
|
||||||
const authorsToQuery = settings.follows
|
const filter = useMemo(() => {
|
||||||
? contacts?.tags.filter(t => t[0] === 'p').map(t => t[1]) || []
|
const authorsToQuery = settings.follows
|
||||||
: listAuthors && listAuthors.length > 0
|
? contacts?.tags.filter(t => t[0] === 'p').map(t => t[1]) || []
|
||||||
? listAuthors
|
: listAuthors && listAuthors.length > 0
|
||||||
: settings.npubs.map(p => nip19.decode(p).data as string);
|
? listAuthors
|
||||||
|
: settings.npubs.map(p => nip19.decode(p).data as string);
|
||||||
|
|
||||||
const filterTags = settings.topic ? topics[settings.topic].tags : settings.tags;
|
const filterTags = settings.topic ? topics[settings.topic].tags : settings.tags;
|
||||||
|
|
||||||
const { events } = useEvents(buildFilter(filterTags, authorsToQuery, settings.showReposts), {
|
return buildFilter(filterTags, authorsToQuery, settings.showReposts);
|
||||||
|
}, [
|
||||||
|
contacts?.tags,
|
||||||
|
listAuthors,
|
||||||
|
settings.follows,
|
||||||
|
settings.npubs,
|
||||||
|
settings.showReposts,
|
||||||
|
settings.tags,
|
||||||
|
settings.topic,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const { events } = useEvents(filter, {
|
||||||
cacheUsage: NDKSubscriptionCacheUsage.PARALLEL,
|
cacheUsage: NDKSubscriptionCacheUsage.PARALLEL,
|
||||||
|
// when seeing global, close stream because of too many updates.
|
||||||
|
closeOnEose: settings.npubs.length == 0 && settings.tags.length == 0
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// console.log('set posts');
|
||||||
setPosts(
|
setPosts(
|
||||||
events
|
events
|
||||||
.filter(
|
.filter(
|
||||||
|
@ -47,7 +47,19 @@ export const topics: { [key: string]: Topic } = {
|
|||||||
},
|
},
|
||||||
lifestyle: {
|
lifestyle: {
|
||||||
name: 'Lifestyle',
|
name: 'Lifestyle',
|
||||||
tags: ['fashion', 'flowerstr', 'foodstr', 'style', 'weedstr', 'travel', 'travelstr', 'happy', 'life', 'love'],
|
tags: [
|
||||||
|
'fashion',
|
||||||
|
'flowerstr',
|
||||||
|
'foodstr',
|
||||||
|
'style',
|
||||||
|
'weedstr',
|
||||||
|
'travel',
|
||||||
|
'travelstr',
|
||||||
|
'happy',
|
||||||
|
'life',
|
||||||
|
'love',
|
||||||
|
'hiking',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
gardenandfarm: { name: 'Gardening und Farming', tags: ['gardening', 'gardenstr', 'nature', 'farming', 'farmstr'] },
|
gardenandfarm: { name: 'Gardening und Farming', tags: ['gardening', 'gardenstr', 'nature', 'farming', 'farmstr'] },
|
||||||
};
|
};
|
||||||
@ -132,6 +144,7 @@ export const adultContentTags = [
|
|||||||
'nakedart',
|
'nakedart',
|
||||||
'nasstr',
|
'nasstr',
|
||||||
'nodestr',
|
'nodestr',
|
||||||
|
'naughty',
|
||||||
'nsfw',
|
'nsfw',
|
||||||
'nude',
|
'nude',
|
||||||
'nudeart',
|
'nudeart',
|
||||||
@ -240,6 +253,7 @@ export const adultNPubs = [
|
|||||||
'npub1ylrnf0xfp9wsmqthxlqjqyqj9yy27pnchjwjq93v3mq66ts7ftjs6x7dcq', // Welcome To The Jungle
|
'npub1ylrnf0xfp9wsmqthxlqjqyqj9yy27pnchjwjq93v3mq66ts7ftjs6x7dcq', // Welcome To The Jungle
|
||||||
'npub1z0xv9t5w6evrcg860kmgqq5tfj55mz84ta40uszjnfp9uhw2clkq63yrak', // ???
|
'npub1z0xv9t5w6evrcg860kmgqq5tfj55mz84ta40uszjnfp9uhw2clkq63yrak', // ???
|
||||||
'npub1f3n7hq0a6vyfsjrv9vfdwtasa0g98ve96he68rxsvq9x6cl8tvxqmv6ca4', // Lady Sex (nude anime)
|
'npub1f3n7hq0a6vyfsjrv9vfdwtasa0g98ve96he68rxsvq9x6cl8tvxqmv6ca4', // Lady Sex (nude anime)
|
||||||
|
'npub1ylq5s3xsdmzgzvgzll6ghcs3qa8a9ajl955hj4tcpmyruvjsl8nq5wqhd8', // Dnera
|
||||||
|
|
||||||
'npub1t07mr7m65lg3ecr5eapu6qe4ayt2wgjpqjs8x58m5kx2r2cutsyqyzzzs9', // NOT NSFW but spammy ai pictures
|
'npub1t07mr7m65lg3ecr5eapu6qe4ayt2wgjpqjs8x58m5kx2r2cutsyqyzzzs9', // NOT NSFW but spammy ai pictures
|
||||||
'npub1curnt7jtq8mhl9fcswnwvuvc9ccm6lvsdv4kzydx75v92kldrvdqh7sq09', // NOT NSFW but spammy ai pictures
|
'npub1curnt7jtq8mhl9fcswnwvuvc9ccm6lvsdv4kzydx75v92kldrvdqh7sq09', // NOT NSFW but spammy ai pictures
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { NDKEvent, NDKFilter, NDKTag } from '@nostr-dev-kit/ndk';
|
import { NDKEvent, NDKFilter, NDKTag } from '@nostr-dev-kit/ndk';
|
||||||
import { adultContentTags, adultPublicKeys, mixedAdultNPubs } from './env';
|
import { adultContentTags, adultPublicKeys, mixedAdultNPubs } from './env';
|
||||||
import uniq from 'lodash/uniq';
|
import uniq from 'lodash/uniq';
|
||||||
|
import { unixNow } from '../ngine/time';
|
||||||
|
|
||||||
export type Post = {
|
export type Post = {
|
||||||
event: NDKEvent;
|
event: NDKEvent;
|
||||||
@ -23,7 +24,7 @@ export type NostrImage = {
|
|||||||
export const buildFilter = (tags: string[], authors: string[], withReposts = false) => {
|
export const buildFilter = (tags: string[], authors: string[], withReposts = false) => {
|
||||||
const filter: NDKFilter = {
|
const filter: NDKFilter = {
|
||||||
kinds: [1, 1063] as number[],
|
kinds: [1, 1063] as number[],
|
||||||
limit: authors.length > 0 ? 1000 : 500,
|
limit: authors.length > 0 ? 1000 : tags.length > 0 ? 500 : 500,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (withReposts) {
|
if (withReposts) {
|
||||||
@ -32,10 +33,10 @@ export const buildFilter = (tags: string[], authors: string[], withReposts = fal
|
|||||||
|
|
||||||
if (authors && authors.length > 0) {
|
if (authors && authors.length > 0) {
|
||||||
filter.authors = authors;
|
filter.authors = authors;
|
||||||
|
} else if (tags && tags.length > 0) {
|
||||||
|
filter['#t'] = tags;
|
||||||
} else {
|
} else {
|
||||||
if (tags && tags.length > 0) {
|
filter.since = unixNow() - 60 * 60 * 24; // 24h
|
||||||
filter['#t'] = tags;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('filter', filter);
|
// console.log('filter', filter);
|
||||||
@ -67,6 +68,8 @@ export const urlFix = (url: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const extractImageUrls = (text: string): string[] => {
|
export const extractImageUrls = (text: string): string[] => {
|
||||||
|
if (text == undefined) return [];
|
||||||
|
|
||||||
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
||||||
const matchedUrls = (text.match(urlRegex) || []).map(u => urlFix(u));
|
const matchedUrls = (text.match(urlRegex) || []).map(u => urlFix(u));
|
||||||
return uniq(matchedUrls);
|
return uniq(matchedUrls);
|
||||||
|
@ -15,16 +15,18 @@ export default function useEvents(filter: NDKFilter | NDKFilter[], opts?: Subscr
|
|||||||
const [eose, setEose] = useState(false);
|
const [eose, setEose] = useState(false);
|
||||||
const [events, setEvents] = useState<NDKEvent[]>([]);
|
const [events, setEvents] = useState<NDKEvent[]>([]);
|
||||||
const id = useMemo(() => {
|
const id = useMemo(() => {
|
||||||
|
console.warn('new ID!!!');
|
||||||
return hashSha256(filter);
|
return hashSha256(filter);
|
||||||
}, [filter]);
|
}, [filter]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (filter && !opts?.disable) {
|
if (filter && !opts?.disable) {
|
||||||
console.log('useEvents: new Subscription');
|
// console.log('useEvents: new Subscription', filter, opts);
|
||||||
setEvents([]);
|
setEvents([]);
|
||||||
const relaySet = relays?.length ?? 0 > 0 ? NDKRelaySet.fromRelayUrls(relays as string[], ndk) : undefined;
|
const relaySet = relays?.length ?? 0 > 0 ? NDKRelaySet.fromRelayUrls(relays as string[], ndk) : undefined;
|
||||||
const sub = ndk.subscribe(filter, opts, relaySet);
|
const sub = ndk.subscribe(filter, opts, relaySet);
|
||||||
sub.on('event', (ev: NDKEvent) => {
|
sub.on('event', (ev: NDKEvent) => {
|
||||||
|
// console.log('new event ');
|
||||||
setEvents(evs => {
|
setEvents(evs => {
|
||||||
const newEvents = evs.concat([ev]).sort((a, b) => (b.created_at ?? 0) - (a.created_at ?? 0));
|
const newEvents = evs.concat([ev]).sort((a, b) => (b.created_at ?? 0) - (a.created_at ?? 0));
|
||||||
return uniqBy(newEvents, (e: NDKEvent) => e.tagId());
|
return uniqBy(newEvents, (e: NDKEvent) => e.tagId());
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
import { useMemo } from 'react';
|
||||||
import useEvent from '../ngine/hooks/useEvent';
|
import useEvent from '../ngine/hooks/useEvent';
|
||||||
import { nip19 } from 'nostr-tools';
|
import { nip19 } from 'nostr-tools';
|
||||||
|
|
||||||
const useAuthorsFromList = (listAddr?: string) => {
|
const useAuthorsFromList = (listAddr?: string): string[] => {
|
||||||
const validListAttr = listAddr?.indexOf('naddr') == 0;
|
const validListAttr = listAddr?.indexOf('naddr') == 0;
|
||||||
const addr = listAddr ? (nip19.decode(listAddr).data as nip19.AddressPointer) : undefined;
|
const addr = listAddr ? (nip19.decode(listAddr).data as nip19.AddressPointer) : undefined;
|
||||||
const addrIsDefined = addr && addr.pubkey && addr.identifier;
|
const addrIsDefined = addr && addr.pubkey && addr.identifier;
|
||||||
@ -13,13 +14,17 @@ const useAuthorsFromList = (listAddr?: string) => {
|
|||||||
{ kinds: [30000], authors: authorFilter, '#d': identFilter },
|
{ kinds: [30000], authors: authorFilter, '#d': identFilter },
|
||||||
{ disable: !validListAttr && !addrIsDefined }
|
{ disable: !validListAttr && !addrIsDefined }
|
||||||
);
|
);
|
||||||
const authors: string[] =
|
|
||||||
(validListAttr &&
|
const authors: string[] = useMemo(() => {
|
||||||
listEvent
|
return (
|
||||||
?.getMatchingTags('p')
|
(validListAttr &&
|
||||||
.map(t => t[1])
|
listEvent
|
||||||
.flat()) ||
|
?.getMatchingTags('p')
|
||||||
[];
|
.map(t => t[1])
|
||||||
|
.flat()) ||
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
}, [listEvent, validListAttr]);
|
||||||
|
|
||||||
return authors;
|
return authors;
|
||||||
};
|
};
|
||||||
|
@ -16,10 +16,14 @@ const usePeopleLists = (npub?: string) => {
|
|||||||
|
|
||||||
return eventsWithName.map(e => {
|
return eventsWithName.map(e => {
|
||||||
const nameTag = e.getMatchingTags('d').slice(0, 1).flat();
|
const nameTag = e.getMatchingTags('d').slice(0, 1).flat();
|
||||||
const name = nameTag ? nameTag[1] : 'unknown';
|
const titleTag = e.getMatchingTags('title').slice(0, 1).flat();
|
||||||
|
const descriptionTag = e.getMatchingTags('description').slice(0, 1).flat();
|
||||||
|
|
||||||
|
const name = titleTag.length>0 ? titleTag[1] : nameTag ? nameTag[1] : 'unknown';
|
||||||
|
const description = descriptionTag.length > 0 && descriptionTag[1];
|
||||||
const people = e.tags.filter(t => t[0] === 'p')?.map(t => t[1]);
|
const people = e.tags.filter(t => t[0] === 'p')?.map(t => t[1]);
|
||||||
|
|
||||||
return { id: e.id, nevent: e.encode(), name, people };
|
return { id: e.id, nevent: e.encode(), name, people, description };
|
||||||
});
|
});
|
||||||
}, [events]);
|
}, [events]);
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ const useNav = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const postfix = searchParams.length > 0 ? `?${searchParams.join('&')}` : '';
|
const postfix = searchParams.length > 0 ? `?${searchParams.join('&')}` : '';
|
||||||
|
console.log(settings);
|
||||||
if (settings.topic) {
|
if (settings.topic) {
|
||||||
navigate(`/topic/${settings.topic}${postfix}`);
|
navigate(`/topic/${settings.topic}${postfix}`);
|
||||||
} else if (settings.follows) {
|
} else if (settings.follows) {
|
||||||
@ -63,7 +64,7 @@ const useNav = () => {
|
|||||||
} else if (validNpubs.length == 1) {
|
} else if (validNpubs.length == 1) {
|
||||||
navigate(`/p/${validNpubs[0]}${postfix}`);
|
navigate(`/p/${validNpubs[0]}${postfix}`);
|
||||||
} else {
|
} else {
|
||||||
navigate(`/${postfix}`);
|
navigate(`/global${postfix}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user