Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion app/lib/rocketchat/rocketchat.js
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,6 @@ const RocketChat = {
return sdk.methodCallWrapper(method, ...params);
},
getUserInfo,

getUidDirectMessage(room) {
const { id: userId } = reduxStore.getState().login.user;

Expand Down
13 changes: 11 additions & 2 deletions app/lib/rocketchat/services/restApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,9 +421,18 @@ export const getDepartmentInfo = (departmentId: string): any =>
// RC 2.2.0
sdk.get(`livechat/department/${departmentId}?includeAgents=false`);

export const getDepartments = () =>
export const getDepartments = (args?: { count: number; offset: number; text: string }) => {
let params;
if (args) {
params = {
text: args.text,
count: args.count,
offset: args.offset
};
}
// RC 2.2.0
sdk.get('livechat/department');
return sdk.get('livechat/department', params);
};

export const usersAutoComplete = (selector: any) =>
// RC 2.4.0
Expand Down
6 changes: 4 additions & 2 deletions app/stacks/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,10 @@ export type ChatsStackParamList = {
PickerView: {
title: string;
data: IOptionsField[];
value?: any; // TODO: Change
onChangeText?: ((text: string) => IOptionsField[]) | ((term?: string) => Promise<any>);
value?: string;
onSearch?: (text?: string) => Promise<any>;
onEndReached?: (text: string, offset?: number) => Promise<any>;
total?: number;
goBack?: boolean;
onChangeValue: Function;
};
Expand Down
58 changes: 29 additions & 29 deletions app/views/ForwardLivechatView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import RocketChat from '../lib/rocketchat';
import OrSeparator from '../containers/OrSeparator';
import Input from '../containers/UIKit/MultiSelect/Input';
import { forwardRoom as forwardRoomAction } from '../actions/room';
import { ILivechatDepartment } from './definition/ILivechatDepartment';
import { IRoom } from '../definitions';
import { ChatsStackParamList } from '../stacks/types';
import { IOptionsField } from './NotificationPreferencesView/options';

const styles = StyleSheet.create({
container: {
Expand All @@ -23,14 +24,6 @@ const styles = StyleSheet.create({
}
});

// TODO: Refactor when migrate room
interface IRoom {
departmentId?: any;
servedBy?: {
_id: string;
};
}

interface ITransferData {
roomId: string;
userId?: string;
Expand All @@ -41,35 +34,38 @@ interface IUser {
username: string;
_id: string;
}

interface IParsedData {
label: string;
value: string;
}

interface IForwardLivechatViewProps {
navigation: StackNavigationProp<ChatsStackParamList, 'ForwardLivechatView'>;
route: RouteProp<ChatsStackParamList, 'ForwardLivechatView'>;
theme: string;
forwardRoom: (rid: string, transferData: ITransferData) => void;
}

const COUNT_DEPARTMENT = 50;

const ForwardLivechatView = ({ forwardRoom, navigation, route, theme }: IForwardLivechatViewProps) => {
const [departments, setDepartments] = useState<IParsedData[]>([]);
const [departments, setDepartments] = useState<IOptionsField[]>([]);
const [departmentId, setDepartment] = useState('');
const [users, setUsers] = useState<IParsedData[]>([]);
const [departmentTotal, setDepartmentTotal] = useState(0);
const [users, setUsers] = useState<IOptionsField[]>([]);
const [userId, setUser] = useState();
const [room, setRoom] = useState<IRoom>({});
const [room, setRoom] = useState<IRoom>({} as IRoom);

const rid = route.params?.rid;

const getDepartments = async () => {
const getDepartments = async (text = '', offset = 0) => {
try {
const result: any = await RocketChat.getDepartments();
const result = await RocketChat.getDepartments({ count: COUNT_DEPARTMENT, text, offset });
if (result.success) {
setDepartments(
result.departments.map((department: ILivechatDepartment) => ({ label: department.name, value: department._id }))
);
const parsedDepartments: IOptionsField[] = result.departments.map(department => ({
label: department.name,
value: department._id
}));
if (!text && !offset) {
setDepartments(parsedDepartments);
setDepartmentTotal(result?.total);
}
return { data: parsedDepartments, total: result?.total, offset: result?.offset };
}
} catch {
// do nothing
Expand All @@ -80,26 +76,27 @@ const ForwardLivechatView = ({ forwardRoom, navigation, route, theme }: IForward
try {
const { servedBy: { _id: agentId } = {} } = room;
const _id = agentId && { $ne: agentId };
const result: any = await RocketChat.usersAutoComplete({
const result = await RocketChat.usersAutoComplete({
conditions: { _id, status: { $ne: 'offline' }, statusLivechat: 'available' },
term
});
if (result.success) {
const parsedUsers = result.items.map((user: IUser) => ({ label: user.username, value: user._id }));
setUsers(parsedUsers);
return parsedUsers;
if (!term) {
setUsers(parsedUsers);
}
return { data: parsedUsers };
}
} catch {
// do nothing
}
return [];
};

const getRoom = async () => {
try {
const result = await RocketChat.getRoomInfo(rid);
if (result.success) {
setRoom(result.room);
setRoom(result.room as IRoom);
}
} catch {
// do nothing
Expand Down Expand Up @@ -148,6 +145,9 @@ const ForwardLivechatView = ({ forwardRoom, navigation, route, theme }: IForward
value: room?.departmentId,
data: departments,
onChangeValue: setDepartment,
onSearch: getDepartments,
onEndReached: getDepartments,
total: departmentTotal,
goBack: false
});
};
Expand All @@ -157,7 +157,7 @@ const ForwardLivechatView = ({ forwardRoom, navigation, route, theme }: IForward
title: I18n.t('Forward_to_user'),
data: users,
onChangeValue: setUser,
onChangeText: getUsers,
onSearch: getUsers,
goBack: false
});
};
Expand Down
78 changes: 50 additions & 28 deletions app/views/PickerView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ const styles = StyleSheet.create({
paddingVertical: 56,
...sharedStyles.textSemibold,
...sharedStyles.textAlignCenter
},
listNoHeader: {
marginTop: 32
}
});

Expand All @@ -34,9 +37,16 @@ interface IItem {
theme: string;
}

interface IRenderSearch {
hasSearch: boolean;
onChangeText: (text: string) => void;
}

interface IPickerViewState {
data: IOptionsField[];
value: string;
total: number;
searchText: string;
}

interface IPickerViewProps {
Expand All @@ -54,8 +64,22 @@ const Item = React.memo(({ item, selected, onItemPress, theme }: IItem) => (
/>
));

const RenderSearch = ({ hasSearch, onChangeText }: IRenderSearch) => {
if (!hasSearch) {
return <List.Separator style={styles.listNoHeader} />;
}
return (
<>
<View style={styles.search}>
<SearchBox onChangeText={onChangeText} />
</View>
<List.Separator />
</>
);
};

class PickerView extends React.PureComponent<IPickerViewProps, IPickerViewState> {
private onSearch?: ((text: string) => IOptionsField[]) | ((term?: string | undefined) => Promise<any>);
private onSearch?: (text?: string) => Promise<any>;

static navigationOptions = ({ route }: IPickerViewProps) => ({
title: route.params?.title ?? I18n.t('Select_an_option')
Expand All @@ -64,10 +88,10 @@ class PickerView extends React.PureComponent<IPickerViewProps, IPickerViewState>
constructor(props: IPickerViewProps) {
super(props);
const data = props.route.params?.data ?? [];
const value = props.route.params?.value;
this.state = { data, value };

this.onSearch = props.route.params?.onChangeText;
const value = props.route.params?.value ?? '';
const total = props.route.params?.total ?? 0;
this.state = { data, value, total, searchText: '' };
this.onSearch = props.route.params?.onSearch;
}

onChangeValue = (value: string) => {
Expand All @@ -80,36 +104,33 @@ class PickerView extends React.PureComponent<IPickerViewProps, IPickerViewState>
}
};

onChangeText = debounce(
async (text: string) => {
if (this.onSearch) {
const data = await this.onSearch(text);
this.setState({ data });
onChangeText = debounce(async (searchText: string) => {
if (this.onSearch) {
const data = await this.onSearch(searchText);
if (data?.data) {
this.setState({ ...data, searchText });
}
},
300,
true
);

renderSearch() {
if (!this.onSearch) {
return null;
}

return (
<View style={styles.search}>
<SearchBox onChangeText={this.onChangeText} />
</View>
);
}
}, 500);

onEndReached = async () => {
const { route } = this.props;
const { data, total, searchText } = this.state;
const onEndReached = route.params?.onEndReached;
if (onEndReached && data.length < total) {
const val = await onEndReached(searchText, data.length);
if (val?.data) {
this.setState({ ...val, data: [...data, ...val.data] });
}
}
};

render() {
const { data, value } = this.state;
const { theme } = this.props;

return (
<SafeAreaView>
{this.renderSearch()}
<FlatList
data={data}
keyExtractor={item => item.value as string}
Expand All @@ -121,13 +142,14 @@ class PickerView extends React.PureComponent<IPickerViewProps, IPickerViewState>
onItemPress={() => this.onChangeValue(item.value as string)}
/>
)}
onEndReached={() => this.onEndReached()}
onEndReachedThreshold={0.5}
ItemSeparatorComponent={List.Separator}
ListHeaderComponent={List.Separator}
ListHeaderComponent={<RenderSearch hasSearch={!!this.onSearch} onChangeText={this.onChangeText} />}
ListFooterComponent={List.Separator}
ListEmptyComponent={() => (
<Text style={[styles.noResult, { color: themes[theme].titleText }]}>{I18n.t('No_results_found')}</Text>
)}
contentContainerStyle={[List.styles.contentContainerStyleFlatList]}
/>
</SafeAreaView>
);
Expand Down