Compare commits
1 Commits
develop
...
fix.number
Author | SHA1 | Date |
---|---|---|
Reinaldo Neto | 011c99d406 |
File diff suppressed because one or more lines are too long
|
@ -1,31 +1,34 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { useWindowDimensions } from 'react-native';
|
||||||
import { FlatList } from 'react-native-gesture-handler';
|
import { FlatList } from 'react-native-gesture-handler';
|
||||||
|
|
||||||
import { IEmoji } from '../../definitions/IEmoji';
|
|
||||||
import scrollPersistTaps from '../../lib/methods/helpers/scrollPersistTaps';
|
|
||||||
import { PressableEmoji } from './PressableEmoji';
|
|
||||||
import { EMOJI_BUTTON_SIZE } from './styles';
|
import { EMOJI_BUTTON_SIZE } from './styles';
|
||||||
|
import scrollPersistTaps from '../../lib/methods/helpers/scrollPersistTaps';
|
||||||
|
import { IEmoji } from '../../definitions/IEmoji';
|
||||||
|
import { PressableEmoji } from './PressableEmoji';
|
||||||
|
|
||||||
interface IEmojiCategoryProps {
|
interface IEmojiCategoryProps {
|
||||||
emojis: IEmoji[];
|
emojis: IEmoji[];
|
||||||
onEmojiSelected: (emoji: IEmoji) => void;
|
onEmojiSelected: (emoji: IEmoji) => void;
|
||||||
tabLabel?: string; // needed for react-native-scrollable-tab-view only
|
tabLabel?: string; // needed for react-native-scrollable-tab-view only
|
||||||
parentWidth: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const EmojiCategory = ({ onEmojiSelected, emojis, parentWidth }: IEmojiCategoryProps): React.ReactElement | null => {
|
const EmojiCategory = ({ onEmojiSelected, emojis }: IEmojiCategoryProps): React.ReactElement | null => {
|
||||||
if (!parentWidth) {
|
const { width } = useWindowDimensions();
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const numColumns = Math.trunc(parentWidth / EMOJI_BUTTON_SIZE);
|
const numColumns = Math.trunc(width / EMOJI_BUTTON_SIZE);
|
||||||
const marginHorizontal = (parentWidth % EMOJI_BUTTON_SIZE) / 2;
|
const marginHorizontal = (width % EMOJI_BUTTON_SIZE) / 2;
|
||||||
|
|
||||||
const renderItem = ({ item }: { item: IEmoji }) => <PressableEmoji emoji={item} onPress={onEmojiSelected} />;
|
const renderItem = ({ item }: { item: IEmoji }) => <PressableEmoji emoji={item} onPress={onEmojiSelected} />;
|
||||||
|
|
||||||
|
if (!width) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FlatList
|
<FlatList
|
||||||
key={`emoji-category-${parentWidth}`}
|
// needed to update the numColumns when the width changes
|
||||||
|
key={`emoji-category-${width}`}
|
||||||
keyExtractor={item => (typeof item === 'string' ? item : item.name)}
|
keyExtractor={item => (typeof item === 'string' ? item : item.name)}
|
||||||
data={emojis}
|
data={emojis}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
import ScrollableTabView from 'react-native-scrollable-tab-view';
|
import ScrollableTabView from 'react-native-scrollable-tab-view';
|
||||||
|
|
||||||
|
@ -20,8 +20,6 @@ const EmojiPicker = ({
|
||||||
searchedEmojis = []
|
searchedEmojis = []
|
||||||
}: IEmojiPickerProps): React.ReactElement | null => {
|
}: IEmojiPickerProps): React.ReactElement | null => {
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
const [parentWidth, setParentWidth] = useState(0);
|
|
||||||
|
|
||||||
const { frequentlyUsed, loaded } = useFrequentlyUsedEmoji();
|
const { frequentlyUsed, loaded } = useFrequentlyUsedEmoji();
|
||||||
|
|
||||||
const allCustomEmojis: ICustomEmojis = useAppSelector(
|
const allCustomEmojis: ICustomEmojis = useAppSelector(
|
||||||
|
@ -52,14 +50,7 @@ const EmojiPicker = ({
|
||||||
if (!emojis.length) {
|
if (!emojis.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (
|
return <EmojiCategory emojis={emojis} onEmojiSelected={(emoji: IEmoji) => handleEmojiSelect(emoji)} tabLabel={label} />;
|
||||||
<EmojiCategory
|
|
||||||
parentWidth={parentWidth}
|
|
||||||
emojis={emojis}
|
|
||||||
onEmojiSelected={(emoji: IEmoji) => handleEmojiSelect(emoji)}
|
|
||||||
tabLabel={label}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
|
@ -67,13 +58,9 @@ const EmojiPicker = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.emojiPickerContainer} onLayout={e => setParentWidth(e.nativeEvent.layout.width)}>
|
<View style={styles.emojiPickerContainer}>
|
||||||
{searching ? (
|
{searching ? (
|
||||||
<EmojiCategory
|
<EmojiCategory emojis={searchedEmojis} onEmojiSelected={(emoji: IEmoji) => handleEmojiSelect(emoji)} />
|
||||||
emojis={searchedEmojis}
|
|
||||||
onEmojiSelected={(emoji: IEmoji) => handleEmojiSelect(emoji)}
|
|
||||||
parentWidth={parentWidth}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<ScrollableTabView
|
<ScrollableTabView
|
||||||
renderTabBar={() => <TabBar />}
|
renderTabBar={() => <TabBar />}
|
||||||
|
|
|
@ -18,7 +18,7 @@ const MessageAvatar = React.memo(({ isHeader, avatar, author, small, navToRoomIn
|
||||||
style={small ? styles.avatarSmall : styles.avatar}
|
style={small ? styles.avatarSmall : styles.avatar}
|
||||||
text={avatar ? '' : author.username}
|
text={avatar ? '' : author.username}
|
||||||
size={small ? 20 : 36}
|
size={small ? 20 : 36}
|
||||||
borderRadius={4}
|
borderRadius={small ? 2 : 4}
|
||||||
onPress={author._id === user.id ? undefined : () => navToRoomInfo(navParam)}
|
onPress={author._id === user.id ? undefined : () => navToRoomInfo(navParam)}
|
||||||
getCustomEmoji={getCustomEmoji}
|
getCustomEmoji={getCustomEmoji}
|
||||||
avatar={avatar}
|
avatar={avatar}
|
||||||
|
|
|
@ -247,8 +247,6 @@ const Reply = React.memo(
|
||||||
>
|
>
|
||||||
<View style={styles.attachmentContainer}>
|
<View style={styles.attachmentContainer}>
|
||||||
<Title attachment={attachment} timeFormat={timeFormat} theme={theme} />
|
<Title attachment={attachment} timeFormat={timeFormat} theme={theme} />
|
||||||
<Description attachment={attachment} getCustomEmoji={getCustomEmoji} theme={theme} />
|
|
||||||
<UrlImage image={attachment.thumb_url} />
|
|
||||||
<Attachments
|
<Attachments
|
||||||
attachments={attachment.attachments}
|
attachments={attachment.attachments}
|
||||||
getCustomEmoji={getCustomEmoji}
|
getCustomEmoji={getCustomEmoji}
|
||||||
|
@ -257,6 +255,8 @@ const Reply = React.memo(
|
||||||
isReply
|
isReply
|
||||||
id={messageId}
|
id={messageId}
|
||||||
/>
|
/>
|
||||||
|
<UrlImage image={attachment.thumb_url} />
|
||||||
|
<Description attachment={attachment} getCustomEmoji={getCustomEmoji} theme={theme} />
|
||||||
<Fields attachment={attachment} getCustomEmoji={getCustomEmoji} theme={theme} />
|
<Fields attachment={attachment} getCustomEmoji={getCustomEmoji} theme={theme} />
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<View style={[styles.backdrop]}>
|
<View style={[styles.backdrop]}>
|
||||||
|
|
|
@ -102,6 +102,7 @@ export interface ISubscription {
|
||||||
onHold?: boolean;
|
onHold?: boolean;
|
||||||
source?: IOmnichannelSource;
|
source?: IOmnichannelSource;
|
||||||
hideMentionStatus?: boolean;
|
hideMentionStatus?: boolean;
|
||||||
|
usersCount?: number;
|
||||||
// https://nozbe.github.io/WatermelonDB/Relation.html#relation-api
|
// https://nozbe.github.io/WatermelonDB/Relation.html#relation-api
|
||||||
messages: RelationModified<TMessageModel>;
|
messages: RelationModified<TMessageModel>;
|
||||||
threads: RelationModified<TThreadModel>;
|
threads: RelationModified<TThreadModel>;
|
||||||
|
|
|
@ -137,5 +137,7 @@ export default class Subscription extends Model {
|
||||||
|
|
||||||
@field('on_hold') onHold;
|
@field('on_hold') onHold;
|
||||||
|
|
||||||
|
@field('users_count') usersCount;
|
||||||
|
|
||||||
@json('source', sanitizer) source;
|
@json('source', sanitizer) source;
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,6 +257,15 @@ export default schemaMigrations({
|
||||||
columns: [{ name: 'e2e_suggested_key', type: 'string', isOptional: true }]
|
columns: [{ name: 'e2e_suggested_key', type: 'string', isOptional: true }]
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
toVersion: 21,
|
||||||
|
steps: [
|
||||||
|
addColumns({
|
||||||
|
table: 'subscriptions',
|
||||||
|
columns: [{ name: 'users_count', type: 'string', isOptional: true }]
|
||||||
|
})
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { appSchema, tableSchema } from '@nozbe/watermelondb';
|
import { appSchema, tableSchema } from '@nozbe/watermelondb';
|
||||||
|
|
||||||
export default appSchema({
|
export default appSchema({
|
||||||
version: 20,
|
version: 21,
|
||||||
tables: [
|
tables: [
|
||||||
tableSchema({
|
tableSchema({
|
||||||
name: 'subscriptions',
|
name: 'subscriptions',
|
||||||
|
@ -63,7 +63,8 @@ export default appSchema({
|
||||||
{ name: 'team_main', type: 'boolean', isOptional: true }, // Use `Q.notEq(true)` to get false or null
|
{ name: 'team_main', type: 'boolean', isOptional: true }, // Use `Q.notEq(true)` to get false or null
|
||||||
{ name: 'on_hold', type: 'boolean', isOptional: true },
|
{ name: 'on_hold', type: 'boolean', isOptional: true },
|
||||||
{ name: 'source', type: 'string', isOptional: true },
|
{ name: 'source', type: 'string', isOptional: true },
|
||||||
{ name: 'hide_mention_status', type: 'boolean', isOptional: true }
|
{ name: 'hide_mention_status', type: 'boolean', isOptional: true },
|
||||||
|
{ name: 'users_count', type: 'number', isOptional: true }
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
tableSchema({
|
tableSchema({
|
||||||
|
|
|
@ -85,6 +85,9 @@ export const merge = (
|
||||||
if (room && 'source' in room) {
|
if (room && 'source' in room) {
|
||||||
mergedSubscription.source = room?.source;
|
mergedSubscription.source = room?.source;
|
||||||
}
|
}
|
||||||
|
if (room && 'usersCount' in room) {
|
||||||
|
mergedSubscription.usersCount = room.usersCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mergedSubscription.name) {
|
if (!mergedSubscription.name) {
|
||||||
|
|
|
@ -85,7 +85,7 @@ interface IRoomActionsViewProps extends IActionSheetProvider, IBaseScreen<ChatsS
|
||||||
|
|
||||||
interface IRoomActionsViewState {
|
interface IRoomActionsViewState {
|
||||||
room: TSubscriptionModel;
|
room: TSubscriptionModel;
|
||||||
membersCount: number;
|
membersCount?: number;
|
||||||
member: Partial<IUser>;
|
member: Partial<IUser>;
|
||||||
joined: boolean;
|
joined: boolean;
|
||||||
canViewMembers: boolean;
|
canViewMembers: boolean;
|
||||||
|
@ -152,7 +152,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
this.roomObservable = room.observe();
|
this.roomObservable = room.observe();
|
||||||
this.subscription = this.roomObservable.subscribe(changes => {
|
this.subscription = this.roomObservable.subscribe(changes => {
|
||||||
if (this.mounted) {
|
if (this.mounted) {
|
||||||
this.setState({ room: changes });
|
this.setState({ room: changes, membersCount: changes.usersCount });
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.state.room = changes;
|
this.state.room = changes;
|
||||||
|
@ -1050,7 +1050,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
<>
|
<>
|
||||||
<List.Item
|
<List.Item
|
||||||
title='Members'
|
title='Members'
|
||||||
subtitle={membersCount > 0 ? `${membersCount} ${I18n.t('members')}` : undefined}
|
subtitle={membersCount && membersCount > 0 ? `${membersCount} ${I18n.t('members')}` : undefined}
|
||||||
onPress={() => this.onPressTouchable({ route: 'RoomMembersView', params: { rid, room, joined: this.joined } })}
|
onPress={() => this.onPressTouchable({ route: 'RoomMembersView', params: { rid, room, joined: this.joined } })}
|
||||||
testID='room-actions-members'
|
testID='room-actions-members'
|
||||||
left={() => <List.Icon name='team' />}
|
left={() => <List.Icon name='team' />}
|
||||||
|
|
Loading…
Reference in New Issue