Message Actions

The Problem(s)

Display of message actions is taken care of by the MessageOptions component and its child components MessageActions and MessageActionsBox. The message actions are represented by buttons displayed in a dropdown and are related to a specific message or its author.

MessageOptions structure

The previously mentioned components, however, make it complicated for the integrators to customize the action buttons (text, translation etc.). A solution to patch these shortcomings was to introduce CustomMessageActionsList component to override the default MessageActions over component context. This allows to render custom buttons within actions dropdown but does not allow to control the conditions, when and how the message options buttons (button to open the actions dropdown, reply or react button) would be displayed.

The New Approach

To solve the mentioned shortcomings we introduce experimental MessageActions component that allows:

  1. to define the components (and thus the contents of the buttons) that will be rendered in the actions dropdown
  2. to specify the placement of the action button either in the dropdown or among the quick actions
  3. to define filtering logic for what actions will be displayed in the dropdown or among the quick actions
The experimental nature of the feature makes it subject to change. It is possible that with the next major version, the `MessageOptions` component will not be used as a parent to render `MessageActions` leading to changes in the resulting markup. This is due to the fact that experimental `MessageActions` component distinguishes between the `dropdown` and `quick` actions placement.

The Customization Process

  1. define the set of actions with buttons as components with own logic and click handlers, marked with quick and dropdown placement
  2. decide on merging the custom actions with the default actions provided by the SDK
  3. define the filter which takes into consideration the user permissions or go with the default filtering logic

The customization example follows:

import { useMemo } from "react";
import { Channel } from "stream-chat-react";
import {
  MessageActions,
  defaultMessageActionSet,
  DefaultDropdownActionButton,
} from "stream-chat-react/experimental";

import { useCustomMessageActionRules } from "./useCustomMessageActionRules";

const CustomMessageActions = () => {
  const customRules = useCustomMessageActionRules(); // your implementation

  const customMessageActionSet = useMemo(() => {
    return [
      // reuse the default set if you need
      ...defaultMessageActionSet,
      {
        type: "myCustomTypeDropdown",
        placement: "dropdown",
        // we recommend defining components outside the scope of
        // the CustomMessageActions component to keep them stable
        Component: () => (
          <DefaultDropdownActionButton>🚀 Custom</DefaultDropdownActionButton>
        ),
      },
      {
        type: "myCustomTypeQuick",
        placement: "quick",
        Component: () => <button>a</button>,
      },
    ].filter(
      // apply custom filter with access to values of contexts and other hooks
      (action) => {
        return !customRules.disallow.includes(action.type);
      },
    );
  }, [customRules]);

  return (
    <MessageActions
      // though not recommended, it's possible to completely disable the default filter
      disableBaseMessageActionSetFilter
      messageActionSet={customMessageActionSet}
    />
  );
};

<Channel MessageActions={CustomMessageActions}>...</Channel>;

image

© Getstream.io, Inc. All Rights Reserved.