Chore: Properly type Status (#3911)
Co-authored-by: Gleidson Daniel Silva <gleidson10daniel@hotmail.com>
This commit is contained in:
parent
70cb252d1b
commit
902827422b
|
@ -7,6 +7,7 @@ import { themes } from '../../constants/colors';
|
|||
import { MarkdownPreview } from '../markdown';
|
||||
import RoomTypeIcon from '../RoomTypeIcon';
|
||||
import { withTheme } from '../../theme';
|
||||
import { TUserStatus } from '../../definitions';
|
||||
|
||||
const HIT_SLOP = {
|
||||
top: 5,
|
||||
|
@ -67,7 +68,7 @@ interface IRoomHeader {
|
|||
prid: string;
|
||||
tmid: string;
|
||||
teamMain: boolean;
|
||||
status: string;
|
||||
status: TUserStatus;
|
||||
theme?: string;
|
||||
usersTyping: [];
|
||||
isGroupChat: boolean;
|
||||
|
|
|
@ -2,7 +2,7 @@ import { dequal } from 'dequal';
|
|||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { IApplicationState } from '../../definitions';
|
||||
import { IApplicationState, TUserStatus } from '../../definitions';
|
||||
import { withDimensions } from '../../dimensions';
|
||||
import I18n from '../../i18n';
|
||||
import RoomHeader from './RoomHeader';
|
||||
|
@ -15,7 +15,7 @@ interface IRoomHeaderContainerProps {
|
|||
tmid: string;
|
||||
teamMain: boolean;
|
||||
usersTyping: [];
|
||||
status: string;
|
||||
status: TUserStatus;
|
||||
statusText: string;
|
||||
connecting: boolean;
|
||||
connected: boolean;
|
||||
|
@ -140,7 +140,7 @@ const mapStateToProps = (state: IApplicationState, ownProps: any) => {
|
|||
connecting: state.meteor.connecting || state.server.loading,
|
||||
connected: state.meteor.connected,
|
||||
usersTyping: state.usersTyping,
|
||||
status,
|
||||
status: status as TUserStatus,
|
||||
statusText
|
||||
};
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@ import { CustomIcon } from '../lib/Icons';
|
|||
import { STATUS_COLORS, themes } from '../constants/colors';
|
||||
import Status from './Status/Status';
|
||||
import { withTheme } from '../theme';
|
||||
import { TUserStatus } from '../definitions';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
icon: {
|
||||
|
@ -17,7 +18,7 @@ interface IRoomTypeIcon {
|
|||
type: string;
|
||||
isGroupChat?: boolean;
|
||||
teamMain?: boolean;
|
||||
status?: string;
|
||||
status?: TUserStatus;
|
||||
size?: number;
|
||||
style?: ViewStyle;
|
||||
}
|
||||
|
@ -31,9 +32,10 @@ const RoomTypeIcon = React.memo(({ type, isGroupChat, status, style, theme, team
|
|||
const iconStyle = [styles.icon, { color }, style];
|
||||
|
||||
if (type === 'd' && !isGroupChat) {
|
||||
return (
|
||||
<Status style={[iconStyle, { color: STATUS_COLORS[status!] ?? STATUS_COLORS.offline }]} size={size} status={status!} />
|
||||
);
|
||||
if (!status) {
|
||||
status = 'offline';
|
||||
}
|
||||
return <Status style={[iconStyle, { color: STATUS_COLORS[status] }]} size={size} status={status} />;
|
||||
}
|
||||
|
||||
// TODO: move this to a separate function
|
||||
|
|
|
@ -3,15 +3,9 @@ import { StyleProp, TextStyle } from 'react-native';
|
|||
|
||||
import { CustomIcon } from '../../lib/Icons';
|
||||
import { STATUS_COLORS } from '../../constants/colors';
|
||||
import { IStatus } from './definition';
|
||||
|
||||
interface IStatus {
|
||||
status: string;
|
||||
size: number;
|
||||
style?: StyleProp<TextStyle>;
|
||||
testID?: string;
|
||||
}
|
||||
|
||||
const Status = React.memo(({ style, status = 'offline', size = 32, ...props }: IStatus) => {
|
||||
const Status = React.memo(({ style, status = 'offline', size = 32, ...props }: Omit<IStatus, 'id'>) => {
|
||||
const name = `status-${status}`;
|
||||
const isNameValid = CustomIcon.hasIcon(name);
|
||||
const iconName = isNameValid ? name : 'status-offline';
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import { TextProps } from 'react-native';
|
||||
|
||||
import { TUserStatus } from '../../definitions';
|
||||
|
||||
export interface IStatus extends TextProps {
|
||||
id: string;
|
||||
size: number;
|
||||
status: TUserStatus;
|
||||
}
|
|
@ -1,20 +1,15 @@
|
|||
import React, { memo } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { IApplicationState, TUserStatus } from '../../definitions';
|
||||
import Status from './Status';
|
||||
import { IStatus } from './definition';
|
||||
|
||||
interface IStatusContainer {
|
||||
style: any;
|
||||
size: number;
|
||||
status: string;
|
||||
}
|
||||
const StatusContainer = ({ id, style, size = 32, ...props }: Omit<IStatus, 'status'>): React.ReactElement => {
|
||||
const status = useSelector((state: IApplicationState) =>
|
||||
state.meteor.connected ? state.activeUsers[id] && state.activeUsers[id].status : 'loading'
|
||||
) as TUserStatus;
|
||||
return <Status size={size} style={style} status={status} {...props} />;
|
||||
};
|
||||
|
||||
const StatusContainer = memo(({ style, size = 32, status }: IStatusContainer) => (
|
||||
<Status size={size} style={style} status={status} />
|
||||
));
|
||||
|
||||
const mapStateToProps = (state: any, ownProps: any) => ({
|
||||
status: state.meteor.connected ? state.activeUsers[ownProps.id] && state.activeUsers[ownProps.id].status : 'loading'
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(StatusContainer);
|
||||
export default StatusContainer;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Model from '@nozbe/watermelondb/Model';
|
||||
|
||||
import { IUserEmail, IUserSettings } from './IUser';
|
||||
import { UserStatus } from './UserStatus';
|
||||
import { TUserStatus } from './TUserStatus';
|
||||
|
||||
export interface ILoggedUser {
|
||||
id: string;
|
||||
|
@ -9,7 +9,7 @@ export interface ILoggedUser {
|
|||
username: string;
|
||||
name: string;
|
||||
language?: string;
|
||||
status: UserStatus;
|
||||
status: TUserStatus;
|
||||
statusText?: string;
|
||||
customFields?: {
|
||||
[key: string]: any;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Model from '@nozbe/watermelondb/Model';
|
||||
|
||||
import { UserStatus } from './UserStatus';
|
||||
import { TUserStatus } from './TUserStatus';
|
||||
import { IRocketChatRecord } from './IRocketChatRecord';
|
||||
import { ILoggedUser } from './ILoggedUser';
|
||||
|
||||
|
@ -25,7 +25,7 @@ export interface IPersonalAccessToken extends ILoginToken {
|
|||
export interface IUserRegistered {
|
||||
_id: string;
|
||||
type: string;
|
||||
status: UserStatus;
|
||||
status: TUserStatus;
|
||||
active: boolean;
|
||||
name: string;
|
||||
username: string;
|
||||
|
@ -133,14 +133,14 @@ export interface IUser extends IRocketChatRecord, Omit<ILoggedUser, 'username' |
|
|||
name?: string;
|
||||
services?: IUserServices;
|
||||
emails?: IUserEmail[];
|
||||
status: UserStatus;
|
||||
status: TUserStatus;
|
||||
statusConnection?: string;
|
||||
lastLogin?: Date;
|
||||
avatarOrigin?: string;
|
||||
avatarETag?: string;
|
||||
utcOffset?: number;
|
||||
language?: string;
|
||||
statusDefault?: UserStatus;
|
||||
statusDefault?: TUserStatus;
|
||||
statusText?: string;
|
||||
oauth?: {
|
||||
authorizedClients: string[];
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
export const STATUSES = ['offline', 'online', 'away', 'busy'] as const;
|
||||
|
||||
export type TUserStatus = typeof STATUSES[number];
|
|
@ -1,6 +0,0 @@
|
|||
export enum UserStatus {
|
||||
ONLINE = 'online',
|
||||
AWAY = 'away',
|
||||
OFFLINE = 'offline',
|
||||
BUSY = 'busy'
|
||||
}
|
|
@ -26,6 +26,7 @@ export * from './ICertificate';
|
|||
export * from './IUrl';
|
||||
export * from './ICredentials';
|
||||
export * from './ISearch';
|
||||
export * from './TUserStatus';
|
||||
|
||||
export interface IBaseScreen<T extends Record<string, object | undefined>, S extends string> {
|
||||
navigation: StackNavigationProp<T, S>;
|
||||
|
|
|
@ -73,7 +73,6 @@ export const THEME_PREFERENCES_KEY = 'RC_THEME_PREFERENCES_KEY';
|
|||
export const CRASH_REPORT_KEY = 'RC_CRASH_REPORT_KEY';
|
||||
export const ANALYTICS_EVENTS_KEY = 'RC_ANALYTICS_EVENTS_KEY';
|
||||
export const MIN_ROCKETCHAT_VERSION = '0.70.0';
|
||||
export const STATUSES = ['offline', 'online', 'away', 'busy'];
|
||||
|
||||
const RocketChat = {
|
||||
TOKEN_KEY,
|
||||
|
|
|
@ -6,7 +6,6 @@ import { Q } from '@nozbe/watermelondb';
|
|||
|
||||
import log from '../../../utils/log';
|
||||
import { onRolesChanged } from '../../methods/getRoles';
|
||||
import { UserStatus } from '../../../definitions/UserStatus';
|
||||
import { setActiveUsers } from '../../../actions/activeUsers';
|
||||
import protectedFunction from '../../methods/helpers/protectedFunction';
|
||||
import database from '../../database';
|
||||
|
@ -17,8 +16,8 @@ import { store } from '../../auxStore';
|
|||
import { loginRequest, setLoginServices, setUser } from '../../../actions/login';
|
||||
import sdk from './sdk';
|
||||
import I18n from '../../../i18n';
|
||||
import RocketChat, { MIN_ROCKETCHAT_VERSION, STATUSES } from '../rocketchat';
|
||||
import { ICredentials, ILoggedUser, IRocketChat } from '../../../definitions';
|
||||
import RocketChat, { MIN_ROCKETCHAT_VERSION } from '../rocketchat';
|
||||
import { ICredentials, ILoggedUser, IRocketChat, STATUSES } from '../../../definitions';
|
||||
import { isIOS } from '../../../utils/deviceInfo';
|
||||
import { connectRequest, connectSuccess, disconnect as disconnectAction } from '../../../actions/connect';
|
||||
import { updatePermission } from '../../../actions/permissions';
|
||||
|
@ -195,7 +194,7 @@ function connect(
|
|||
|
||||
const { user: loggedUser } = store.getState().login;
|
||||
if (loggedUser && loggedUser.id === id) {
|
||||
store.dispatch(setUser({ status: STATUSES[status] as UserStatus, statusText }));
|
||||
store.dispatch(setUser({ status: STATUSES[status], statusText }));
|
||||
}
|
||||
} else if (/updateAvatar/.test(eventName)) {
|
||||
const { username, etag } = ddpMessage.fields.args[0];
|
||||
|
|
|
@ -12,6 +12,7 @@ import Touchable from './Touchable';
|
|||
import Tag from './Tag';
|
||||
import I18n from '../../i18n';
|
||||
import { DisplayMode } from '../../constants/constantDisplayMode';
|
||||
import { TUserStatus } from '../../definitions';
|
||||
|
||||
interface IRoomItem {
|
||||
rid: string;
|
||||
|
@ -24,7 +25,7 @@ interface IRoomItem {
|
|||
avatarSize: number;
|
||||
testID: string;
|
||||
width: number;
|
||||
status: string;
|
||||
status: TUserStatus;
|
||||
useRealName: boolean;
|
||||
theme: string;
|
||||
isFocused: boolean;
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import React from 'react';
|
||||
|
||||
import { TUserStatus } from '../../definitions';
|
||||
import RoomTypeIcon from '../../containers/RoomTypeIcon';
|
||||
|
||||
interface ITypeIcon {
|
||||
type: string;
|
||||
status: string;
|
||||
status: TUserStatus;
|
||||
prid: string;
|
||||
isGroupChat: boolean;
|
||||
teamMain: boolean;
|
||||
|
|
|
@ -5,6 +5,7 @@ import I18n from '../../i18n';
|
|||
import { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from './styles';
|
||||
import { formatDate } from '../../utils/room';
|
||||
import RoomItem from './RoomItem';
|
||||
import { TUserStatus } from '../../definitions';
|
||||
|
||||
export { ROW_HEIGHT, ROW_HEIGHT_CONDENSED };
|
||||
interface IRoomItemContainerProps {
|
||||
|
@ -16,7 +17,7 @@ interface IRoomItemContainerProps {
|
|||
username: string;
|
||||
avatarSize: number;
|
||||
width: number;
|
||||
status: string;
|
||||
status: TUserStatus;
|
||||
toggleFav(): void;
|
||||
toggleRead(): void;
|
||||
hideChannel(): void;
|
||||
|
@ -53,7 +54,7 @@ class RoomItemContainer extends React.Component<IRoomItemContainerProps, any> {
|
|||
|
||||
private roomSubscription: any;
|
||||
|
||||
static defaultProps = {
|
||||
static defaultProps: Partial<IRoomItemContainerProps> = {
|
||||
avatarSize: 48,
|
||||
status: 'offline',
|
||||
getUserPresence: () => {},
|
||||
|
@ -233,7 +234,7 @@ const mapStateToProps = (state: any, ownProps: any) => {
|
|||
}
|
||||
return {
|
||||
connected: state.meteor.connected,
|
||||
status
|
||||
status: status as TUserStatus
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { clearActiveUsers, setActiveUsers } from '../actions/activeUsers';
|
||||
import { UserStatus } from '../definitions/UserStatus';
|
||||
import { IActiveUsers, initialState } from './activeUsers';
|
||||
import { mockedStore } from './mockedStore';
|
||||
|
||||
|
@ -9,7 +8,7 @@ describe('test reducer', () => {
|
|||
expect(state).toEqual(initialState);
|
||||
});
|
||||
it('should return modified store after action', () => {
|
||||
const activeUsers: IActiveUsers = { any: { status: UserStatus.ONLINE, statusText: 'any' } };
|
||||
const activeUsers: IActiveUsers = { any: { status: 'online', statusText: 'any' } };
|
||||
mockedStore.dispatch(setActiveUsers(activeUsers));
|
||||
const state = mockedStore.getState().activeUsers;
|
||||
expect(state).toEqual({ ...activeUsers });
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { ACTIVE_USERS } from '../actions/actionsTypes';
|
||||
import { TApplicationActions } from '../definitions';
|
||||
import { UserStatus } from '../definitions/UserStatus';
|
||||
import { TApplicationActions, TUserStatus } from '../definitions';
|
||||
|
||||
export interface IActiveUser {
|
||||
status: UserStatus;
|
||||
status: TUserStatus;
|
||||
statusText: string;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { TUserStatus } from '../definitions';
|
||||
import {
|
||||
clearUser,
|
||||
loginFailure,
|
||||
|
@ -8,7 +9,6 @@ import {
|
|||
setLoginServices,
|
||||
setUser
|
||||
} from '../actions/login';
|
||||
import { UserStatus } from '../definitions/UserStatus';
|
||||
import { initialState } from './login';
|
||||
import { mockedStore } from './mockedStore';
|
||||
|
||||
|
@ -49,7 +49,7 @@ describe('test selectedUsers reducer', () => {
|
|||
isFromWebView: false,
|
||||
showMessageInMainThread: false,
|
||||
enableMessageParserEarlyAdoption: false,
|
||||
status: UserStatus.ONLINE,
|
||||
status: 'online' as TUserStatus,
|
||||
statusText: 'online'
|
||||
};
|
||||
mockedStore.dispatch(loginSuccess(user));
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { UserStatus } from '../definitions/UserStatus';
|
||||
import * as types from '../actions/actionsTypes';
|
||||
import { TActionsLogin } from '../actions/login';
|
||||
import { IUser } from '../definitions';
|
||||
import { IUser, TUserStatus } from '../definitions';
|
||||
|
||||
export interface IUserLogin {
|
||||
id: string;
|
||||
|
@ -9,7 +8,7 @@ export interface IUserLogin {
|
|||
username: string;
|
||||
name: string;
|
||||
language?: string;
|
||||
status: UserStatus;
|
||||
status: TUserStatus;
|
||||
statusText: string;
|
||||
roles: string[];
|
||||
avatarETag?: string;
|
||||
|
|
|
@ -19,6 +19,7 @@ import Navigation from '../../lib/Navigation';
|
|||
import SidebarItem from './SidebarItem';
|
||||
import styles from './styles';
|
||||
import { DrawerParamList } from '../../stacks/types';
|
||||
import { TUserStatus } from '../../definitions';
|
||||
|
||||
interface ISeparatorProps {
|
||||
theme: string;
|
||||
|
@ -40,7 +41,7 @@ interface ISidebarProps {
|
|||
Site_Name: string;
|
||||
user: {
|
||||
statusText: string;
|
||||
status: string;
|
||||
status: TUserStatus;
|
||||
username: string;
|
||||
name: string;
|
||||
roles: string[];
|
||||
|
|
|
@ -2,7 +2,6 @@ import React from 'react';
|
|||
import { FlatList, StyleSheet } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { UserStatus } from '../definitions/UserStatus';
|
||||
import { setUser } from '../actions/login';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import * as List from '../containers/List';
|
||||
|
@ -11,7 +10,7 @@ import SafeAreaView from '../containers/SafeAreaView';
|
|||
import Status from '../containers/Status/Status';
|
||||
import TextInput from '../containers/TextInput';
|
||||
import { LISTENER } from '../containers/Toast';
|
||||
import { IApplicationState, IBaseScreen, IUser } from '../definitions';
|
||||
import { IApplicationState, IBaseScreen, IUser, TUserStatus } from '../definitions';
|
||||
import I18n from '../i18n';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
import { getUserSelector } from '../selectors/login';
|
||||
|
@ -20,7 +19,12 @@ import EventEmitter from '../utils/events';
|
|||
import { showErrorAlert } from '../utils/info';
|
||||
import log, { events, logEvent } from '../utils/log';
|
||||
|
||||
const STATUS = [
|
||||
interface IStatus {
|
||||
id: TUserStatus;
|
||||
name: string;
|
||||
}
|
||||
|
||||
const STATUS: IStatus[] = [
|
||||
{
|
||||
id: 'online',
|
||||
name: 'Online'
|
||||
|
@ -135,7 +139,7 @@ class StatusView extends React.Component<IStatusViewProps, IStatusViewState> {
|
|||
value={statusText}
|
||||
containerStyle={styles.inputContainer}
|
||||
onChangeText={text => this.setState({ statusText: text })}
|
||||
left={<Status testID={`status-view-current-${user.status}`} style={styles.inputLeft} status={user.status!} size={24} />}
|
||||
left={<Status testID={`status-view-current-${user.status}`} style={styles.inputLeft} status={user.status} size={24} />}
|
||||
inputStyle={styles.inputStyle}
|
||||
placeholder={I18n.t('What_are_you_doing_right_now')}
|
||||
testID='status-view-input'
|
||||
|
@ -145,7 +149,7 @@ class StatusView extends React.Component<IStatusViewProps, IStatusViewState> {
|
|||
);
|
||||
};
|
||||
|
||||
renderItem = ({ item }: { item: { id: string; name: string } }) => {
|
||||
renderItem = ({ item }: { item: IStatus }) => {
|
||||
const { statusText } = this.state;
|
||||
const { user, dispatch } = this.props;
|
||||
const { id, name } = item;
|
||||
|
@ -159,7 +163,7 @@ class StatusView extends React.Component<IStatusViewProps, IStatusViewState> {
|
|||
try {
|
||||
const result = await RocketChat.setUserStatus(item.id, statusText);
|
||||
if (result.success) {
|
||||
dispatch(setUser({ status: item.id as UserStatus }));
|
||||
dispatch(setUser({ status: item.id }));
|
||||
}
|
||||
} catch (e: any) {
|
||||
showErrorAlert(I18n.t(e.data.errorType));
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue