diff --git a/app/containers/Avatar/Avatar.tsx b/app/containers/Avatar/Avatar.tsx
index 4f2da1806..5457f6f50 100644
--- a/app/containers/Avatar/Avatar.tsx
+++ b/app/containers/Avatar/Avatar.tsx
@@ -8,7 +8,6 @@ import { getAvatarURL } from '../../lib/methods/helpers/getAvatarUrl';
import { SubscriptionType } from '../../definitions';
import Emoji from '../markdown/Emoji';
import { IAvatar } from './interfaces';
-import { useTheme } from '../../theme';
const Avatar = React.memo(
({
@@ -16,7 +15,8 @@ const Avatar = React.memo(
style,
avatar,
children,
- user,
+ userId,
+ token,
onPress,
emoji,
getCustomEmoji,
@@ -31,8 +31,6 @@ const Avatar = React.memo(
type = SubscriptionType.DIRECT,
externalProviderUrl
}: IAvatar) => {
- const { theme } = useTheme();
-
if ((!text && !avatar && !emoji && !rid) || !server) {
return null;
}
@@ -46,14 +44,7 @@ const Avatar = React.memo(
let image;
if (emoji) {
image = (
-
+
);
} else {
let uri = avatar;
@@ -62,7 +53,8 @@ const Avatar = React.memo(
type,
text,
size,
- user,
+ userId,
+ token,
avatar,
server,
avatarETag,
diff --git a/app/containers/Avatar/index.tsx b/app/containers/Avatar/index.tsx
index 404e3e4c9..9f762308d 100644
--- a/app/containers/Avatar/index.tsx
+++ b/app/containers/Avatar/index.tsx
@@ -1,84 +1,65 @@
-import React from 'react';
-import { connect } from 'react-redux';
import { Q } from '@nozbe/watermelondb';
+import React, { useEffect, useRef, useState } from 'react';
+import { shallowEqual, useSelector } from 'react-redux';
import { Observable, Subscription } from 'rxjs';
+import { IApplicationState, TSubscriptionModel, TUserModel } from '../../definitions';
import database from '../../lib/database';
import { getUserSelector } from '../../selectors/login';
-import { IApplicationState, TSubscriptionModel, TUserModel } from '../../definitions';
import Avatar from './Avatar';
import { IAvatar } from './interfaces';
-class AvatarContainer extends React.Component {
- private subscription?: Subscription;
+const AvatarContainer = ({
+ style,
+ text = '',
+ avatar,
+ emoji,
+ size,
+ borderRadius,
+ type,
+ children,
+ onPress,
+ getCustomEmoji,
+ isStatic,
+ rid
+}: IAvatar): React.ReactElement => {
+ const subscription = useRef();
+ const [avatarETag, setAvatarETag] = useState('');
- static defaultProps = {
- text: '',
- type: 'd'
- };
+ const isDirect = () => type === 'd';
- constructor(props: IAvatar) {
- super(props);
- this.state = { avatarETag: '' };
- this.init();
- }
+ const server = useSelector((state: IApplicationState) => state.share.server.server || state.server.server);
+ const serverVersion = useSelector((state: IApplicationState) => state.share.server.version || state.server.version);
+ const { id, token } = useSelector(
+ (state: IApplicationState) => ({
+ id: getUserSelector(state).id,
+ token: getUserSelector(state).token
+ }),
+ shallowEqual
+ );
- componentDidUpdate(prevProps: IAvatar) {
- const { text, type } = this.props;
- if (prevProps.text !== text || prevProps.type !== type) {
- this.init();
- }
- }
+ const externalProviderUrl = useSelector(
+ (state: IApplicationState) => state.settings.Accounts_AvatarExternalProviderUrl as string
+ );
+ const blockUnauthenticatedAccess = useSelector(
+ (state: IApplicationState) =>
+ (state.share.settings?.Accounts_AvatarBlockUnauthenticatedAccess as boolean) ??
+ state.settings.Accounts_AvatarBlockUnauthenticatedAccess ??
+ true
+ );
- shouldComponentUpdate(nextProps: IAvatar, nextState: { avatarETag: string }) {
- const { avatarETag } = this.state;
- const { text, type, size, externalProviderUrl } = this.props;
- if (nextProps.externalProviderUrl !== externalProviderUrl) {
- return true;
- }
- if (nextState.avatarETag !== avatarETag) {
- return true;
- }
- if (nextProps.text !== text) {
- return true;
- }
- if (nextProps.type !== type) {
- return true;
- }
- if (nextProps.size !== size) {
- return true;
- }
-
- return false;
- }
-
- componentWillUnmount() {
- if (this.subscription?.unsubscribe) {
- this.subscription.unsubscribe();
- }
- }
-
- get isDirect() {
- const { type } = this.props;
- return type === 'd';
- }
-
- init = async () => {
+ const init = async () => {
const db = database.active;
const usersCollection = db.get('users');
const subsCollection = db.get('subscriptions');
let record;
try {
- if (this.isDirect) {
- const { text } = this.props;
+ if (isDirect()) {
const [user] = await usersCollection.query(Q.where('username', text)).fetch();
record = user;
- } else {
- const { rid } = this.props;
- if (rid) {
- record = await subsCollection.find(rid);
- }
+ } else if (rid) {
+ record = await subsCollection.find(rid);
}
} catch {
// Record not found
@@ -86,28 +67,46 @@ class AvatarContainer extends React.Component {
if (record) {
const observable = record.observe() as Observable;
- this.subscription = observable.subscribe(r => {
- const { avatarETag } = r;
- this.setState({ avatarETag });
+ subscription.current = observable.subscribe(r => {
+ setAvatarETag(r.avatarETag);
});
}
};
- render() {
- const { avatarETag } = this.state;
- const { serverVersion } = this.props;
- return ;
- }
-}
+ useEffect(() => {
+ if (!avatarETag) {
+ init();
+ }
+ return () => {
+ if (subscription?.current?.unsubscribe) {
+ subscription.current.unsubscribe();
+ }
+ };
+ }, [text, type, size, avatarETag, externalProviderUrl]);
-const mapStateToProps = (state: IApplicationState) => ({
- user: getUserSelector(state),
- server: state.share.server.server || state.server.server,
- serverVersion: state.share.server.version || state.server.version,
- blockUnauthenticatedAccess:
- (state.share.settings?.Accounts_AvatarBlockUnauthenticatedAccess as boolean) ??
- state.settings.Accounts_AvatarBlockUnauthenticatedAccess ??
- true,
- externalProviderUrl: state.settings.Accounts_AvatarExternalProviderUrl as string
-});
-export default connect(mapStateToProps)(AvatarContainer);
+ return (
+
+ );
+};
+
+export default AvatarContainer;
diff --git a/app/containers/Avatar/interfaces.ts b/app/containers/Avatar/interfaces.ts
index c4be26f7b..8124f4e65 100644
--- a/app/containers/Avatar/interfaces.ts
+++ b/app/containers/Avatar/interfaces.ts
@@ -5,23 +5,21 @@ import { TGetCustomEmoji } from '../../definitions/IEmoji';
export interface IAvatar {
server?: string;
style?: any;
- text: string;
+ text?: string;
avatar?: string;
emoji?: string;
size?: number;
borderRadius?: number;
type?: string;
children?: React.ReactElement | null;
- user?: {
- id?: string;
- token?: string;
- };
+ userId?: string;
+ token?: string;
onPress?: () => void;
getCustomEmoji?: TGetCustomEmoji;
avatarETag?: string;
isStatic?: boolean | string;
rid?: string;
blockUnauthenticatedAccess?: boolean;
- serverVersion: string | null;
+ serverVersion?: string | null;
externalProviderUrl?: string;
}
diff --git a/app/containers/markdown/Emoji.tsx b/app/containers/markdown/Emoji.tsx
index 8abfd8161..130d1cda0 100644
--- a/app/containers/markdown/Emoji.tsx
+++ b/app/containers/markdown/Emoji.tsx
@@ -3,9 +3,8 @@ import { Text } from 'react-native';
import shortnameToUnicode from '../../lib/methods/helpers/shortnameToUnicode';
import CustomEmoji from '../EmojiPicker/CustomEmoji';
-import { themes } from '../../lib/constants';
import styles from './styles';
-import { TSupportedThemes } from '../../theme';
+import { useTheme } from '../../theme';
interface IEmoji {
literal: string;
@@ -14,13 +13,13 @@ interface IEmoji {
baseUrl: string;
customEmojis?: any;
style?: object;
- theme: TSupportedThemes;
onEmojiSelected?: Function;
tabEmojiStyle?: object;
}
const Emoji = React.memo(
- ({ literal, isMessageContainsOnlyEmoji, getCustomEmoji, baseUrl, customEmojis = true, style = {}, theme }: IEmoji) => {
+ ({ literal, isMessageContainsOnlyEmoji, getCustomEmoji, baseUrl, customEmojis = true, style = {} }: IEmoji) => {
+ const { colors } = useTheme();
const emojiUnicode = shortnameToUnicode(literal);
const emoji: any = getCustomEmoji && getCustomEmoji(literal.replace(/:/g, ''));
if (emoji && customEmojis) {
@@ -33,7 +32,7 @@ const Emoji = React.memo(
);
}
return (
-
+
{emojiUnicode}
);
diff --git a/app/containers/markdown/index.tsx b/app/containers/markdown/index.tsx
index 16c86d1d0..7b7c3f92b 100644
--- a/app/containers/markdown/index.tsx
+++ b/app/containers/markdown/index.tsx
@@ -233,7 +233,7 @@ class Markdown extends PureComponent {
};
renderEmoji = ({ literal }: TLiteral) => {
- const { getCustomEmoji, baseUrl = '', customEmojis, style, theme } = this.props;
+ const { getCustomEmoji, baseUrl = '', customEmojis, style } = this.props;
return (
{
baseUrl={baseUrl}
customEmojis={customEmojis}
style={style}
- theme={theme}
/>
);
};
diff --git a/app/lib/methods/helpers/getAvatarUrl.ts b/app/lib/methods/helpers/getAvatarUrl.ts
index 1c4c18dd3..bf5c732fc 100644
--- a/app/lib/methods/helpers/getAvatarUrl.ts
+++ b/app/lib/methods/helpers/getAvatarUrl.ts
@@ -6,9 +6,10 @@ const formatUrl = (url: string, size: number, query?: string) => `${url}?format=
export const getAvatarURL = ({
type,
- text,
+ text = '',
size = 25,
- user = {},
+ userId,
+ token,
avatar,
server,
avatarETag,
@@ -30,10 +31,9 @@ export const getAvatarURL = ({
room = `@${text}`;
}
- const { id, token } = user;
let query = '';
- if (id && token && blockUnauthenticatedAccess) {
- query += `&rc_token=${token}&rc_uid=${id}`;
+ if (userId && token && blockUnauthenticatedAccess) {
+ query += `&rc_token=${token}&rc_uid=${userId}`;
}
if (avatarETag) {
query += `&etag=${avatarETag}`;
diff --git a/app/views/CreateDiscussionView/SelectChannel.tsx b/app/views/CreateDiscussionView/SelectChannel.tsx
index f96562fa7..5e09af9a6 100644
--- a/app/views/CreateDiscussionView/SelectChannel.tsx
+++ b/app/views/CreateDiscussionView/SelectChannel.tsx
@@ -36,7 +36,8 @@ const SelectChannel = ({
getAvatarURL({
text: getRoomAvatar(item),
type: item.t,
- user: { id: userId, token },
+ userId,
+ token,
server,
avatarETag: item.avatarETag,
rid: item.rid,
diff --git a/app/views/CreateDiscussionView/SelectUsers.tsx b/app/views/CreateDiscussionView/SelectUsers.tsx
index a58410f76..7cb3a98cb 100644
--- a/app/views/CreateDiscussionView/SelectUsers.tsx
+++ b/app/views/CreateDiscussionView/SelectUsers.tsx
@@ -40,7 +40,8 @@ const SelectUsers = ({
getAvatarURL({
text: getRoomAvatar(item),
type: SubscriptionType.DIRECT,
- user: { id: userId, token },
+ userId,
+ token,
server,
avatarETag: item.avatarETag,
blockUnauthenticatedAccess,