Fix app avatars, fix perm names in App page, fix time format
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Noauth",
|
"name": "Nsec.app",
|
||||||
"short_name": "Noauth Nostr key manager",
|
"short_name": "Nsec.app - Nostr key management tool",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "/android-chrome-192x192.png",
|
"src": "/android-chrome-192x192.png",
|
||||||
|
|||||||
@@ -47,8 +47,7 @@ function App() {
|
|||||||
setApps({
|
setApps({
|
||||||
apps: apps.map((app) => ({
|
apps: apps.map((app) => ({
|
||||||
...app,
|
...app,
|
||||||
// MOCK IMAGE
|
//icon: 'https://nostr.band/android-chrome-192x192.png',
|
||||||
icon: 'https://nostr.band/android-chrome-192x192.png',
|
|
||||||
})),
|
})),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useModalSearchParams } from '@/hooks/useModalSearchParams'
|
import { useModalSearchParams } from '@/hooks/useModalSearchParams'
|
||||||
import { Modal } from '@/shared/Modal/Modal'
|
import { Modal } from '@/shared/Modal/Modal'
|
||||||
import { MODAL_PARAMS_KEYS } from '@/types/modal'
|
import { MODAL_PARAMS_KEYS } from '@/types/modal'
|
||||||
import { call, getAppIconTitle, getShortenNpub, getSignReqKind } from '@/utils/helpers/helpers'
|
import { call, getAppIconTitle, getReqActionName, getShortenNpub, getSignReqKind } from '@/utils/helpers/helpers'
|
||||||
import { Avatar, Box, List, ListItem, ListItemIcon, ListItemText, Stack, Typography } from '@mui/material'
|
import { Avatar, Box, List, ListItem, ListItemIcon, ListItemText, Stack, Typography } from '@mui/material'
|
||||||
import { useParams, useSearchParams } from 'react-router-dom'
|
import { useParams, useSearchParams } from 'react-router-dom'
|
||||||
import { useAppSelector } from '@/store/hooks/redux'
|
import { useAppSelector } from '@/store/hooks/redux'
|
||||||
@@ -13,7 +13,6 @@ import { SectionTitle } from '@/shared/SectionTitle/SectionTitle'
|
|||||||
import { swicCall } from '@/modules/swic'
|
import { swicCall } from '@/modules/swic'
|
||||||
import { Checkbox } from '@/shared/Checkbox/Checkbox'
|
import { Checkbox } from '@/shared/Checkbox/Checkbox'
|
||||||
import { DbPending } from '@/modules/db'
|
import { DbPending } from '@/modules/db'
|
||||||
import { ACTIONS } from '@/utils/consts'
|
|
||||||
import { IPendingsByAppNpub } from '@/pages/KeyPage/hooks/useTriggerConfirmModal'
|
import { IPendingsByAppNpub } from '@/pages/KeyPage/hooks/useTriggerConfirmModal'
|
||||||
|
|
||||||
enum ACTION_TYPE {
|
enum ACTION_TYPE {
|
||||||
@@ -101,15 +100,6 @@ export const ModalConfirmEvent: FC<ModalConfirmEventProps> = ({ confirmEventReqs
|
|||||||
setPendingRequests(newPendingRequests)
|
setPendingRequests(newPendingRequests)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getAction = (req: PendingRequest) => {
|
|
||||||
const action = ACTIONS[req.method]
|
|
||||||
if (req.method === 'sign_event') {
|
|
||||||
const kind = getSignReqKind(req)
|
|
||||||
if (kind !== undefined) return `${action} of kind ${kind}`
|
|
||||||
}
|
|
||||||
return action
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isPopup) {
|
if (isPopup) {
|
||||||
document.addEventListener('visibilitychange', () => {
|
document.addEventListener('visibilitychange', () => {
|
||||||
if (document.visibilityState === 'hidden') {
|
if (document.visibilityState === 'hidden') {
|
||||||
@@ -154,7 +144,7 @@ export const ModalConfirmEvent: FC<ModalConfirmEventProps> = ({ confirmEventReqs
|
|||||||
<ListItemIcon>
|
<ListItemIcon>
|
||||||
<Checkbox checked={req.checked} onChange={handleChangeCheckbox(req.id)} />
|
<Checkbox checked={req.checked} onChange={handleChangeCheckbox(req.id)} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText>{getAction(req)}</ListItemText>
|
<ListItemText>{getReqActionName(req)}</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -420,8 +420,8 @@ export class NoauthBackend {
|
|||||||
const app = this.apps.find((a) => a.appNpub === r.req.appNpub)
|
const app = this.apps.find((a) => a.appNpub === r.req.appNpub)
|
||||||
if (r.req.method !== 'connect' && !app) continue
|
if (r.req.method !== 'connect' && !app) continue
|
||||||
|
|
||||||
// FIXME use Nsec.app icon!
|
// FIXME check
|
||||||
const icon = 'https://nostr.band/android-chrome-192x192.png'
|
const icon = 'assets/icons/logo.svg'
|
||||||
|
|
||||||
const appName = app?.name || getShortenNpub(r.req.appNpub)
|
const appName = app?.name || getShortenNpub(r.req.appNpub)
|
||||||
// FIXME load profile?
|
// FIXME load profile?
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { Navigate, useNavigate } from 'react-router-dom'
|
|||||||
import { formatTimestampDate } from '@/utils/helpers/date'
|
import { formatTimestampDate } from '@/utils/helpers/date'
|
||||||
import { Box, Stack, Typography } from '@mui/material'
|
import { Box, Stack, Typography } from '@mui/material'
|
||||||
import { SectionTitle } from '@/shared/SectionTitle/SectionTitle'
|
import { SectionTitle } from '@/shared/SectionTitle/SectionTitle'
|
||||||
import { getShortenNpub } from '@/utils/helpers/helpers'
|
import { getAppIconTitle, getShortenNpub } from '@/utils/helpers/helpers'
|
||||||
import { Button } from '@/shared/Button/Button'
|
import { Button } from '@/shared/Button/Button'
|
||||||
import { ACTION_TYPE } from '@/utils/consts'
|
import { ACTION_TYPE } from '@/utils/consts'
|
||||||
import { Permissions } from './components/Permissions/Permissions'
|
import { Permissions } from './components/Permissions/Permissions'
|
||||||
@@ -38,6 +38,8 @@ const AppPage = () => {
|
|||||||
|
|
||||||
const { icon = '', name = '' } = currentApp || {}
|
const { icon = '', name = '' } = currentApp || {}
|
||||||
const appName = name || getShortenNpub(appNpub)
|
const appName = name || getShortenNpub(appNpub)
|
||||||
|
const appAvatarTitle = getAppIconTitle(name, appNpub)
|
||||||
|
|
||||||
const { timestamp } = connectPerm || {}
|
const { timestamp } = connectPerm || {}
|
||||||
|
|
||||||
const connectedOn = connectPerm && timestamp ? `Connected at ${formatTimestampDate(timestamp)}` : 'Not connected'
|
const connectedOn = connectPerm && timestamp ? `Connected at ${formatTimestampDate(timestamp)}` : 'Not connected'
|
||||||
@@ -57,7 +59,9 @@ const AppPage = () => {
|
|||||||
<Stack maxHeight={'100%'} overflow={'auto'} alignItems={'flex-start'} height={'100%'}>
|
<Stack maxHeight={'100%'} overflow={'auto'} alignItems={'flex-start'} height={'100%'}>
|
||||||
<IOSBackButton onNavigate={() => navigate(`key/${npub}`)} />
|
<IOSBackButton onNavigate={() => navigate(`key/${npub}`)} />
|
||||||
<Stack marginBottom={'1rem'} direction={'row'} gap={'1rem'} width={'100%'}>
|
<Stack marginBottom={'1rem'} direction={'row'} gap={'1rem'} width={'100%'}>
|
||||||
<StyledAppIcon src={icon} />
|
<StyledAppIcon src={icon}>
|
||||||
|
{appAvatarTitle}
|
||||||
|
</StyledAppIcon>
|
||||||
<Box flex={'1'} overflow={'hidden'}>
|
<Box flex={'1'} overflow={'hidden'}>
|
||||||
<Typography variant="h4" noWrap>
|
<Typography variant="h4" noWrap>
|
||||||
{appName}
|
{appName}
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import { FC } from 'react'
|
|||||||
import { Box, IconButton, Typography } from '@mui/material'
|
import { Box, IconButton, Typography } from '@mui/material'
|
||||||
import { DbPerm } from '@/modules/db'
|
import { DbPerm } from '@/modules/db'
|
||||||
import { formatTimestampDate } from '@/utils/helpers/date'
|
import { formatTimestampDate } from '@/utils/helpers/date'
|
||||||
import { ACTIONS } from '@/utils/consts'
|
|
||||||
import { StyledPermissionItem } from './styled'
|
import { StyledPermissionItem } from './styled'
|
||||||
import ClearRoundedIcon from '@mui/icons-material/ClearRounded'
|
import ClearRoundedIcon from '@mui/icons-material/ClearRounded'
|
||||||
import DoneRoundedIcon from '@mui/icons-material/DoneRounded'
|
import DoneRoundedIcon from '@mui/icons-material/DoneRounded'
|
||||||
import MoreVertRoundedIcon from '@mui/icons-material/MoreVertRounded'
|
import MoreVertRoundedIcon from '@mui/icons-material/MoreVertRounded'
|
||||||
import { ItemPermissionMenu } from './ItemPermissionMenu'
|
import { ItemPermissionMenu } from './ItemPermissionMenu'
|
||||||
import { useOpenMenu } from '@/hooks/useOpenMenu'
|
import { useOpenMenu } from '@/hooks/useOpenMenu'
|
||||||
|
import { getPermActionName } from '@/utils/helpers/helpers'
|
||||||
|
|
||||||
type ItemPermissionProps = {
|
type ItemPermissionProps = {
|
||||||
permission: DbPerm
|
permission: DbPerm
|
||||||
@@ -26,7 +26,7 @@ export const ItemPermission: FC<ItemPermissionProps> = ({ permission }) => {
|
|||||||
<StyledPermissionItem>
|
<StyledPermissionItem>
|
||||||
<Box display={'flex'} flexDirection={'column'} gap={'0.5rem'} flex={1}>
|
<Box display={'flex'} flexDirection={'column'} gap={'0.5rem'} flex={1}>
|
||||||
<Typography flex={1} fontWeight={700}>
|
<Typography flex={1} fontWeight={700}>
|
||||||
{ACTIONS[perm] || perm}
|
{getPermActionName(permission)}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body2">{formatTimestampDate(timestamp)}</Typography>
|
<Typography variant="body2">{formatTimestampDate(timestamp)}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ import { Avatar, Stack, Typography } from '@mui/material'
|
|||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
// import ImageOutlinedIcon from '@mui/icons-material/ImageOutlined'
|
// import ImageOutlinedIcon from '@mui/icons-material/ImageOutlined'
|
||||||
import { getShortenNpub } from '@/utils/helpers/helpers'
|
import { getAppIconTitle, getShortenNpub } from '@/utils/helpers/helpers'
|
||||||
import { StyledItemAppContainer } from './styled'
|
import { StyledItemAppContainer } from './styled'
|
||||||
|
|
||||||
type ItemAppProps = DbApp
|
type ItemAppProps = DbApp
|
||||||
|
|
||||||
export const ItemApp: FC<ItemAppProps> = ({ npub, appNpub, icon, name }) => {
|
export const ItemApp: FC<ItemAppProps> = ({ npub, appNpub, icon, name }) => {
|
||||||
const appName = name || getShortenNpub(appNpub)
|
const appName = name || getShortenNpub(appNpub)
|
||||||
|
const appAvatarTitle = getAppIconTitle(name, appNpub)
|
||||||
return (
|
return (
|
||||||
<StyledItemAppContainer
|
<StyledItemAppContainer
|
||||||
direction={'row'}
|
direction={'row'}
|
||||||
@@ -19,7 +20,14 @@ export const ItemApp: FC<ItemAppProps> = ({ npub, appNpub, icon, name }) => {
|
|||||||
component={Link}
|
component={Link}
|
||||||
to={`/key/${npub}/app/${appNpub}`}
|
to={`/key/${npub}/app/${appNpub}`}
|
||||||
>
|
>
|
||||||
<Avatar variant="square" sx={{ width: 56, height: 56 }} src={icon} alt={name} />
|
<Avatar
|
||||||
|
variant="rounded"
|
||||||
|
sx={{ width: 56, height: 56 }}
|
||||||
|
src={icon}
|
||||||
|
alt={name}
|
||||||
|
>
|
||||||
|
{appAvatarTitle}
|
||||||
|
</Avatar>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Typography noWrap display={'block'} variant="body2">
|
<Typography noWrap display={'block'} variant="body2">
|
||||||
{appName}
|
{appName}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export enum ACTION_TYPE {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const ACTIONS: { [type: string]: string } = {
|
export const ACTIONS: { [type: string]: string } = {
|
||||||
|
basic: 'Basic permissions',
|
||||||
get_public_key: 'Get public key',
|
get_public_key: 'Get public key',
|
||||||
sign_event: 'Sign event',
|
sign_event: 'Sign event',
|
||||||
connect: 'Connect',
|
connect: 'Connect',
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { format } from 'date-fns'
|
|||||||
export const formatTimestampDate = (timestamp: number) => {
|
export const formatTimestampDate = (timestamp: number) => {
|
||||||
try {
|
try {
|
||||||
const date = new Date(timestamp)
|
const date = new Date(timestamp)
|
||||||
const formattedDate = format(date, "HH:mm',' dd-MM-yyyy")
|
const formattedDate = format(date, "dd-MM-yyyy HH:mm")
|
||||||
return formattedDate
|
return formattedDate
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return ''
|
return ''
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { nip19 } from 'nostr-tools'
|
import { nip19 } from 'nostr-tools'
|
||||||
import { ACTION_TYPE, NIP46_RELAYS } from '../consts'
|
import { ACTIONS, ACTION_TYPE, NIP46_RELAYS } from '../consts'
|
||||||
import { DbPending } from '@/modules/db'
|
import { DbPending, DbPerm } from '@/modules/db'
|
||||||
import { MetaEvent } from '@/types/meta-event'
|
import { MetaEvent } from '@/types/meta-event'
|
||||||
|
|
||||||
export async function call(cb: () => any) {
|
export async function call(cb: () => any) {
|
||||||
@@ -53,6 +53,25 @@ export function getSignReqKind(req: DbPending): number | undefined {
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getReqActionName(req: DbPending) {
|
||||||
|
const action = ACTIONS[req.method]
|
||||||
|
if (req.method === 'sign_event') {
|
||||||
|
const kind = getSignReqKind(req)
|
||||||
|
if (kind !== undefined) return `${action} of kind ${kind}`
|
||||||
|
}
|
||||||
|
return action
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPermActionName(req: DbPerm) {
|
||||||
|
const method = req.perm.split(':')[0]
|
||||||
|
const action = ACTIONS[method]
|
||||||
|
if (method === 'sign_event') {
|
||||||
|
const kind = req.perm.split(':')[1]
|
||||||
|
if (kind !== undefined) return `${action} of kind ${kind}`
|
||||||
|
}
|
||||||
|
return action
|
||||||
|
}
|
||||||
|
|
||||||
export function getReqPerm(req: DbPending): string {
|
export function getReqPerm(req: DbPending): string {
|
||||||
if (req.method === 'sign_event') {
|
if (req.method === 'sign_event') {
|
||||||
const kind = getSignReqKind(req)
|
const kind = getSignReqKind(req)
|
||||||
|
|||||||
Reference in New Issue
Block a user