Chore: Properly type MessageActions (#3930)
This commit is contained in:
parent
c483abfa60
commit
4416f82665
|
@ -2,7 +2,7 @@ import React, { ForwardedRef, forwardRef, useContext, useRef } from 'react';
|
|||
|
||||
import ActionSheet from './ActionSheet';
|
||||
|
||||
export type TActionSheetOptionsItem = { title: string; icon: string; onPress: () => void };
|
||||
export type TActionSheetOptionsItem = { title: string; icon: string; onPress: () => void; danger?: boolean };
|
||||
|
||||
export type TActionSheetOptions = {
|
||||
options: TActionSheetOptionsItem[];
|
||||
|
|
|
@ -8,6 +8,7 @@ const CustomEmoji = React.memo(
|
|||
<FastImage
|
||||
style={style}
|
||||
source={{
|
||||
// @ts-ignore
|
||||
uri: `${baseUrl}/emoji-custom/${encodeURIComponent(emoji.content || emoji.name)}.${emoji.extension}`,
|
||||
priority: FastImage.priority.high
|
||||
}}
|
||||
|
|
|
@ -56,6 +56,7 @@ class EmojiCategory extends React.Component<Partial<IEmojiCategory>> {
|
|||
contentContainerStyle={{ marginHorizontal }}
|
||||
// rerender FlatList in case of width changes
|
||||
key={`emoji-category-${width}`}
|
||||
// @ts-ignore
|
||||
keyExtractor={item => (item && item.isCustom && item.content) || item}
|
||||
data={emojis}
|
||||
extraData={this.props}
|
||||
|
|
|
@ -109,6 +109,7 @@ class EmojiPicker extends Component<IEmojiPickerProps, IEmojiPickerState> {
|
|||
const freqEmojiCollection = db.get('frequently_used_emojis');
|
||||
let freqEmojiRecord: any;
|
||||
try {
|
||||
// @ts-ignore
|
||||
freqEmojiRecord = await freqEmojiCollection.find(emoji.content);
|
||||
} catch (error) {
|
||||
// Do nothing
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { FlatList, StyleSheet, Text, View } from 'react-native';
|
||||
|
||||
import { withTheme } from '../../theme';
|
||||
import { useTheme } from '../../theme';
|
||||
import { themes } from '../../constants/colors';
|
||||
import { CustomIcon } from '../../lib/Icons';
|
||||
import shortnameToUnicode from '../../utils/shortnameToUnicode';
|
||||
|
@ -10,26 +10,30 @@ import database from '../../lib/database';
|
|||
import { Button } from '../ActionSheet';
|
||||
import { useDimensions } from '../../dimensions';
|
||||
import sharedStyles from '../../views/Styles';
|
||||
import { IEmoji } from '../../definitions/IEmoji';
|
||||
import { TFrequentlyUsedEmojiModel } from '../../definitions/IFrequentlyUsedEmoji';
|
||||
import { TAnyMessageModel } from '../../definitions';
|
||||
import { IEmoji } from '../../definitions/IEmoji';
|
||||
|
||||
interface IHeader {
|
||||
handleReaction: Function;
|
||||
type TItem = TFrequentlyUsedEmojiModel | string;
|
||||
|
||||
export interface IHeader {
|
||||
handleReaction: (emoji: TItem, message: TAnyMessageModel) => void;
|
||||
server: string;
|
||||
message: object;
|
||||
message: TAnyMessageModel;
|
||||
isMasterDetail: boolean;
|
||||
theme?: string;
|
||||
}
|
||||
|
||||
type TOnReaction = ({ emoji }: { emoji: TItem }) => void;
|
||||
|
||||
interface THeaderItem {
|
||||
item: IEmoji;
|
||||
onReaction: Function;
|
||||
item: TItem;
|
||||
onReaction: TOnReaction;
|
||||
server: string;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
interface THeaderFooter {
|
||||
onReaction: any;
|
||||
onReaction: TOnReaction;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
|
@ -62,25 +66,32 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
const keyExtractor = (item: any) => item?.id || item;
|
||||
const keyExtractor = (item: TItem) => {
|
||||
const emojiModel = item as TFrequentlyUsedEmojiModel;
|
||||
return (emojiModel.id ? emojiModel.content : item) as string;
|
||||
};
|
||||
|
||||
const DEFAULT_EMOJIS = ['clap', '+1', 'heart_eyes', 'grinning', 'thinking_face', 'smiley'];
|
||||
|
||||
const HeaderItem = React.memo(({ item, onReaction, server, theme }: THeaderItem) => (
|
||||
const HeaderItem = ({ item, onReaction, server, theme }: THeaderItem) => {
|
||||
const emojiModel = item as TFrequentlyUsedEmojiModel;
|
||||
const emoji = (emojiModel.id ? emojiModel.content : item) as string;
|
||||
return (
|
||||
<Button
|
||||
testID={`message-actions-emoji-${item.content || item}`}
|
||||
onPress={() => onReaction({ emoji: `:${item.content || item}:` })}
|
||||
testID={`message-actions-emoji-${emoji}`}
|
||||
onPress={() => onReaction({ emoji: `:${emoji}:` })}
|
||||
style={[styles.headerItem, { backgroundColor: themes[theme].auxiliaryBackground }]}
|
||||
theme={theme}>
|
||||
{item?.isCustom ? (
|
||||
<CustomEmoji style={styles.customEmoji} emoji={item} baseUrl={server} />
|
||||
{emojiModel?.isCustom ? (
|
||||
<CustomEmoji style={styles.customEmoji} emoji={emojiModel as IEmoji} baseUrl={server} />
|
||||
) : (
|
||||
<Text style={styles.headerIcon}>{shortnameToUnicode(`:${item.content || item}:`)}</Text>
|
||||
<Text style={styles.headerIcon}>{shortnameToUnicode(`:${emoji}:`)}</Text>
|
||||
)}
|
||||
</Button>
|
||||
));
|
||||
);
|
||||
};
|
||||
|
||||
const HeaderFooter = React.memo(({ onReaction, theme }: THeaderFooter) => (
|
||||
const HeaderFooter = ({ onReaction, theme }: THeaderFooter) => (
|
||||
<Button
|
||||
testID='add-reaction'
|
||||
onPress={onReaction}
|
||||
|
@ -88,17 +99,19 @@ const HeaderFooter = React.memo(({ onReaction, theme }: THeaderFooter) => (
|
|||
theme={theme}>
|
||||
<CustomIcon name='reaction-add' size={24} color={themes[theme].bodyText} />
|
||||
</Button>
|
||||
));
|
||||
);
|
||||
|
||||
const Header = React.memo(({ handleReaction, server, message, isMasterDetail, theme }: IHeader) => {
|
||||
const [items, setItems] = useState<(TFrequentlyUsedEmojiModel | string)[]>([]);
|
||||
const { width, height }: any = useDimensions();
|
||||
const Header = React.memo(({ handleReaction, server, message, isMasterDetail }: IHeader) => {
|
||||
const [items, setItems] = useState<TItem[]>([]);
|
||||
const { width, height } = useDimensions();
|
||||
const { theme } = useTheme();
|
||||
|
||||
// TODO: create custom hook to re-render based on screen size
|
||||
const setEmojis = async () => {
|
||||
try {
|
||||
const db = database.active;
|
||||
const freqEmojiCollection = db.get('frequently_used_emojis');
|
||||
let freqEmojis: (TFrequentlyUsedEmojiModel | string)[] = await freqEmojiCollection.query().fetch();
|
||||
let freqEmojis: TItem[] = await freqEmojiCollection.query().fetch();
|
||||
|
||||
const isLandscape = width > height;
|
||||
const size = (isLandscape || isMasterDetail ? width / 2 : width) - CONTAINER_MARGIN * 2;
|
||||
|
@ -115,22 +128,21 @@ const Header = React.memo(({ handleReaction, server, message, isMasterDetail, th
|
|||
setEmojis();
|
||||
}, []);
|
||||
|
||||
const onReaction = ({ emoji }: { emoji: IEmoji }) => handleReaction(emoji, message);
|
||||
const onReaction: TOnReaction = ({ emoji }) => handleReaction(emoji, message);
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ item }) => <HeaderItem item={item} onReaction={onReaction} server={server} theme={theme!} />,
|
||||
[]
|
||||
const renderItem = ({ item }: { item: TItem }) => (
|
||||
<HeaderItem item={item} onReaction={onReaction} server={server} theme={theme} />
|
||||
);
|
||||
|
||||
const renderFooter = useCallback(() => <HeaderFooter onReaction={onReaction} theme={theme!} />, []);
|
||||
const renderFooter = () => <HeaderFooter onReaction={onReaction} theme={theme} />;
|
||||
|
||||
return (
|
||||
<View style={[styles.container, { backgroundColor: themes[theme!].focusedBackground }]}>
|
||||
<View style={[styles.container, { backgroundColor: themes[theme].focusedBackground }]}>
|
||||
<FlatList
|
||||
data={items}
|
||||
renderItem={renderItem}
|
||||
ListFooterComponent={renderFooter}
|
||||
style={{ backgroundColor: themes[theme!].focusedBackground }}
|
||||
style={{ backgroundColor: themes[theme].focusedBackground }}
|
||||
keyExtractor={keyExtractor}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
scrollEnabled={false}
|
||||
|
@ -140,4 +152,4 @@ const Header = React.memo(({ handleReaction, server, message, isMasterDetail, th
|
|||
);
|
||||
});
|
||||
|
||||
export default withTheme(Header);
|
||||
export default Header;
|
||||
|
|
|
@ -13,33 +13,33 @@ import { getMessageTranslation } from '../message/utils';
|
|||
import { LISTENER } from '../Toast';
|
||||
import EventEmitter from '../../utils/events';
|
||||
import { showConfirmationAlert } from '../../utils/info';
|
||||
import { useActionSheet } from '../ActionSheet';
|
||||
import Header, { HEADER_HEIGHT } from './Header';
|
||||
import { TActionSheetOptionsItem, useActionSheet } from '../ActionSheet';
|
||||
import Header, { HEADER_HEIGHT, IHeader } from './Header';
|
||||
import events from '../../utils/log/events';
|
||||
import { ILoggedUser, TAnyMessageModel, TSubscriptionModel } from '../../definitions';
|
||||
import { IApplicationState, ILoggedUser, TAnyMessageModel, TSubscriptionModel } from '../../definitions';
|
||||
|
||||
export interface IMessageActions {
|
||||
room: TSubscriptionModel;
|
||||
tmid?: string;
|
||||
user: Pick<ILoggedUser, 'id'>;
|
||||
editInit: Function;
|
||||
reactionInit: Function;
|
||||
onReactionPress: Function;
|
||||
replyInit: Function;
|
||||
editInit: (message: TAnyMessageModel) => void;
|
||||
reactionInit: (message: TAnyMessageModel) => void;
|
||||
onReactionPress: (shortname: string, messageId: string) => void;
|
||||
replyInit: (message: TAnyMessageModel, mention: boolean) => void;
|
||||
isMasterDetail: boolean;
|
||||
isReadOnly: boolean;
|
||||
Message_AllowDeleting: boolean;
|
||||
Message_AllowDeleting_BlockDeleteInMinutes: number;
|
||||
Message_AllowEditing: boolean;
|
||||
Message_AllowEditing_BlockEditInMinutes: number;
|
||||
Message_AllowPinning: boolean;
|
||||
Message_AllowStarring: boolean;
|
||||
Message_Read_Receipt_Store_Users: boolean;
|
||||
Message_AllowDeleting?: boolean;
|
||||
Message_AllowDeleting_BlockDeleteInMinutes?: number;
|
||||
Message_AllowEditing?: boolean;
|
||||
Message_AllowEditing_BlockEditInMinutes?: number;
|
||||
Message_AllowPinning?: boolean;
|
||||
Message_AllowStarring?: boolean;
|
||||
Message_Read_Receipt_Store_Users?: boolean;
|
||||
server: string;
|
||||
editMessagePermission: [];
|
||||
deleteMessagePermission: [];
|
||||
forceDeleteMessagePermission: [];
|
||||
pinMessagePermission: [];
|
||||
editMessagePermission?: string[];
|
||||
deleteMessagePermission?: string[];
|
||||
forceDeleteMessagePermission?: string[];
|
||||
pinMessagePermission?: string[];
|
||||
}
|
||||
|
||||
const MessageActions = React.memo(
|
||||
|
@ -69,9 +69,14 @@ const MessageActions = React.memo(
|
|||
pinMessagePermission
|
||||
}: IMessageActions,
|
||||
ref
|
||||
): any => {
|
||||
let permissions: any = {};
|
||||
const { showActionSheet, hideActionSheet }: any = useActionSheet();
|
||||
) => {
|
||||
let permissions = {
|
||||
hasEditPermission: false,
|
||||
hasDeletePermission: false,
|
||||
hasForceDeletePermission: false,
|
||||
hasPinPermission: false
|
||||
};
|
||||
const { showActionSheet, hideActionSheet } = useActionSheet();
|
||||
|
||||
const getPermissions = async () => {
|
||||
try {
|
||||
|
@ -88,9 +93,9 @@ const MessageActions = React.memo(
|
|||
}
|
||||
};
|
||||
|
||||
const isOwn = (message: any) => message.u && message.u._id === user.id;
|
||||
const isOwn = (message: TAnyMessageModel) => message.u && message.u._id === user.id;
|
||||
|
||||
const allowEdit = (message: any) => {
|
||||
const allowEdit = (message: TAnyMessageModel) => {
|
||||
if (isReadOnly) {
|
||||
return false;
|
||||
}
|
||||
|
@ -105,7 +110,7 @@ const MessageActions = React.memo(
|
|||
if (message.ts != null) {
|
||||
msgTs = moment(message.ts);
|
||||
}
|
||||
let currentTsDiff: any;
|
||||
let currentTsDiff = 0;
|
||||
if (msgTs != null) {
|
||||
currentTsDiff = moment().diff(msgTs, 'minutes');
|
||||
}
|
||||
|
@ -114,7 +119,7 @@ const MessageActions = React.memo(
|
|||
return true;
|
||||
};
|
||||
|
||||
const allowDelete = (message: any) => {
|
||||
const allowDelete = (message: TAnyMessageModel) => {
|
||||
if (isReadOnly) {
|
||||
return false;
|
||||
}
|
||||
|
@ -136,7 +141,7 @@ const MessageActions = React.memo(
|
|||
if (message.ts != null) {
|
||||
msgTs = moment(message.ts);
|
||||
}
|
||||
let currentTsDiff: any;
|
||||
let currentTsDiff = 0;
|
||||
if (msgTs != null) {
|
||||
currentTsDiff = moment().diff(msgTs, 'minutes');
|
||||
}
|
||||
|
@ -145,19 +150,19 @@ const MessageActions = React.memo(
|
|||
return true;
|
||||
};
|
||||
|
||||
const getPermalink = (message: any) => RocketChat.getPermalinkMessage(message);
|
||||
const getPermalink = (message: TAnyMessageModel) => RocketChat.getPermalinkMessage(message);
|
||||
|
||||
const handleReply = (message: any) => {
|
||||
const handleReply = (message: TAnyMessageModel) => {
|
||||
logEvent(events.ROOM_MSG_ACTION_REPLY);
|
||||
replyInit(message, true);
|
||||
};
|
||||
|
||||
const handleEdit = (message: any) => {
|
||||
const handleEdit = (message: TAnyMessageModel) => {
|
||||
logEvent(events.ROOM_MSG_ACTION_EDIT);
|
||||
editInit(message);
|
||||
};
|
||||
|
||||
const handleCreateDiscussion = (message: any) => {
|
||||
const handleCreateDiscussion = (message: TAnyMessageModel) => {
|
||||
logEvent(events.ROOM_MSG_ACTION_DISCUSSION);
|
||||
const params = { message, channel: room, showCloseModal: true };
|
||||
if (isMasterDetail) {
|
||||
|
@ -167,7 +172,7 @@ const MessageActions = React.memo(
|
|||
}
|
||||
};
|
||||
|
||||
const handleUnread = async (message: any) => {
|
||||
const handleUnread = async (message: TAnyMessageModel) => {
|
||||
logEvent(events.ROOM_MSG_ACTION_UNREAD);
|
||||
const { id: messageId, ts } = message;
|
||||
const { rid } = room;
|
||||
|
@ -179,7 +184,7 @@ const MessageActions = React.memo(
|
|||
const subRecord = await subCollection.find(rid);
|
||||
await db.write(async () => {
|
||||
try {
|
||||
await subRecord.update(sub => (sub.lastOpen = ts));
|
||||
await subRecord.update(sub => (sub.lastOpen = ts as Date)); // TODO: reevaluate IMessage
|
||||
} catch {
|
||||
// do nothing
|
||||
}
|
||||
|
@ -192,42 +197,44 @@ const MessageActions = React.memo(
|
|||
}
|
||||
};
|
||||
|
||||
const handlePermalink = async (message: any) => {
|
||||
const handlePermalink = async (message: TAnyMessageModel) => {
|
||||
logEvent(events.ROOM_MSG_ACTION_PERMALINK);
|
||||
try {
|
||||
const permalink: any = await getPermalink(message);
|
||||
Clipboard.setString(permalink);
|
||||
const permalink = await getPermalink(message);
|
||||
Clipboard.setString(permalink ?? '');
|
||||
EventEmitter.emit(LISTENER, { message: I18n.t('Permalink_copied_to_clipboard') });
|
||||
} catch {
|
||||
logEvent(events.ROOM_MSG_ACTION_PERMALINK_F);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCopy = async (message: any) => {
|
||||
const handleCopy = async (message: TAnyMessageModel) => {
|
||||
logEvent(events.ROOM_MSG_ACTION_COPY);
|
||||
await Clipboard.setString(message?.attachments?.[0]?.description || message.msg);
|
||||
await Clipboard.setString((message?.attachments?.[0]?.description || message.msg) ?? '');
|
||||
EventEmitter.emit(LISTENER, { message: I18n.t('Copied_to_clipboard') });
|
||||
};
|
||||
|
||||
const handleShare = async (message: any) => {
|
||||
const handleShare = async (message: TAnyMessageModel) => {
|
||||
logEvent(events.ROOM_MSG_ACTION_SHARE);
|
||||
try {
|
||||
const permalink: any = await getPermalink(message);
|
||||
const permalink = await getPermalink(message);
|
||||
if (permalink) {
|
||||
Share.share({ message: permalink });
|
||||
}
|
||||
} catch {
|
||||
logEvent(events.ROOM_MSG_ACTION_SHARE_F);
|
||||
}
|
||||
};
|
||||
|
||||
const handleQuote = (message: any) => {
|
||||
const handleQuote = (message: TAnyMessageModel) => {
|
||||
logEvent(events.ROOM_MSG_ACTION_QUOTE);
|
||||
replyInit(message, false);
|
||||
};
|
||||
|
||||
const handleStar = async (message: any) => {
|
||||
const handleStar = async (message: TAnyMessageModel) => {
|
||||
logEvent(message.starred ? events.ROOM_MSG_ACTION_UNSTAR : events.ROOM_MSG_ACTION_STAR);
|
||||
try {
|
||||
await RocketChat.toggleStarMessage(message.id, message.starred);
|
||||
await RocketChat.toggleStarMessage(message.id, message.starred as boolean); // TODO: reevaluate `message.starred` type on IMessage
|
||||
EventEmitter.emit(LISTENER, { message: message.starred ? I18n.t('Message_unstarred') : I18n.t('Message_starred') });
|
||||
} catch (e) {
|
||||
logEvent(events.ROOM_MSG_ACTION_STAR_F);
|
||||
|
@ -235,20 +242,21 @@ const MessageActions = React.memo(
|
|||
}
|
||||
};
|
||||
|
||||
const handlePin = async (message: any) => {
|
||||
const handlePin = async (message: TAnyMessageModel) => {
|
||||
logEvent(events.ROOM_MSG_ACTION_PIN);
|
||||
try {
|
||||
await RocketChat.togglePinMessage(message.id, message.pinned);
|
||||
await RocketChat.togglePinMessage(message.id, message.pinned as boolean); // TODO: reevaluate `message.pinned` type on IMessage
|
||||
} catch (e) {
|
||||
logEvent(events.ROOM_MSG_ACTION_PIN_F);
|
||||
log(e);
|
||||
}
|
||||
};
|
||||
|
||||
const handleReaction = (shortname: any, message: any) => {
|
||||
const handleReaction: IHeader['handleReaction'] = (shortname, message) => {
|
||||
logEvent(events.ROOM_MSG_ACTION_REACTION);
|
||||
if (shortname) {
|
||||
onReactionPress(shortname, message.id);
|
||||
// TODO: evaluate unification with IEmoji
|
||||
onReactionPress(shortname as any, message.id);
|
||||
} else {
|
||||
reactionInit(message);
|
||||
}
|
||||
|
@ -256,7 +264,7 @@ const MessageActions = React.memo(
|
|||
hideActionSheet();
|
||||
};
|
||||
|
||||
const handleReadReceipt = (message: any) => {
|
||||
const handleReadReceipt = (message: TAnyMessageModel) => {
|
||||
if (isMasterDetail) {
|
||||
Navigation.navigate('ModalStackNavigator', { screen: 'ReadReceiptsView', params: { messageId: message.id } });
|
||||
} else {
|
||||
|
@ -291,7 +299,7 @@ const MessageActions = React.memo(
|
|||
}
|
||||
};
|
||||
|
||||
const handleReport = async (message: any) => {
|
||||
const handleReport = async (message: TAnyMessageModel) => {
|
||||
logEvent(events.ROOM_MSG_ACTION_REPORT);
|
||||
try {
|
||||
await RocketChat.reportMessage(message.id);
|
||||
|
@ -302,14 +310,14 @@ const MessageActions = React.memo(
|
|||
}
|
||||
};
|
||||
|
||||
const handleDelete = (message: any) => {
|
||||
const handleDelete = (message: TAnyMessageModel) => {
|
||||
showConfirmationAlert({
|
||||
message: I18n.t('You_will_not_be_able_to_recover_this_message'),
|
||||
confirmationText: I18n.t('Delete'),
|
||||
onPress: async () => {
|
||||
try {
|
||||
logEvent(events.ROOM_MSG_ACTION_DELETE);
|
||||
await RocketChat.deleteMessage(message.id, message.subscription.id);
|
||||
await RocketChat.deleteMessage(message.id, message.subscription ? message.subscription.id : '');
|
||||
} catch (e) {
|
||||
logEvent(events.ROOM_MSG_ACTION_DELETE_F);
|
||||
log(e);
|
||||
|
@ -319,7 +327,7 @@ const MessageActions = React.memo(
|
|||
};
|
||||
|
||||
const getOptions = (message: TAnyMessageModel) => {
|
||||
let options: any = [];
|
||||
let options: TActionSheetOptionsItem[] = [];
|
||||
|
||||
// Reply
|
||||
if (!isReadOnly) {
|
||||
|
@ -463,16 +471,15 @@ const MessageActions = React.memo(
|
|||
}
|
||||
)
|
||||
);
|
||||
|
||||
const mapStateToProps = (state: any) => ({
|
||||
const mapStateToProps = (state: IApplicationState) => ({
|
||||
server: state.server.server,
|
||||
Message_AllowDeleting: state.settings.Message_AllowDeleting,
|
||||
Message_AllowDeleting_BlockDeleteInMinutes: state.settings.Message_AllowDeleting_BlockDeleteInMinutes,
|
||||
Message_AllowEditing: state.settings.Message_AllowEditing,
|
||||
Message_AllowEditing_BlockEditInMinutes: state.settings.Message_AllowEditing_BlockEditInMinutes,
|
||||
Message_AllowPinning: state.settings.Message_AllowPinning,
|
||||
Message_AllowStarring: state.settings.Message_AllowStarring,
|
||||
Message_Read_Receipt_Store_Users: state.settings.Message_Read_Receipt_Store_Users,
|
||||
Message_AllowDeleting: state.settings.Message_AllowDeleting as boolean,
|
||||
Message_AllowDeleting_BlockDeleteInMinutes: state.settings.Message_AllowDeleting_BlockDeleteInMinutes as number,
|
||||
Message_AllowEditing: state.settings.Message_AllowEditing as boolean,
|
||||
Message_AllowEditing_BlockEditInMinutes: state.settings.Message_AllowEditing_BlockEditInMinutes as number,
|
||||
Message_AllowPinning: state.settings.Message_AllowPinning as boolean,
|
||||
Message_AllowStarring: state.settings.Message_AllowStarring as boolean,
|
||||
Message_Read_Receipt_Store_Users: state.settings.Message_Read_Receipt_Store_Users as boolean,
|
||||
isMasterDetail: state.app.isMasterDetail,
|
||||
editMessagePermission: state.permissions['edit-message'],
|
||||
deleteMessagePermission: state.permissions['delete-message'],
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
// TODO: evaluate unification with IEmoji
|
||||
export interface IEmoji {
|
||||
content: any;
|
||||
name: string;
|
||||
extension: any;
|
||||
isCustom: boolean;
|
||||
content?: string;
|
||||
name?: string;
|
||||
extension?: string;
|
||||
isCustom?: boolean;
|
||||
}
|
||||
|
||||
export interface ICustomEmoji {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Model from '@nozbe/watermelondb/Model';
|
||||
|
||||
// TODO: evaluate unification with IEmoji
|
||||
export interface IFrequentlyUsedEmoji {
|
||||
content?: string;
|
||||
extension?: string;
|
||||
|
|
|
@ -7,7 +7,7 @@ import { TNavigationOptions } from './definitions/navigationTypes';
|
|||
export interface IDimensionsContextProps {
|
||||
width: number;
|
||||
height: number;
|
||||
scale?: number;
|
||||
scale: number;
|
||||
fontScale: number;
|
||||
setDimensions?: ({
|
||||
width,
|
||||
|
|
Loading…
Reference in New Issue