144 lines
3.8 KiB
TypeScript
144 lines
3.8 KiB
TypeScript
import { Q } from '@nozbe/watermelondb';
|
|
import React, { useEffect, useRef, useState } from 'react';
|
|
import { shallowEqual, useSelector } from 'react-redux';
|
|
import { Observable, Subscription } from 'rxjs';
|
|
|
|
import Button from '../Button';
|
|
import { IApplicationState, TSubscriptionModel, TUserModel } from '../../definitions';
|
|
import database from '../../lib/database';
|
|
import { getUserSelector } from '../../selectors/login';
|
|
import Avatar from './Avatar';
|
|
import { IAvatar } from './interfaces';
|
|
import I18n from '../../i18n';
|
|
import { useTheme } from '../../theme';
|
|
import styles from './styles';
|
|
|
|
interface IAvatarContainer extends IAvatar {
|
|
isUserProfile?: boolean;
|
|
handleEdit?: () => void;
|
|
}
|
|
|
|
const AvatarContainer = ({
|
|
style,
|
|
text = '',
|
|
avatar,
|
|
emoji,
|
|
size,
|
|
borderRadius,
|
|
type,
|
|
children,
|
|
onPress,
|
|
getCustomEmoji,
|
|
isStatic,
|
|
rid,
|
|
handleEdit,
|
|
isUserProfile
|
|
}: IAvatarContainer): React.ReactElement => {
|
|
const subscription = useRef<Subscription>();
|
|
const [avatarETag, setAvatarETag] = useState<string | undefined>('');
|
|
const previousAvatarEtag = useRef<string | undefined>('');
|
|
const { colors } = useTheme();
|
|
|
|
const isDirect = () => type === 'd';
|
|
|
|
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, avatarETagUser } = useSelector(
|
|
(state: IApplicationState) => ({
|
|
id: getUserSelector(state).id,
|
|
token: getUserSelector(state).token,
|
|
avatarETagUser: getUserSelector(state).avatarETag
|
|
}),
|
|
shallowEqual
|
|
);
|
|
|
|
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
|
|
);
|
|
|
|
const init = async () => {
|
|
const db = database.active;
|
|
const usersCollection = db.get('users');
|
|
const subsCollection = db.get('subscriptions');
|
|
|
|
let record;
|
|
try {
|
|
if (isDirect()) {
|
|
const [user] = await usersCollection.query(Q.where('username', text)).fetch();
|
|
record = user;
|
|
} else if (rid) {
|
|
record = await subsCollection.find(rid);
|
|
}
|
|
} catch {
|
|
// Record not found
|
|
}
|
|
|
|
if (record) {
|
|
const observable = record.observe() as Observable<TSubscriptionModel | TUserModel>;
|
|
subscription.current = observable.subscribe(r => {
|
|
setAvatarETag(r.avatarETag);
|
|
});
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (!avatarETag || avatarETag !== previousAvatarEtag.current) {
|
|
init();
|
|
}
|
|
return () => {
|
|
if (subscription?.current?.unsubscribe) {
|
|
subscription.current.unsubscribe();
|
|
}
|
|
};
|
|
}, [text, type, size, avatarETag, externalProviderUrl]);
|
|
|
|
useEffect(() => {
|
|
previousAvatarEtag.current = avatarETag;
|
|
}, [avatarETag]);
|
|
|
|
return (
|
|
<>
|
|
<Avatar
|
|
server={server}
|
|
style={style}
|
|
text={text}
|
|
avatar={avatar}
|
|
emoji={emoji}
|
|
size={size}
|
|
borderRadius={borderRadius}
|
|
type={type}
|
|
children={children}
|
|
userId={id}
|
|
token={token}
|
|
onPress={onPress}
|
|
getCustomEmoji={getCustomEmoji}
|
|
isStatic={isStatic}
|
|
rid={rid}
|
|
blockUnauthenticatedAccess={blockUnauthenticatedAccess}
|
|
externalProviderUrl={externalProviderUrl}
|
|
avatarETag={isUserProfile ? avatarETagUser : avatarETag}
|
|
serverVersion={serverVersion}
|
|
/>
|
|
{handleEdit ? (
|
|
<Button
|
|
title={I18n.t('Edit')}
|
|
type='secondary'
|
|
backgroundColor={colors.editAndUploadButtonAvatar}
|
|
onPress={handleEdit}
|
|
testID='avatar-edit-button'
|
|
style={styles.editAvatarButton}
|
|
color={colors.titleText}
|
|
/>
|
|
) : null}
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default AvatarContainer;
|