mirror of
https://github.com/Myzel394/kleckrelay-website.git
synced 2025-06-20 08:15:26 +02:00
fixed latest alias passing between extension and instance
This commit is contained in:
parent
c71c36fcc5
commit
46f9b4b526
@ -1,29 +1,37 @@
|
|||||||
interface ExtensionKleckMessagePasswordStatus {
|
export interface ExtensionKleckMessagePasswordStatus {
|
||||||
type: "password-status"
|
type: "password-status"
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ExtensionKleckMessageAskForPassword {
|
export interface ExtensionKleckMessageAskForPassword {
|
||||||
type: "ask-for-password"
|
type: "ask-for-password"
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ExtensionKleckMessageUser {
|
export interface ExtensionKleckMessageUser {
|
||||||
type: "get-user"
|
type: "get-user"
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ExtensionKleckMessageEnterPassword {
|
export interface ExtensionKleckMessageEnterPassword {
|
||||||
type: "enter-password"
|
type: "enter-password"
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ExtensionKleckMessageRefetchAliases {
|
export interface ExtensionKleckMessageRefetchAliases {
|
||||||
type: "refetch-aliases"
|
type: "refetch-aliases"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ExtensionKleckMessageLatestAlias {
|
||||||
|
type: "latest-alias"
|
||||||
|
data: {
|
||||||
|
latestAliasId: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export type ExtensionKleckMessage =
|
export type ExtensionKleckMessage =
|
||||||
| ExtensionKleckMessagePasswordStatus
|
| ExtensionKleckMessagePasswordStatus
|
||||||
| ExtensionKleckMessageAskForPassword
|
| ExtensionKleckMessageAskForPassword
|
||||||
| ExtensionKleckMessageUser
|
| ExtensionKleckMessageUser
|
||||||
| ExtensionKleckMessageEnterPassword
|
| ExtensionKleckMessageEnterPassword
|
||||||
| ExtensionKleckMessageRefetchAliases
|
| ExtensionKleckMessageRefetchAliases
|
||||||
|
| ExtensionKleckMessageLatestAlias
|
||||||
|
|
||||||
export type ExtensionKleckEvent = MessageEvent & {
|
export type ExtensionKleckEvent = MessageEvent & {
|
||||||
detail: ExtensionKleckMessage
|
detail: ExtensionKleckMessage
|
||||||
|
@ -1,22 +1,33 @@
|
|||||||
import {useCallback} from "react"
|
import {useCallback} from "react"
|
||||||
import {useEvent} from "react-use"
|
import {useEvent} from "react-use"
|
||||||
|
|
||||||
import {ExtensionKleckEvent} from "~/extension-types"
|
import {ExtensionKleckEvent, ExtensionKleckMessageLatestAlias} from "~/extension-types"
|
||||||
|
|
||||||
export interface UseExtensionHandlerData {
|
export interface UseExtensionHandlerData {
|
||||||
onEnterPassword?: () => void
|
onEnterPassword?: () => void
|
||||||
|
onRefetchAliases?: () => void
|
||||||
|
onLatestAliasChange?: ({latestAliasId}: ExtensionKleckMessageLatestAlias["data"]) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function useExtensionHandler({onEnterPassword}: UseExtensionHandlerData): void {
|
export default function useExtensionHandler({
|
||||||
|
onEnterPassword,
|
||||||
|
onRefetchAliases,
|
||||||
|
onLatestAliasChange,
|
||||||
|
}: UseExtensionHandlerData): void {
|
||||||
const handleExtensionEvent = useCallback(
|
const handleExtensionEvent = useCallback(
|
||||||
(event: ExtensionKleckEvent) => {
|
(event: ExtensionKleckEvent) => {
|
||||||
switch (event.detail.type) {
|
switch (event.detail.type) {
|
||||||
case "enter-password":
|
case "enter-password":
|
||||||
onEnterPassword?.()
|
onEnterPassword?.()
|
||||||
break
|
break
|
||||||
|
case "refetch-aliases":
|
||||||
|
onRefetchAliases?.()
|
||||||
|
break
|
||||||
|
case "latest-alias":
|
||||||
|
onLatestAliasChange?.(event.detail.data)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[onEnterPassword],
|
[onEnterPassword, onRefetchAliases, onLatestAliasChange],
|
||||||
)
|
)
|
||||||
|
|
||||||
useEvent("kleckrelay-kleck", handleExtensionEvent)
|
useEvent("kleckrelay-kleck", handleExtensionEvent)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {ReactElement} from "react"
|
import {ReactElement} from "react"
|
||||||
import {MdContentCopy} from "react-icons/md"
|
import {MdContentCopy, MdExtension} from "react-icons/md"
|
||||||
import {Link as RouterLink} from "react-router-dom"
|
import {Link as RouterLink} from "react-router-dom"
|
||||||
|
|
||||||
import {ListItemButton, ListItemIcon, ListItemSecondaryAction, ListItemText} from "@mui/material"
|
import {ListItemButton, ListItemIcon, ListItemSecondaryAction, ListItemText} from "@mui/material"
|
||||||
@ -9,12 +9,18 @@ import {AliasList} from "~/server-types"
|
|||||||
|
|
||||||
export interface AliasesListItemProps {
|
export interface AliasesListItemProps {
|
||||||
alias: AliasList
|
alias: AliasList
|
||||||
|
|
||||||
|
showExtensionIcon?: boolean
|
||||||
onCopy?: (address: string) => void
|
onCopy?: (address: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const getAddress = (alias: AliasList): string => `${alias.local}@${alias.domain}`
|
const getAddress = (alias: AliasList): string => `${alias.local}@${alias.domain}`
|
||||||
|
|
||||||
export default function AliasesListItem({alias, onCopy}: AliasesListItemProps): ReactElement {
|
export default function AliasesListItem({
|
||||||
|
alias,
|
||||||
|
showExtensionIcon,
|
||||||
|
onCopy,
|
||||||
|
}: AliasesListItemProps): ReactElement {
|
||||||
const isInCopyAddressMode = onCopy !== undefined
|
const isInCopyAddressMode = onCopy !== undefined
|
||||||
const address = getAddress(alias)
|
const address = getAddress(alias)
|
||||||
|
|
||||||
@ -44,11 +50,19 @@ export default function AliasesListItem({alias, onCopy}: AliasesListItemProps):
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{isInCopyAddressMode && (
|
{(() => {
|
||||||
<ListItemSecondaryAction>
|
if (isInCopyAddressMode) {
|
||||||
<MdContentCopy />
|
return (
|
||||||
</ListItemSecondaryAction>
|
<ListItemSecondaryAction>
|
||||||
)}
|
<MdContentCopy />
|
||||||
|
</ListItemSecondaryAction>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showExtensionIcon) {
|
||||||
|
return <MdExtension />
|
||||||
|
}
|
||||||
|
})()}
|
||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,11 @@
|
|||||||
import {ReactElement, useState, useTransition} from "react"
|
import {ReactElement, useCallback, useEffect, useState, useTransition} from "react"
|
||||||
import {AxiosError} from "axios"
|
import {AxiosError} from "axios"
|
||||||
import {MdSearch} from "react-icons/md"
|
import {MdSearch} from "react-icons/md"
|
||||||
import {useTranslation} from "react-i18next"
|
import {useTranslation} from "react-i18next"
|
||||||
import {useCopyToClipboard, useKeyPress, useUpdateEffect} from "react-use"
|
import {useCopyToClipboard, useKeyPress, useUpdateEffect} from "react-use"
|
||||||
|
|
||||||
import {useQuery} from "@tanstack/react-query"
|
import {useQuery} from "@tanstack/react-query"
|
||||||
import {
|
import {Alert, Chip, Grid, InputAdornment, List, Snackbar, TextField} from "@mui/material"
|
||||||
Alert,
|
|
||||||
Chip,
|
|
||||||
Divider,
|
|
||||||
Grid,
|
|
||||||
InputAdornment,
|
|
||||||
List,
|
|
||||||
Snackbar,
|
|
||||||
TextField,
|
|
||||||
ToggleButton,
|
|
||||||
} from "@mui/material"
|
|
||||||
|
|
||||||
import {AliasList, AliasType, PaginationResult} from "~/server-types"
|
import {AliasList, AliasType, PaginationResult} from "~/server-types"
|
||||||
import {
|
import {
|
||||||
@ -26,8 +16,9 @@ import {
|
|||||||
SimplePage,
|
SimplePage,
|
||||||
SuccessSnack,
|
SuccessSnack,
|
||||||
} from "~/components"
|
} from "~/components"
|
||||||
import {useIsAnyInputFocused} from "~/hooks"
|
import {useExtensionHandler, useIsAnyInputFocused, useWindowVisible} from "~/hooks"
|
||||||
import {CreateAliasButton} from "~/route-widgets/AliasesRoute/CreateAliasButton"
|
import {CreateAliasButton} from "~/route-widgets/AliasesRoute/CreateAliasButton"
|
||||||
|
import {ExtensionKleckMessageLatestAlias} from "~/extension-types"
|
||||||
import AliasesListItem from "~/route-widgets/AliasesRoute/AliasesListItem"
|
import AliasesListItem from "~/route-widgets/AliasesRoute/AliasesListItem"
|
||||||
import EmptyStateScreen from "~/route-widgets/AliasesRoute/EmptyStateScreen"
|
import EmptyStateScreen from "~/route-widgets/AliasesRoute/EmptyStateScreen"
|
||||||
import getAliases from "~/apis/get-aliases"
|
import getAliases from "~/apis/get-aliases"
|
||||||
@ -59,6 +50,8 @@ export default function AliasesRoute(): ReactElement {
|
|||||||
const isAnyInputFocused = useIsAnyInputFocused()
|
const isAnyInputFocused = useIsAnyInputFocused()
|
||||||
const [lockDisabledCopyMode, setLockDisabledCopyMode] = useState<boolean>(false)
|
const [lockDisabledCopyMode, setLockDisabledCopyMode] = useState<boolean>(false)
|
||||||
const isInCopyAddressMode = !isAnyInputFocused && !lockDisabledCopyMode && isPressingControl
|
const isInCopyAddressMode = !isAnyInputFocused && !lockDisabledCopyMode && isPressingControl
|
||||||
|
const [latestAliasId, setLatestAliasId] = useState<string | null>(null)
|
||||||
|
const isVisible = useWindowVisible()
|
||||||
|
|
||||||
const query = useQuery<PaginationResult<AliasList>, AxiosError>(
|
const query = useQuery<PaginationResult<AliasList>, AxiosError>(
|
||||||
["get_aliases", {queryValue, searchFilter, typeFilter}],
|
["get_aliases", {queryValue, searchFilter, typeFilter}],
|
||||||
@ -97,12 +90,45 @@ export default function AliasesRoute(): ReactElement {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const updateLatestAliasId = useCallback(
|
||||||
|
({latestAliasId}: ExtensionKleckMessageLatestAlias["data"]) => {
|
||||||
|
setLatestAliasId(latestAliasId)
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
useExtensionHandler({
|
||||||
|
onLatestAliasChange: updateLatestAliasId,
|
||||||
|
onRefetchAliases: query.refetch,
|
||||||
|
})
|
||||||
|
|
||||||
useUpdateEffect(() => {
|
useUpdateEffect(() => {
|
||||||
if (!isPressingControl) {
|
if (!isPressingControl) {
|
||||||
setLockDisabledCopyMode(false)
|
setLockDisabledCopyMode(false)
|
||||||
}
|
}
|
||||||
}, [isPressingControl])
|
}, [isPressingControl])
|
||||||
|
|
||||||
|
useUpdateEffect(() => {
|
||||||
|
if (!query.data) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If `latestAliasId` is not present in the current query result, then
|
||||||
|
// we need to refetch the query to get the latest alias.
|
||||||
|
if (!query.data.items.some(({id}) => id === latestAliasId)) {
|
||||||
|
query.refetch()
|
||||||
|
}
|
||||||
|
}, [latestAliasId])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.dispatchEvent(
|
||||||
|
new CustomEvent("kleckrelay-blob", {
|
||||||
|
detail: {
|
||||||
|
type: "get-latest-alias",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}, [isVisible])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SimplePage
|
<SimplePage
|
||||||
title={t("routes.AliasesRoute.title")}
|
title={t("routes.AliasesRoute.title")}
|
||||||
@ -260,6 +286,7 @@ export default function AliasesRoute(): ReactElement {
|
|||||||
<AliasesListItem
|
<AliasesListItem
|
||||||
alias={alias}
|
alias={alias}
|
||||||
key={alias.id}
|
key={alias.id}
|
||||||
|
showExtensionIcon={alias.id === latestAliasId}
|
||||||
onCopy={
|
onCopy={
|
||||||
isInCopyAddressMode
|
isInCopyAddressMode
|
||||||
? alias => {
|
? alias => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user