Skip to content

Commit 70d8876

Browse files
refactor(content-sidebar): convert ActivityMessage to TypeScript (#3905)
* chore(activity-message): convert ActivityMessage to TypeScript Co-Authored-By: [email protected] <[email protected]> * refactor(content-sidebar): convert ActivityMessage to TypeScript Co-Authored-By: [email protected] <[email protected]> * refactor(content-sidebar): use GetProfileUrlCallback type Co-Authored-By: [email protected] <[email protected]> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: [email protected] <[email protected]> Co-authored-by: Trevor <[email protected]>
1 parent b1ca157 commit 70d8876

File tree

2 files changed

+126
-0
lines changed

2 files changed

+126
-0
lines changed

src/elements/content-sidebar/activity-feed/common/activity-message/ActivityMessage.js renamed to src/elements/content-sidebar/activity-feed/common/activity-message/ActivityMessage.js.flow

File renamed without changes.
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import * as React from 'react';
2+
import noop from 'lodash/noop';
3+
import { FormattedMessage } from 'react-intl';
4+
5+
import CollapsableMessage from './CollapsableMessage';
6+
import LoadingIndicator, { LoadingIndicatorSize } from '../../../../../components/loading-indicator';
7+
import ShowOriginalButton from './ShowOriginalButton';
8+
import TranslateButton from './TranslateButton';
9+
10+
import formatTaggedMessage from '../../utils/formatTaggedMessage';
11+
import { withFeatureConsumer, isFeatureEnabled } from '../../../../common/feature-checking';
12+
13+
import messages from './messages';
14+
15+
import type { GetProfileUrlCallback } from '../../../../common/flowTypes';
16+
import type { FeatureConfig } from '../../../../common/feature-checking';
17+
18+
import './ActivityMessage.scss';
19+
20+
export interface ActivityMessageProps {
21+
features: FeatureConfig;
22+
getUserProfileUrl?: GetProfileUrlCallback;
23+
id: string;
24+
isEdited?: boolean;
25+
onTranslate?: ({ id, tagged_message }: { id: string; tagged_message: string }) => void;
26+
tagged_message: string;
27+
translatedTaggedMessage?: string;
28+
translationEnabled?: boolean;
29+
translationFailed?: boolean | null;
30+
}
31+
32+
type State = {
33+
isLoading?: boolean;
34+
isTranslation?: boolean;
35+
};
36+
37+
class ActivityMessage extends React.Component<ActivityMessageProps, State> {
38+
static defaultProps = {
39+
isEdited: false,
40+
translationEnabled: false,
41+
};
42+
43+
state = {
44+
isLoading: false,
45+
isTranslation: false,
46+
};
47+
48+
componentDidUpdate(prevProps: ActivityMessageProps): void {
49+
const { translatedTaggedMessage, translationFailed } = this.props;
50+
const { translatedTaggedMessage: prevTaggedMessage, translationFailed: prevTranslationFailed } = prevProps;
51+
52+
if (prevTaggedMessage === translatedTaggedMessage || prevTranslationFailed === translationFailed) {
53+
return;
54+
}
55+
56+
if (translatedTaggedMessage || translationFailed) {
57+
this.setState({ isLoading: false });
58+
}
59+
}
60+
61+
getButton(isTranslation?: boolean): React.ReactNode {
62+
let button = null;
63+
if (isTranslation) {
64+
button = <ShowOriginalButton handleShowOriginal={this.handleShowOriginal} />;
65+
} else {
66+
button = <TranslateButton handleTranslate={this.handleTranslate} />;
67+
}
68+
69+
return button;
70+
}
71+
72+
handleTranslate = (event: React.MouseEvent): void => {
73+
const { id, tagged_message, onTranslate = noop, translatedTaggedMessage } = this.props;
74+
if (!translatedTaggedMessage) {
75+
this.setState({ isLoading: true });
76+
onTranslate({ id, tagged_message });
77+
}
78+
79+
this.setState({ isTranslation: true });
80+
event.preventDefault();
81+
};
82+
83+
handleShowOriginal = (event: React.MouseEvent): void => {
84+
this.setState({ isTranslation: false });
85+
event.preventDefault();
86+
};
87+
88+
render(): React.ReactNode {
89+
const {
90+
features,
91+
getUserProfileUrl,
92+
id,
93+
isEdited,
94+
tagged_message,
95+
translatedTaggedMessage,
96+
translationEnabled,
97+
} = this.props;
98+
const { isLoading, isTranslation } = this.state;
99+
const commentToDisplay =
100+
translationEnabled && isTranslation && translatedTaggedMessage ? translatedTaggedMessage : tagged_message;
101+
const MessageWrapper = isFeatureEnabled(features, 'activityFeed.collapsableMessages.enabled')
102+
? CollapsableMessage
103+
: React.Fragment;
104+
105+
return isLoading ? (
106+
<div className="bcs-ActivityMessageLoading">
107+
<LoadingIndicator size={LoadingIndicatorSize.SMALL} />
108+
</div>
109+
) : (
110+
<div className="bcs-ActivityMessage">
111+
<MessageWrapper>
112+
{formatTaggedMessage(commentToDisplay, id, false, getUserProfileUrl)}
113+
{isEdited && (
114+
<span className="bcs-ActivityMessage-edited">
115+
<FormattedMessage {...messages.activityMessageEdited} />
116+
</span>
117+
)}
118+
</MessageWrapper>
119+
{translationEnabled ? this.getButton(isTranslation) : null}
120+
</div>
121+
);
122+
}
123+
}
124+
125+
export { ActivityMessage };
126+
export default withFeatureConsumer(ActivityMessage);

0 commit comments

Comments
 (0)