chore: formating and cleanup
This commit is contained in:
parent
dbd0406ce8
commit
a4bc3fd0ce
23
TODO.md
23
TODO.md
@ -1,16 +1,21 @@
|
||||
# TODO
|
||||
|
||||
- hashtag view (single hasttag), header
|
||||
- masonry, mit subtitles (user displayname, tags (most imporant), desc?, date) (ggf. nur desktop)
|
||||
- NIP 46
|
||||
- header für multiple tags??
|
||||
- follow button für user view
|
||||
- navigation entry points:
|
||||
- Curated Topics, i.e. defined hashtags -> topic view
|
||||
- Search (custom hashtags, profile search, content search, community seaarch)
|
||||
- Global
|
||||
- community view
|
||||
- community links in detail view (/masonry)
|
||||
|
||||
- Avatar display is laggy, needs caching
|
||||
- video mute icon position needs to be better arranged
|
||||
- add zap/like to the scroll view
|
||||
- grid profile: add banner/bio, maybe name to the right of the logo
|
||||
- turn settings dialog into a "search" and improve display on mbile
|
||||
- bring back the desktop view of the details dialog
|
||||
- bring back the desktop view of the details dialog (maybe!?)
|
||||
- nip-46 nsecbunker login
|
||||
- think about use of ui framework, and redesign settings dialog
|
||||
- move NSFW block list into a list event on an slidestr.net profile
|
||||
- direct link to profile (from nostrudel) should go to the grid.
|
||||
- move NSFW block list into a list event on an slidestr.net profile (public nsfw mute list)
|
||||
- Add key/salt to imageproxy, see snort impl
|
||||
- Add Follow button to profile page
|
||||
- After seleting a profile, I get to the grid for that user: How to I get back to the previous search?
|
||||
-
|
@ -2,6 +2,6 @@
|
||||
overflow: hidden;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
|
||||
|
||||
/*background-color: green; /* DEBUG colors */
|
||||
}
|
||||
|
46
src/components/AuthorProfile/AuthorProfile.css
Normal file
46
src/components/AuthorProfile/AuthorProfile.css
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
.author-info {
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
position: absolute;
|
||||
bottom: 2em;
|
||||
left: 2em;
|
||||
z-index: 200;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.author-image {
|
||||
display: block;
|
||||
transition: opacity 1s ease-in-out;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 12px;
|
||||
animation-duration: 0.5s;
|
||||
animation-timing-function: ease-in;
|
||||
animation-name: showAuthor;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.author-image {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.author-info {
|
||||
width: 80vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.author-name {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import './SlideShow.css';
|
||||
import useImageLoaded from '../utils/useImageLoaded';
|
||||
import { createImgProxyUrl } from './nostrImageDownload';
|
||||
import useNav from '../utils/useNav';
|
||||
import { ViewMode } from './SlideShow';
|
||||
import './AuthorProfile.css';
|
||||
import useImageLoaded from '../../utils/useImageLoaded';
|
||||
import { createImgProxyUrl } from '../nostrImageDownload';
|
||||
import useNav from '../../utils/useNav';
|
||||
import { ViewMode } from '../SlideShow';
|
||||
|
||||
type AvatarImageProps = {
|
||||
src?: string;
|
@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
.details {
|
||||
position: absolute;
|
||||
z-index: 500;
|
||||
@ -49,7 +47,6 @@
|
||||
display: inline;
|
||||
}
|
||||
|
||||
|
||||
.details-contents .detail-image {
|
||||
object-fit: contain;
|
||||
max-width: 100%;
|
||||
@ -134,7 +131,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.details {
|
||||
overflow-y: scroll;
|
@ -31,7 +31,7 @@ const DetailsView = ({ images, currentImage, setCurrentImage }: DetailsViewProps
|
||||
() => (currentImage !== undefined ? images[currentImage] : undefined),
|
||||
[images, currentImage]
|
||||
);
|
||||
|
||||
|
||||
const nextImageData = useMemo(
|
||||
() => (currentImage !== undefined ? images[currentImage + 1] : undefined),
|
||||
[images, currentImage]
|
@ -64,10 +64,14 @@
|
||||
}
|
||||
|
||||
.profile-header {
|
||||
padding:2em;
|
||||
padding: 2em;
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
.profile-header h2 {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.profile-header .author-info {
|
||||
position: relative;
|
||||
bottom: initial;
|
||||
|
@ -3,7 +3,7 @@ import { NostrImage, urlFix } from '../nostrImageDownload';
|
||||
import './GridView.css';
|
||||
import GridImage from './GridImage';
|
||||
import { Settings } from '../../utils/useNav';
|
||||
import AuthorProfile from '../AuthorProfile';
|
||||
import AuthorProfile from '../AuthorProfile/AuthorProfile';
|
||||
import { useSwipeable } from 'react-swipeable';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import useProfile from '../../utils/useProfile';
|
||||
@ -62,7 +62,7 @@ const GridView = ({ settings, images, currentImage, setCurrentImage, setViewMode
|
||||
|
||||
useEffect(() => {
|
||||
document.body.addEventListener('keydown', onKeyDown);
|
||||
setState({activeImage: undefined});
|
||||
setState({ activeImage: undefined });
|
||||
|
||||
if (currentImage) {
|
||||
console.log('setting hash to #g' + currentImage);
|
||||
@ -84,19 +84,18 @@ const GridView = ({ settings, images, currentImage, setCurrentImage, setViewMode
|
||||
<DetailsView images={sortedImages} currentImage={currentImage} setCurrentImage={setCurrentImage} />
|
||||
) : null}
|
||||
*/}
|
||||
{activeProfile && (
|
||||
{(activeProfile || settings.tags.length == 1) && (
|
||||
<div className="profile-header">
|
||||
<AuthorProfile
|
||||
src={urlFix(activeProfile.image || '')}
|
||||
author={activeProfile.displayName || activeProfile.name}
|
||||
npub={activeProfile.npub}
|
||||
setViewMode={setViewMode}
|
||||
></AuthorProfile>
|
||||
{/*
|
||||
<span>{activeProfile.banner}</span>
|
||||
<span>{activeProfile.bio}</span>
|
||||
{activeProfile.website}
|
||||
*/}
|
||||
{activeProfile ? (
|
||||
<AuthorProfile
|
||||
src={urlFix(activeProfile.image || '')}
|
||||
author={activeProfile.displayName || activeProfile.name}
|
||||
npub={activeProfile.npub}
|
||||
setViewMode={setViewMode}
|
||||
></AuthorProfile>
|
||||
) : (
|
||||
settings.tags.map(t => <h2>#{t}</h2>)
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
@ -1,7 +1,13 @@
|
||||
const IconSettings = () => (
|
||||
<svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M21 21L16.65 16.65M19 11C19 15.4183 15.4183 19 11 19C6.58172 19 3 15.4183 3 11C3 6.58172 6.58172 3 11 3C15.4183 3 19 6.58172 19 11Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M21 21L16.65 16.65M19 11C19 15.4183 15.4183 19 11 19C6.58172 19 3 15.4183 3 11C3 6.58172 6.58172 3 11 3C15.4183 3 19 6.58172 19 11Z"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export default IconSettings;
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { uniq } from 'lodash';
|
||||
import uniq from 'lodash/uniq';
|
||||
import { NostrImage, urlFix } from '../nostrImageDownload';
|
||||
import useNav, { Settings } from '../../utils/useNav';
|
||||
import './InfoPanel.css';
|
||||
import IconChevronDown from '../Icons/IconChevronDown';
|
||||
import { ViewMode } from '../SlideShow';
|
||||
import AuthorProfile from '../AuthorProfile';
|
||||
import AuthorProfile from '../AuthorProfile/AuthorProfile';
|
||||
import useProfile from '../../utils/useProfile';
|
||||
import { useGlobalState } from '../../utils/globalState';
|
||||
import IconLink from '../Icons/IconLink';
|
||||
@ -48,21 +48,20 @@ const InfoPanel = ({ image, onClose, setViewMode, settings }: InfoPanelProps) =>
|
||||
|
||||
{image.tags.length > 0 && (
|
||||
<div className="info-panel-tags">
|
||||
{uniq(image?.tags)
|
||||
.map(t => (
|
||||
<>
|
||||
<span
|
||||
className="tag"
|
||||
onClick={() => {
|
||||
//setCurrentImage(undefined);
|
||||
setViewMode('grid');
|
||||
nav({ ...currentSettings, tags: [t], npubs: [] });
|
||||
}}
|
||||
>
|
||||
{t}
|
||||
</span>{' '}
|
||||
</>
|
||||
))}
|
||||
{uniq(image?.tags).map(t => (
|
||||
<>
|
||||
<span
|
||||
className="tag"
|
||||
onClick={() => {
|
||||
//setCurrentImage(undefined);
|
||||
setViewMode('grid');
|
||||
nav({ ...currentSettings, tags: [t], npubs: [] });
|
||||
}}
|
||||
>
|
||||
{t}
|
||||
</span>{' '}
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<div className="info-panel-footer">
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { NostrImage, urlFix } from '../nostrImageDownload';
|
||||
import { Settings } from '../../utils/useNav';
|
||||
import AuthorProfile from '../AuthorProfile';
|
||||
import AuthorProfile from '../AuthorProfile/AuthorProfile';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import useProfile from '../../utils/useProfile';
|
||||
import ScrollImage from './ScrollImage';
|
||||
@ -47,7 +47,7 @@ const ScrollView = ({ settings, images, currentImage, setCurrentImage, setViewMo
|
||||
const { activeProfile, profileNpub, title } = useProfile(settings, state.activeImage);
|
||||
|
||||
const infoPanelAvailable = state.activeImage && (state.activeImage.content || state.activeImage.tags.length > 0);
|
||||
console.log(JSON.stringify([state?.activeImage?.content, state?.activeImage?.tags]));
|
||||
console.log(JSON.stringify([state?.activeImage?.content, state?.activeImage?.tags]));
|
||||
return (
|
||||
<div ref={containerRef} className="scrollview" tabIndex={0}>
|
||||
<Helmet>
|
@ -81,29 +81,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.author-info {
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
position: absolute;
|
||||
bottom: 2em;
|
||||
left: 2em;
|
||||
z-index: 200;
|
||||
}
|
||||
|
||||
.author-image {
|
||||
margin-bottom: 0.5em;
|
||||
display: block;
|
||||
transition: opacity 1s ease-in-out;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 12px;
|
||||
animation-duration: 0.5s;
|
||||
animation-timing-function: ease-in;
|
||||
animation-name: showAuthor;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.slide {
|
||||
position: fixed;
|
||||
@ -297,19 +274,4 @@
|
||||
.controls {
|
||||
top: 2em;
|
||||
}
|
||||
|
||||
.author-image {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.author-info {
|
||||
width: 80vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.author-name {
|
||||
display: none;
|
||||
}
|
||||
}
|
@ -24,15 +24,15 @@ import { NDKEvent } from '@nostr-dev-kit/ndk';
|
||||
import { useGlobalState } from '../utils/globalState';
|
||||
import useAutoLogin from '../utils/useAutoLogin';
|
||||
import IconUser from './Icons/IconUser';
|
||||
import ScrollView from './GridView/ScrollView';
|
||||
import ScrollView from './ScrollView/ScrollView';
|
||||
import IconPlay from './Icons/IconPlay';
|
||||
import IconGrid from './Icons/IconGrid';
|
||||
import IconFullScreen from './Icons/IconFullScreen';
|
||||
import GridView from './GridView';
|
||||
import useZapsAndReations from '../utils/useZapAndReaction';
|
||||
import IconHeart from './Icons/IconHeart';
|
||||
import IconBolt from './Icons/IconBolt';
|
||||
import IconSearch from './Icons/IconSearch';
|
||||
import GridView from './GridView';
|
||||
|
||||
// type AlbyNostr = typeof window.nostr & { enabled: boolean };
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { MutableRefObject, useEffect, useRef, useState } from 'react';
|
||||
import AuthorProfile from '../AuthorProfile';
|
||||
import AuthorProfile from '../AuthorProfile/AuthorProfile';
|
||||
import Slide from './Slide';
|
||||
import { NostrImage, urlFix } from '../nostrImageDownload';
|
||||
import useDebouncedEffect from '../../utils/useDebouncedEffect';
|
||||
|
@ -2,6 +2,25 @@ import { nip19 } from 'nostr-tools';
|
||||
|
||||
export const appName = 'slidestr.net';
|
||||
|
||||
export const topics = {
|
||||
art: ['art', 'artstr', 'beautiful', 'colorful', 'psychedelic'],
|
||||
bitcoin: ['bitcoin', 'plebchain'],
|
||||
nostr: ['coffeechain', 'nostr', 'zapathon', 'grownostr', 'freedom'],
|
||||
animals: ['catstr', 'cute', 'dogstr'],
|
||||
photography: [
|
||||
'naturephotography',
|
||||
'photo',
|
||||
'photography',
|
||||
'photos',
|
||||
'photostr',
|
||||
'picoftheday',
|
||||
'streetphotography',
|
||||
'picstr',
|
||||
],
|
||||
lifestyle: ['fashion', 'flowerstr', 'foodstr', 'style', 'weedstr', 'travel', 'travelstr', 'happy', 'life', 'love'],
|
||||
gardening: ['gardening', 'gardenstr', 'nature'],
|
||||
};
|
||||
|
||||
export const defaultHashTags = [
|
||||
'artstr',
|
||||
'catstr',
|
||||
|
@ -8,7 +8,7 @@ const useProfile = (settings: Settings, activeImage?: NostrImage) => {
|
||||
const { getProfile } = useNDK();
|
||||
const [title, setTitle] = useState(appName);
|
||||
|
||||
const profileNpub = settings.npubs.length == 1 ?settings.npubs[0] : activeImage && activeImage?.author;
|
||||
const profileNpub = settings.npubs.length == 1 ? settings.npubs[0] : activeImage && activeImage?.author;
|
||||
|
||||
const activeProfile = profileNpub && getProfile(profileNpub);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user