Compare commits

...

6 Commits

Author SHA1 Message Date
Bekbolsun
41f390cf59 hide profile menu and make non-clickable profile name & avatar on popup mode 2024-02-22 20:52:23 +06:00
artur
8c0b5f379e Make nip05 name take priority over profile.name 2024-02-22 14:21:24 +03:00
Nostr.Band
905dc7ac1b Merge pull request #112 from nostrband/feature/adaptive-styles
Feature/adaptive styles
2024-02-22 13:43:27 +03:00
artur
ca25712d20 Drop old pending requests 2024-02-22 13:07:56 +03:00
artur
051eaf001f Add 10000 kind to basic perms 2024-02-21 14:10:57 +03:00
artur
4a2362f6b9 Add 27235 kind to basic perms 2024-02-21 14:09:47 +03:00
7 changed files with 47 additions and 23 deletions

View File

@@ -14,7 +14,7 @@ export const useProfile = (npub: string) => {
const [profile, setProfile] = useState<MetaEvent | null>(null) const [profile, setProfile] = useState<MetaEvent | null>(null)
const currentKey = useAppSelector((state) => selectKeyByNpub(state, npub)) const currentKey = useAppSelector((state) => selectKeyByNpub(state, npub))
const userName = getProfileUsername(profile) || currentKey?.name const userName = currentKey?.name || getProfileUsername(profile)
const userAvatar = profile?.info?.picture || '' const userAvatar = profile?.info?.picture || ''
const avatarTitle = getFirstLetter(userName) const avatarTitle = getFirstLetter(userName)

View File

@@ -1,7 +1,7 @@
import { Avatar, Stack, Toolbar, Typography, Divider, DividerProps, styled } from '@mui/material' import { Avatar, Stack, Toolbar, Typography, Divider, DividerProps, styled } from '@mui/material'
import { StyledAppBar, StyledAppLogo, StyledAppName, StyledProfileContainer, StyledThemeButton } from './styled' import { StyledAppBar, StyledAppLogo, StyledAppName, StyledProfileContainer, StyledThemeButton } from './styled'
import { Menu } from './components/Menu' import { Menu } from './components/Menu'
import { useNavigate, useParams } from 'react-router-dom' import { useNavigate, useParams, useSearchParams } from 'react-router-dom'
import { ProfileMenu } from './components/ProfileMenu' import { ProfileMenu } from './components/ProfileMenu'
import { useProfile } from '@/hooks/useProfile' import { useProfile } from '@/hooks/useProfile'
import DarkModeIcon from '@mui/icons-material/DarkMode' import DarkModeIcon from '@mui/icons-material/DarkMode'
@@ -10,6 +10,7 @@ import { useAppDispatch, useAppSelector } from '@/store/hooks/redux'
import { setThemeMode } from '@/store/reducers/ui.slice' import { setThemeMode } from '@/store/reducers/ui.slice'
import { useSessionStorage } from 'usehooks-ts' import { useSessionStorage } from 'usehooks-ts'
import { RELOAD_STORAGE_KEY } from '@/utils/consts' import { RELOAD_STORAGE_KEY } from '@/utils/consts'
import { useCallback } from 'react'
export const Header = () => { export const Header = () => {
const themeMode = useAppSelector((state) => state.ui.themeMode) const themeMode = useAppSelector((state) => state.ui.themeMode)
@@ -17,9 +18,12 @@ export const Header = () => {
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const [needReload] = useSessionStorage(RELOAD_STORAGE_KEY, false) const [needReload] = useSessionStorage(RELOAD_STORAGE_KEY, false)
const [searchParams] = useSearchParams()
const isPopupMode = searchParams.get('popup') === 'true'
const { npub = '' } = useParams<{ npub: string }>() const { npub = '' } = useParams<{ npub: string }>()
const { userName, userAvatar, avatarTitle } = useProfile(npub) const { userName, userAvatar, avatarTitle } = useProfile(npub)
const showProfile = Boolean(npub) const isKeyPage = Boolean(npub)
const handleNavigate = () => { const handleNavigate = () => {
navigate(`/key/${npub}`) navigate(`/key/${npub}`)
@@ -32,12 +36,17 @@ export const Header = () => {
dispatch(setThemeMode({ mode: isDarkMode ? 'light' : 'dark' })) dispatch(setThemeMode({ mode: isDarkMode ? 'light' : 'dark' }))
} }
const renderMenus = useCallback(() => {
if (isPopupMode && isKeyPage) return null
return isKeyPage ? <ProfileMenu /> : <Menu />
}, [isPopupMode, isKeyPage])
return ( return (
<StyledAppBar position={needReload ? 'relative' : 'fixed'}> <StyledAppBar position={needReload ? 'relative' : 'fixed'}>
<Toolbar sx={{ padding: '12px' }}> <Toolbar sx={{ padding: '12px' }}>
<Stack direction={'row'} justifyContent={'space-between'} alignItems={'center'} width={'100%'}> <Stack direction={'row'} justifyContent={'space-between'} alignItems={'center'} width={'100%'}>
{showProfile && ( {isKeyPage && (
<StyledProfileContainer> <StyledProfileContainer nonclickable={isPopupMode}>
<Avatar src={userAvatar} alt={userName} onClick={handleNavigate} className="avatar"> <Avatar src={userAvatar} alt={userName} onClick={handleNavigate} className="avatar">
{avatarTitle} {avatarTitle}
</Avatar> </Avatar>
@@ -47,7 +56,7 @@ export const Header = () => {
</StyledProfileContainer> </StyledProfileContainer>
)} )}
{!showProfile && ( {!isKeyPage && (
<StyledAppName> <StyledAppName>
<StyledAppLogo /> <StyledAppLogo />
<span>Nsec.app</span> <span>Nsec.app</span>
@@ -56,7 +65,7 @@ export const Header = () => {
<StyledThemeButton onClick={handleChangeMode}>{themeIcon}</StyledThemeButton> <StyledThemeButton onClick={handleChangeMode}>{themeIcon}</StyledThemeButton>
{showProfile ? <ProfileMenu /> : <Menu />} {renderMenus()}
</Stack> </Stack>
</Toolbar> </Toolbar>
<StyledDivider /> <StyledDivider />

View File

@@ -32,18 +32,23 @@ export const StyledAppName = styled((props: TypographyProps) => (
marginLeft: '0.5rem', marginLeft: '0.5rem',
})) }))
export const StyledProfileContainer = styled((props: StackProps) => <Stack {...props} />)(() => ({ export const StyledProfileContainer = styled((props: StackProps & { nonclickable: boolean }) => <Stack {...props} />)(
gap: '1rem', ({ nonclickable = false }) => ({
flexDirection: 'row', gap: '1rem',
alignItems: 'center', flexDirection: 'row',
flex: 1, alignItems: 'center',
'& .avatar': { flex: 1,
cursor: 'pointer', '& .avatar': {
}, cursor: 'pointer',
'& .username': { },
cursor: 'pointer', '& .username': {
}, cursor: 'pointer',
})) },
'& > *': {
pointerEvents: nonclickable ? 'none' : 'initial',
},
})
)
export const StyledThemeButton = styled(IconButton)({ export const StyledThemeButton = styled(IconButton)({
margin: '0 0.5rem', margin: '0 0.5rem',

View File

@@ -10,7 +10,7 @@ import NDK, {
NDKSubscriptionCacheUsage, NDKSubscriptionCacheUsage,
NDKUser, NDKUser,
} from '@nostr-dev-kit/ndk' } from '@nostr-dev-kit/ndk'
import { NOAUTHD_URL, WEB_PUSH_PUBKEY, NIP46_RELAYS, MIN_POW, MAX_POW, KIND_RPC, DOMAIN } from '../utils/consts' import { NOAUTHD_URL, WEB_PUSH_PUBKEY, NIP46_RELAYS, MIN_POW, MAX_POW, KIND_RPC, DOMAIN, REQ_TTL } from '../utils/consts'
// import { Nip04 } from './nip04' // import { Nip04 } from './nip04'
import { fetchNip05, getReqPerm, getShortenNpub, isPackagePerm } from '@/utils/helpers/helpers' import { fetchNip05, getReqPerm, getShortenNpub, isPackagePerm } from '@/utils/helpers/helpers'
import { NostrPowEvent, minePow } from './pow' import { NostrPowEvent, minePow } from './pow'
@@ -310,6 +310,13 @@ export class NoauthBackend {
this.apps = await dbi.listApps() this.apps = await dbi.listApps()
console.log('started apps', this.apps) console.log('started apps', this.apps)
// drop old pending reqs
const pending = await dbi.listPending()
for (const p of pending) {
if (p.timestamp < Date.now() - REQ_TTL)
await dbi.removePending(p.id)
}
const sub = await this.swg.registration.pushManager.getSubscription() const sub = await this.swg.registration.pushManager.getSubscription()
for (const k of this.enckeys) { for (const k of this.enckeys) {

View File

@@ -1,7 +1,7 @@
import { useModalSearchParams } from '@/hooks/useModalSearchParams' import { useModalSearchParams } from '@/hooks/useModalSearchParams'
import { DbPending, DbPerm } from '@/modules/db' import { DbPending, DbPerm } from '@/modules/db'
import { MODAL_PARAMS_KEYS } from '@/types/modal' import { MODAL_PARAMS_KEYS } from '@/types/modal'
import { ACTION_TYPE } from '@/utils/consts' import { ACTION_TYPE, REQ_TTL } from '@/utils/consts'
import { useCallback, useEffect, useRef } from 'react' import { useCallback, useEffect, useRef } from 'react'
import { useSearchParams } from 'react-router-dom' import { useSearchParams } from 'react-router-dom'
@@ -25,7 +25,7 @@ export const useTriggerConfirmModal = (npub: string, pending: DbPending[], perms
const isConfirmConnectModalOpened = getModalOpened(MODAL_PARAMS_KEYS.CONFIRM_CONNECT) const isConfirmConnectModalOpened = getModalOpened(MODAL_PARAMS_KEYS.CONFIRM_CONNECT)
const isConfirmEventModalOpened = getModalOpened(MODAL_PARAMS_KEYS.CONFIRM_EVENT) const isConfirmEventModalOpened = getModalOpened(MODAL_PARAMS_KEYS.CONFIRM_EVENT)
const filteredPendingReqs = pending.filter((p) => p.npub === npub) const filteredPendingReqs = pending.filter((p) => p.npub === npub && p.timestamp > Date.now() - REQ_TTL)
const filteredPerms = perms.filter((p) => p.npub === npub) const filteredPerms = perms.filter((p) => p.npub === npub)
const npubConnectPerms = filteredPerms.filter((perm) => perm.perm === 'connect' || perm.perm === ACTION_TYPE.BASIC) const npubConnectPerms = filteredPerms.filter((perm) => perm.perm === 'connect' || perm.perm === ACTION_TYPE.BASIC)

View File

@@ -11,6 +11,8 @@ export const KIND_RPC = 24133
export const RELOAD_STORAGE_KEY = 'reload' export const RELOAD_STORAGE_KEY = 'reload'
export const REQ_TTL = 60000 // 1 min
export enum ACTION_TYPE { export enum ACTION_TYPE {
BASIC = 'basic', BASIC = 'basic',
ADVANCED = 'advanced', ADVANCED = 'advanced',

View File

@@ -16,7 +16,7 @@ export const getShortenNpub = (npub = '') => {
} }
export const getProfileUsername = (profile: MetaEvent | null) => { export const getProfileUsername = (profile: MetaEvent | null) => {
if (!profile) return null if (!profile) return undefined
return profile?.info?.name || profile?.info?.display_name return profile?.info?.name || profile?.info?.display_name
} }
@@ -72,6 +72,7 @@ export function isPackagePerm(perm: string, reqPerm: string) {
case 'sign_event:10002': case 'sign_event:10002':
case 'sign_event:30023': case 'sign_event:30023':
case 'sign_event:10000': case 'sign_event:10000':
case 'sign_event:27235':
return true return true
} }
} }