Skip to content

Commit

Permalink
feat: ✨ support user n channel mentions
Browse files Browse the repository at this point in the history
  • Loading branch information
themashcodee committed May 12, 2024
1 parent 8766a6a commit 090837b
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 4 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"html-react-parser": "^4.2.2",
"node-emoji": "^2.1.0",
"slack-markdown": "^0.3.0",
"xregexp": "^5.1.1"
"xregexp": "^5.1.1",
"zustand": "^4.5.2"
},
"peerDependencies": {
"react": "^17.0.0 || ^18.0.0",
Expand Down
30 changes: 30 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 12 additions & 2 deletions src/components/composition_objects/text_object.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useGlobalData } from "../../store";
import type { TextObject as TextObjectType } from "../../types";
import { parseEmojis, slack_text_to_jsx } from "../../utils";

Expand All @@ -9,6 +10,7 @@ type TextObjectProps = {
export const TextObject = (props: TextObjectProps) => {
const { type, text, emoji, verbatim = false } = props.data;
const { className = "" } = props;
const { channels, users } = useGlobalData();

// TODO: HANDLE VERBATIM

Expand All @@ -19,7 +21,15 @@ export const TextObject = (props: TextObjectProps) => {
emoji_parsed = emoji_parsed.replace(/&gt;/g, "> ").replace(/&lt;/g, "<");

if (type === "plain_text")
return <div className={className}>{slack_text_to_jsx(emoji_parsed, { markdown: false })}</div>;
return (
<div className={className}>
{slack_text_to_jsx(emoji_parsed, { markdown: false, users, channels })}
</div>
);

return <div className={className}>{slack_text_to_jsx(emoji_parsed, { markdown: true })}</div>;
return (
<div className={className}>
{slack_text_to_jsx(emoji_parsed, { markdown: true, users, channels })}
</div>
);
};
20 changes: 20 additions & 0 deletions src/message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Block } from "./types";
import { Header } from "./header";
import { getBlockComponent } from "./components";
import { BlockWrapper } from "./block_wrapper";
import { useGlobalData } from "./store";
import { useEffect } from "react";

type Props = {
/**
Expand All @@ -19,6 +21,16 @@ type Props = {
className?: string;
style?: React.CSSProperties;
unstyled?: boolean;
data?: {
users?: {
id: string;
name: string;
}[];
channels?: {
id: string;
name: string;
}[];
};
};

export const Message = (props: Props) => {
Expand All @@ -31,8 +43,16 @@ export const Message = (props: Props) => {
style,
showBlockKitDebug = false,
unstyled = false,
data = {},
} = props;

const { setChannels, setUsers } = useGlobalData();

useEffect(() => {
if (data.users) setUsers(data.users);
if (data.channels) setChannels(data.channels);
}, [data]);

return (
<div id="slack_blocks_to_jsx">
<section
Expand Down
1 change: 1 addition & 0 deletions src/store/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./useGlobalData";
36 changes: 36 additions & 0 deletions src/store/useGlobalData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { create } from "zustand";

type User = {
id: string;
name: string;
};

type Channel = {
id: string;
name: string;
};

type Data = {
users: User[];
channels: Channel[];
setUsers: (users: User[]) => void;
setChannels: (channels: Channel[]) => void;
};

const useBearStore = create<Data>((set) => ({
users: [],
channels: [],
setUsers: (users) => set({ users }),
setChannels: (channels) => set({ channels }),
}));

export const useGlobalData = () => {
const { users, channels, setChannels, setUsers } = useBearStore();

return {
users,
channels,
setChannels,
setUsers,
};
};
9 changes: 9 additions & 0 deletions src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,15 @@
& .slack_user {
color: rgb(18, 100, 163);
background: rgb(29, 155, 209, 0.1);
user-select: none;
cursor: pointer;
}

& .slack_channel {
color: rgb(18, 100, 163);
background: rgb(29, 155, 209, 0.1);
user-select: none;
cursor: pointer;
}

/* #endregion */
Expand Down
25 changes: 24 additions & 1 deletion src/utils/slack_text_to_jsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,39 @@ const slack_text_parser = toHTML;

type Options = {
markdown: boolean;
users: {
id: string;
name: string;
}[];
channels: {
id: string;
name: string;
}[];
};

export const slack_text_to_jsx = (text: string, parse_options: Options): ReactNode => {
const { markdown, users, channels } = parse_options;

if (!text) return null;

const html_string = slack_text_parser(text, {
slackCallbacks: {
user(data) {
return `<span class="slack_user" data-user-id="${data.id}">@Manish Panwar</span>`;
const user = users.find((u) => u.id === data.id || u.name === data.name);
const label = user?.name || data.id || data.name;

return `<span class="slack_user" data-user-id="${user?.id || data.id}">@${label}</span>`;
},
channel(data) {
const channel = channels.find((c) => c.id === data.id || c.name === data.name);
const label = channel?.name || data.id || data.name;

return `<span class="slack_channel" data-channel-id="${
channel?.id || data.id
}">#${label}</span>`;
},
},
});

return parse(html_string, { trim: false });
};

0 comments on commit 090837b

Please sign in to comment.