This commit is contained in:
@@ -3,7 +3,7 @@ import { Button, Dropdown } from 'antd';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import styles from './ActionButtonMenu.module.scss';
|
import styles from './ActionButtonMenu.module.scss';
|
||||||
import { ExternalAction } from '../../../interfaces/external-action';
|
import { ExternalAction, ExternalActionUtils } from '../../../interfaces/external-action';
|
||||||
|
|
||||||
// Lazy loaded components
|
// Lazy loaded components
|
||||||
|
|
||||||
@@ -50,12 +50,15 @@ export const ActionButtonMenu: FC<ActionButtonMenuProps> = ({
|
|||||||
followItemSelected();
|
followItemSelected();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const action = actions.find(x => x.url === a.key);
|
// Find the action using the utility function
|
||||||
externalActionSelected(action);
|
const action = ExternalActionUtils.findByKey(actions, a.key);
|
||||||
|
if (action) {
|
||||||
|
externalActionSelected(action);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const items = actions.map(action => ({
|
const items = actions.map(action => ({
|
||||||
key: action.url,
|
key: ExternalActionUtils.generateKey(action),
|
||||||
label: (
|
label: (
|
||||||
<span className={styles.item}>
|
<span className={styles.item}>
|
||||||
{action.icon && <img className={styles.icon} src={action.icon} alt={action.title} />}{' '}
|
{action.icon && <img className={styles.icon} src={action.icon} alt={action.title} />}{' '}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Dispatch, FC, SetStateAction } from 'react';
|
import { Dispatch, FC, SetStateAction } from 'react';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import { Skeleton } from 'antd';
|
import { Skeleton } from 'antd';
|
||||||
import { ExternalAction } from '../../../interfaces/external-action';
|
import { ExternalAction, ExternalActionUtils } from '../../../interfaces/external-action';
|
||||||
import { ActionButtonMenu } from '../../action-buttons/ActionButtonMenu/ActionButtonMenu';
|
import { ActionButtonMenu } from '../../action-buttons/ActionButtonMenu/ActionButtonMenu';
|
||||||
import { ActionButtonRow } from '../../action-buttons/ActionButtonRow/ActionButtonRow';
|
import { ActionButtonRow } from '../../action-buttons/ActionButtonRow/ActionButtonRow';
|
||||||
import { FollowButton } from '../../action-buttons/FollowButton';
|
import { FollowButton } from '../../action-buttons/FollowButton';
|
||||||
@@ -17,7 +17,6 @@ interface ActionButtonProps {
|
|||||||
setShowFollowModal: Dispatch<SetStateAction<boolean>>;
|
setShowFollowModal: Dispatch<SetStateAction<boolean>>;
|
||||||
setShowNotifyModal: Dispatch<SetStateAction<boolean>>;
|
setShowNotifyModal: Dispatch<SetStateAction<boolean>>;
|
||||||
disableNotifyReminderPopup: () => void;
|
disableNotifyReminderPopup: () => void;
|
||||||
setExternalActionToDisplay: any;
|
|
||||||
externalActionSelected: (action: ExternalAction) => void;
|
externalActionSelected: (action: ExternalAction) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,12 +36,11 @@ const ActionButtons: FC<ActionButtonProps> = ({
|
|||||||
setShowNotifyModal,
|
setShowNotifyModal,
|
||||||
disableNotifyReminderPopup,
|
disableNotifyReminderPopup,
|
||||||
externalActions,
|
externalActions,
|
||||||
setExternalActionToDisplay,
|
|
||||||
externalActionSelected,
|
externalActionSelected,
|
||||||
}) => {
|
}) => {
|
||||||
const externalActionButtons = externalActions.map(action => (
|
const externalActionButtons = externalActions.map(action => (
|
||||||
<ActionButton
|
<ActionButton
|
||||||
key={action.url || action.html}
|
key={ExternalActionUtils.generateKey(action)}
|
||||||
action={action}
|
action={action}
|
||||||
externalActionSelected={externalActionSelected}
|
externalActionSelected={externalActionSelected}
|
||||||
/>
|
/>
|
||||||
@@ -70,13 +68,12 @@ const ActionButtons: FC<ActionButtonProps> = ({
|
|||||||
<div className={styles.mobileActionButtons}>
|
<div className={styles.mobileActionButtons}>
|
||||||
{(supportsBrowserNotifications ||
|
{(supportsBrowserNotifications ||
|
||||||
supportsBrowserNotifications ||
|
supportsBrowserNotifications ||
|
||||||
externalActionButtons.length > 0) && (
|
externalActions.length > 0) && (
|
||||||
<ActionButtonMenu
|
<ActionButtonMenu
|
||||||
className={styles.actionButtonMenu}
|
actions={externalActions}
|
||||||
showFollowItem={supportFediverseFeatures}
|
showFollowItem={supportFediverseFeatures}
|
||||||
showNotifyItem={supportsBrowserNotifications}
|
showNotifyItem={supportsBrowserNotifications}
|
||||||
actions={externalActions}
|
externalActionSelected={externalActionSelected}
|
||||||
externalActionSelected={setExternalActionToDisplay}
|
|
||||||
notifyItemSelected={() => setShowNotifyModal(true)}
|
notifyItemSelected={() => setShowNotifyModal(true)}
|
||||||
followItemSelected={() => setShowFollowModal(true)}
|
followItemSelected={() => setShowFollowModal(true)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -274,7 +274,6 @@ export const Content: FC = () => {
|
|||||||
setShowNotifyModal={setShowNotifyModal}
|
setShowNotifyModal={setShowNotifyModal}
|
||||||
disableNotifyReminderPopup={disableNotifyReminderPopup}
|
disableNotifyReminderPopup={disableNotifyReminderPopup}
|
||||||
externalActions={externalActions || []}
|
externalActions={externalActions || []}
|
||||||
setExternalActionToDisplay={setExternalActionToDisplay}
|
|
||||||
setShowFollowModal={setShowFollowModal}
|
setShowFollowModal={setShowFollowModal}
|
||||||
externalActionSelected={externalActionSelected}
|
externalActionSelected={externalActionSelected}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -7,3 +7,24 @@ export interface ExternalAction {
|
|||||||
icon?: string;
|
icon?: string;
|
||||||
openExternally?: boolean;
|
openExternally?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility functions for working with ExternalAction objects
|
||||||
|
*/
|
||||||
|
export namespace ExternalActionUtils {
|
||||||
|
/**
|
||||||
|
* Generates a unique key for an external action based on its properties.
|
||||||
|
* This ensures each action has a unique identifier for React rendering.
|
||||||
|
*/
|
||||||
|
export function generateKey(action: ExternalAction): string {
|
||||||
|
return `${action.title}-${action.url || action.html || 'no-url'}-${action.color || 'no-color'}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds an action from an array based on a generated key.
|
||||||
|
* Useful for finding actions in event handlers when only the key is available.
|
||||||
|
*/
|
||||||
|
export function findByKey(actions: ExternalAction[], key: string): ExternalAction | undefined {
|
||||||
|
return actions.find(action => generateKey(action) === key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user