Rocket.Chat.ReactNative/app/views/ShareView/index.js

300 lines
7.6 KiB
JavaScript
Raw Normal View History

2019-07-18 17:44:02 +00:00
import React from 'react';
import PropTypes from 'prop-types';
2019-12-04 16:39:53 +00:00
import { View, Text, Image } from 'react-native';
2019-07-18 17:44:02 +00:00
import { connect } from 'react-redux';
import ShareExtension from 'rn-extensions-share';
2019-12-04 16:39:53 +00:00
import { themes } from '../../constants/colors';
2019-07-18 17:44:02 +00:00
import I18n from '../../i18n';
import RocketChat from '../../lib/rocketchat';
import { CustomIcon } from '../../lib/Icons';
import log from '../../utils/log';
import styles from './styles';
2019-12-04 16:39:53 +00:00
import TextInput from '../../containers/TextInput';
import ActivityIndicator from '../../containers/ActivityIndicator';
2019-07-18 17:44:02 +00:00
import { CustomHeaderButtons, Item } from '../../containers/HeaderButton';
import { isReadOnly, isBlocked } from '../../utils/room';
2019-12-04 16:39:53 +00:00
import { withTheme } from '../../theme';
import { themedHeader } from '../../utils/navigation';
2019-07-18 17:44:02 +00:00
class ShareView extends React.Component {
2019-12-04 16:39:53 +00:00
static navigationOptions = ({ navigation, screenProps }) => {
2019-07-29 16:33:28 +00:00
const canSend = navigation.getParam('canSend', true);
2019-07-18 17:44:02 +00:00
return ({
title: I18n.t('Share'),
2019-12-04 16:39:53 +00:00
...themedHeader(screenProps.theme),
2019-07-18 17:44:02 +00:00
headerRight:
canSend
? (
<CustomHeaderButtons>
<Item
title={I18n.t('Send')}
onPress={navigation.getParam('sendMessage')}
testID='send-message-share-view'
buttonStyle={styles.send}
/>
</CustomHeaderButtons>
)
: null
});
}
static propTypes = {
navigation: PropTypes.object,
2019-12-04 16:39:53 +00:00
theme: PropTypes.string,
2019-07-29 16:33:28 +00:00
user: PropTypes.shape({
id: PropTypes.string.isRequired,
username: PropTypes.string.isRequired,
token: PropTypes.string.isRequired
}),
baseUrl: PropTypes.string.isRequired
2019-07-18 17:44:02 +00:00
};
constructor(props) {
super(props);
const { navigation } = this.props;
const rid = navigation.getParam('rid', '');
const name = navigation.getParam('name', '');
const value = navigation.getParam('value', '');
const isMedia = navigation.getParam('isMedia', false);
const fileInfo = navigation.getParam('fileInfo', {});
[CHORE] Migrate to Watermelon (#1171) * Install * Create subscriptions * Subscription observing and sorting * Saving last message * Stash * Stash * stash * Stash * Rooms list listing :) * Animated set state * Search working * Fix load rooms on login * stash db class * set active db with path * Remove db on logout * stash * Created updateMessages * Inserting/updating threads * Persisting thread messages * Removed unused list * Loading messages from watermelon * Debounce updates and rerender message * optional fields * Fix realm conflict issues * Fix some render issues * stash * List mount * stash * fix message id * Fix tmsg * - Save subscription.rid as id on watermelon and _id as _id - Send room as param to room view * Throttle room updates * stash * comment removeClippedSubviews * Fetch thread name * try/catch updateMessages * Show loading while RoomView.init is still running * stash * Fix updateMessages * Threads * Delete message * Permalink * Pin * Star * Report * MessageActions refactor * Edit message * Reply message * Add reaction * Auto translate * Fix connection issues * Mark message as error if something happened on the call * Error actions * get custom emoji * Always run console.log when __DEV__ * Try to create serversDB * Don't call updateMessages. Execute that entire logic for one message id instead. * Refactor update messages * ServersDB User [Realm -> Watermelon] * Fix models * Custom emojis * Custom emojis on emoji picker * Frequently used emojis * Fix add reaction on message * stash * Fix * Read messages * Fix thread * Fetch thread header * Follow/unfollow thread * Fix thread * Upload file * Thread tweak * Realm -> Watermelon [Share Extension] * Add RoomsUpdatedAt to Servers Table * Settings * Settings * Fix logout * SendFileMessage ServersDB * ServersDB on serverDropdown * Remove serversDB from Realm * Load thread messages * Delete message * Improve getSettings * Improve * Remove subscription * Remove update * Update room via socket * Small refactor * Fix logout and improve migration * Refactor updateMessages * Improve migration * Remove unnecessary update * Revert remove runAfterInteractions * Fix serverDropdown * Fix merge * Init room actions Watermelon * Room actions Watermelon * Remove realm on room members * Room swipe -> Watermelon * Fix hideChannel * Get roles watermelon * Get permissions watermelon * Users typing + memory db * Auto translate watermelon * New Message View * Selected Users View * try/catch * Get Slash Commands watermelon * Slash Commands message box * Custom emojis message box * Get rooms message box * Room info view * Room info edit * Save active users * Small refactor * Message Actions * hasPermission await * last hasPermission fix * Active users on redux * Add user roles * Users typing on redux and remove memory db * Fix saga delay * Fix few issues * Fix slash commands preview * Draft message * Add muted * Unread count watermelon * Remove realm * Fiz RoomItem rerenders * Remove realm config * Rerender status update on RoomItem * Refactor RoomsListView * Fix load missed messages * Fix room update * Message refactor * Fixing lint * removeClippedSubviews on iOS only * Added few interaction managers * Fix few rerenders * Fix RoomItem status typo * Fix RoomView.SCU * Fix broadcast * Fix user status on RoomActionsView * Fix RocketChat.hasPermission * Fix database inconsistencies * Fix few update issues * Add rxjs and remove with observables * Fix tests * Remove subscriptions * Fix RoomsListView SCU * Change database structure and set all schemas to 1 * Fix RoomsListView search * Fixed errors, removed rerenders and added animation * Fixed a few errors * Fix lint * Fix issues caught by LGTM * fix ios build * Fix load unjoined channel messages * Log on database path on startup * Fix join channel * Remove react-native-realm-path * Set user status on login.user reducer * Fix status not rendering on RoomsListView * Fix few reducers * Fix users going offline * Never use "watermelon" term directly. Replaced by "database" * Fix custom emoji * Creating room from app must update roomUpdatedAt * Log subscribeRoom start * Fix room subscribe right after creating a DM * Refactor is read only on messages actions * Fix typo * Fix typo * Review * Fix schema * Fix muted & freq emoji & unpin & unstar * Remove throttleTime to room info & fix reset on edit room * Fix openServerDropdown spec & Fix unarchive * Fix MessageAction * Refactor RoomInfoEditView * Remove unnecessary condition * Remove unnecessary condition * Remove unnecessary condition * Remove get database * Rename Command.js to SlashCommand.js * Create sanitizer util * Fix indentation * Create subscription.t index * Refactor queries on RoomsListView * Create subscription.name index * Fix getPermissions * Fix indentation * Add missing await * Fix rocketchat.hasPermission * Unnecessary change * Star, pin e delete message refactored * Refactor customEmojis reducer * Remove code * Remove logs * Remove throttle * Call this.init on foreground focus on RoomView * Bump servers schema migration * Always mark message as sent after a success * Fetch only messages needed on updateMessages * Just leave a comment for now * Fetch only subscriptions returned by fetch * Set room param on RoomView header in find room * Update kotlin * Fix auto translate constructor * Fix few setState on constructor * Fix empty room image blinking while mounting * Improve fetch/persist execution for custom emojis, permissions and settings * Query only user tapped on RoomMembersView * Fix typo on canOpenRoom
2019-09-16 20:26:32 +00:00
const room = navigation.getParam('room', { rid });
2019-07-18 17:44:02 +00:00
this.state = {
rid,
value,
isMedia,
name,
fileInfo,
[CHORE] Migrate to Watermelon (#1171) * Install * Create subscriptions * Subscription observing and sorting * Saving last message * Stash * Stash * stash * Stash * Rooms list listing :) * Animated set state * Search working * Fix load rooms on login * stash db class * set active db with path * Remove db on logout * stash * Created updateMessages * Inserting/updating threads * Persisting thread messages * Removed unused list * Loading messages from watermelon * Debounce updates and rerender message * optional fields * Fix realm conflict issues * Fix some render issues * stash * List mount * stash * fix message id * Fix tmsg * - Save subscription.rid as id on watermelon and _id as _id - Send room as param to room view * Throttle room updates * stash * comment removeClippedSubviews * Fetch thread name * try/catch updateMessages * Show loading while RoomView.init is still running * stash * Fix updateMessages * Threads * Delete message * Permalink * Pin * Star * Report * MessageActions refactor * Edit message * Reply message * Add reaction * Auto translate * Fix connection issues * Mark message as error if something happened on the call * Error actions * get custom emoji * Always run console.log when __DEV__ * Try to create serversDB * Don't call updateMessages. Execute that entire logic for one message id instead. * Refactor update messages * ServersDB User [Realm -> Watermelon] * Fix models * Custom emojis * Custom emojis on emoji picker * Frequently used emojis * Fix add reaction on message * stash * Fix * Read messages * Fix thread * Fetch thread header * Follow/unfollow thread * Fix thread * Upload file * Thread tweak * Realm -> Watermelon [Share Extension] * Add RoomsUpdatedAt to Servers Table * Settings * Settings * Fix logout * SendFileMessage ServersDB * ServersDB on serverDropdown * Remove serversDB from Realm * Load thread messages * Delete message * Improve getSettings * Improve * Remove subscription * Remove update * Update room via socket * Small refactor * Fix logout and improve migration * Refactor updateMessages * Improve migration * Remove unnecessary update * Revert remove runAfterInteractions * Fix serverDropdown * Fix merge * Init room actions Watermelon * Room actions Watermelon * Remove realm on room members * Room swipe -> Watermelon * Fix hideChannel * Get roles watermelon * Get permissions watermelon * Users typing + memory db * Auto translate watermelon * New Message View * Selected Users View * try/catch * Get Slash Commands watermelon * Slash Commands message box * Custom emojis message box * Get rooms message box * Room info view * Room info edit * Save active users * Small refactor * Message Actions * hasPermission await * last hasPermission fix * Active users on redux * Add user roles * Users typing on redux and remove memory db * Fix saga delay * Fix few issues * Fix slash commands preview * Draft message * Add muted * Unread count watermelon * Remove realm * Fiz RoomItem rerenders * Remove realm config * Rerender status update on RoomItem * Refactor RoomsListView * Fix load missed messages * Fix room update * Message refactor * Fixing lint * removeClippedSubviews on iOS only * Added few interaction managers * Fix few rerenders * Fix RoomItem status typo * Fix RoomView.SCU * Fix broadcast * Fix user status on RoomActionsView * Fix RocketChat.hasPermission * Fix database inconsistencies * Fix few update issues * Add rxjs and remove with observables * Fix tests * Remove subscriptions * Fix RoomsListView SCU * Change database structure and set all schemas to 1 * Fix RoomsListView search * Fixed errors, removed rerenders and added animation * Fixed a few errors * Fix lint * Fix issues caught by LGTM * fix ios build * Fix load unjoined channel messages * Log on database path on startup * Fix join channel * Remove react-native-realm-path * Set user status on login.user reducer * Fix status not rendering on RoomsListView * Fix few reducers * Fix users going offline * Never use "watermelon" term directly. Replaced by "database" * Fix custom emoji * Creating room from app must update roomUpdatedAt * Log subscribeRoom start * Fix room subscribe right after creating a DM * Refactor is read only on messages actions * Fix typo * Fix typo * Review * Fix schema * Fix muted & freq emoji & unpin & unstar * Remove throttleTime to room info & fix reset on edit room * Fix openServerDropdown spec & Fix unarchive * Fix MessageAction * Refactor RoomInfoEditView * Remove unnecessary condition * Remove unnecessary condition * Remove unnecessary condition * Remove get database * Rename Command.js to SlashCommand.js * Create sanitizer util * Fix indentation * Create subscription.t index * Refactor queries on RoomsListView * Create subscription.name index * Fix getPermissions * Fix indentation * Add missing await * Fix rocketchat.hasPermission * Unnecessary change * Star, pin e delete message refactored * Refactor customEmojis reducer * Remove code * Remove logs * Remove throttle * Call this.init on foreground focus on RoomView * Bump servers schema migration * Always mark message as sent after a success * Fetch only messages needed on updateMessages * Just leave a comment for now * Fetch only subscriptions returned by fetch * Set room param on RoomView header in find room * Update kotlin * Fix auto translate constructor * Fix few setState on constructor * Fix empty room image blinking while mounting * Improve fetch/persist execution for custom emojis, permissions and settings * Query only user tapped on RoomMembersView * Fix typo on canOpenRoom
2019-09-16 20:26:32 +00:00
room,
2019-07-18 17:44:02 +00:00
loading: false,
file: {
name: fileInfo ? fileInfo.name : '',
description: ''
}
};
}
componentDidMount() {
const { room } = this.state;
2019-07-29 16:33:28 +00:00
const { navigation, user } = this.props;
const { username } = user;
2019-07-18 17:44:02 +00:00
navigation.setParams({ sendMessage: this._sendMessage, canSend: !(isReadOnly(room, { username }) || isBlocked(room)) });
}
2019-07-29 16:33:28 +00:00
bytesToSize = bytes => `${ (bytes / 1048576).toFixed(2) }MB`;
2019-07-18 17:44:02 +00:00
_sendMessage = async() => {
const { isMedia, loading } = this.state;
if (loading) {
return;
}
2019-07-18 17:44:02 +00:00
this.setState({ loading: true });
2019-07-18 17:44:02 +00:00
if (isMedia) {
await this.sendMediaMessage();
} else {
await this.sendTextMessage();
}
this.setState({ loading: false });
ShareExtension.close();
}
sendMediaMessage = async() => {
const { rid, fileInfo, file } = this.state;
2019-07-29 16:33:28 +00:00
const { baseUrl: server, user } = this.props;
2019-07-18 17:44:02 +00:00
const { name, description } = file;
2019-07-30 16:15:39 +00:00
const fileMessage = {
name,
description,
size: fileInfo.size,
type: fileInfo.mime,
store: 'Uploads',
path: fileInfo.path
};
2019-07-18 17:44:02 +00:00
if (fileInfo && rid !== '') {
try {
2019-07-29 16:33:28 +00:00
await RocketChat.sendFileMessage(rid, fileMessage, undefined, server, user);
2019-07-18 17:44:02 +00:00
} catch (e) {
log(e);
2019-07-18 17:44:02 +00:00
}
}
}
sendTextMessage = async() => {
const { value, rid } = this.state;
2019-07-29 16:33:28 +00:00
const { user } = this.props;
2019-07-18 17:44:02 +00:00
if (value !== '' && rid !== '') {
try {
2019-07-29 16:33:28 +00:00
await RocketChat.sendMessage(rid, value, undefined, user);
} catch (e) {
log(e);
2019-07-18 17:44:02 +00:00
}
}
};
renderPreview = () => {
const { fileInfo } = this.state;
2019-12-04 16:39:53 +00:00
const { theme } = this.props;
2019-07-18 17:44:02 +00:00
const icon = fileInfo.mime.match(/image/)
2019-07-18 17:44:02 +00:00
? <Image source={{ isStatic: true, uri: fileInfo.path }} style={styles.mediaImage} />
: (
<View style={styles.mediaIconContainer}>
<CustomIcon name='file-generic' style={styles.mediaIcon} />
</View>
);
return (
2019-12-04 16:39:53 +00:00
<View
style={[
styles.mediaContent,
{
borderColor: themes[theme].separatorColor,
backgroundColor: themes[theme].auxiliaryBackground
}
]}
>
2019-07-18 17:44:02 +00:00
{icon}
<View style={styles.mediaInfo}>
2019-12-04 16:39:53 +00:00
<Text style={[styles.mediaText, { color: themes[theme].titleText }]} numberOfLines={1}>{fileInfo.name}</Text>
<Text style={[styles.mediaText, { color: themes[theme].titleText }]}>{this.bytesToSize(fileInfo.size)}</Text>
2019-07-18 17:44:02 +00:00
</View>
</View>
);
};
renderMediaContent = () => {
const { fileInfo, file } = this.state;
2019-12-04 16:39:53 +00:00
const { theme } = this.props;
const inputStyle = {
backgroundColor: themes[theme].focusedBackground,
borderColor: themes[theme].separatorColor
};
2019-07-18 17:44:02 +00:00
return fileInfo ? (
<View style={styles.mediaContainer}>
{this.renderPreview()}
<View style={styles.mediaInputContent}>
<TextInput
2019-12-04 16:39:53 +00:00
inputStyle={[
styles.mediaNameInput,
styles.input,
styles.firstInput,
inputStyle
]}
2019-07-18 17:44:02 +00:00
placeholder={I18n.t('File_name')}
onChangeText={name => this.setState({ file: { ...file, name } })}
defaultValue={file.name}
2019-12-04 16:39:53 +00:00
containerStyle={styles.inputContainer}
theme={theme}
2019-07-18 17:44:02 +00:00
/>
<TextInput
2019-12-04 16:39:53 +00:00
inputStyle={[
styles.mediaDescriptionInput,
styles.input,
inputStyle
]}
2019-07-18 17:44:02 +00:00
placeholder={I18n.t('File_description')}
onChangeText={description => this.setState({ file: { ...file, description } })}
defaultValue={file.description}
multiline
textAlignVertical='top'
autoFocus
2019-12-04 16:39:53 +00:00
containerStyle={styles.inputContainer}
theme={theme}
2019-07-18 17:44:02 +00:00
/>
</View>
</View>
) : null;
};
renderInput = () => {
const { value } = this.state;
2019-12-04 16:39:53 +00:00
const { theme } = this.props;
2019-07-18 17:44:02 +00:00
return (
<TextInput
2019-12-04 16:39:53 +00:00
containerStyle={[styles.content, styles.inputContainer]}
inputStyle={[
styles.input,
styles.textInput,
{
borderColor: themes[theme].separatorColor,
backgroundColor: themes[theme].focusedBackground
}
]}
2019-07-18 17:44:02 +00:00
placeholder=''
onChangeText={handleText => this.setState({ value: handleText })}
defaultValue={value}
multiline
textAlignVertical='top'
autoFocus
2019-12-04 16:39:53 +00:00
theme={theme}
2019-07-18 17:44:02 +00:00
/>
);
}
renderError = () => {
const { room } = this.state;
return (
<View style={[styles.container, styles.centered]}>
<Text style={styles.title}>
{
isBlocked(room) ? I18n.t('This_room_is_blocked') : I18n.t('This_room_is_read_only')
}
</Text>
</View>
);
}
render() {
2019-12-04 16:39:53 +00:00
const { user, theme } = this.props;
2019-07-29 16:33:28 +00:00
const { username } = user;
2019-07-18 17:44:02 +00:00
const {
name, loading, isMedia, room
} = this.state;
if (isReadOnly(room, { username }) || isBlocked(room)) {
return this.renderError();
}
return (
2019-12-04 16:39:53 +00:00
<View style={[styles.container, { backgroundColor: themes[theme].auxiliaryBackground }]}>
<View
style={[
isMedia
? styles.toContent
: styles.toContentText,
{
backgroundColor: isMedia
? themes[theme].focusedBackground
: themes[theme].auxiliaryBackground
}
]}
>
2019-07-18 17:44:02 +00:00
<Text style={styles.text} numberOfLines={1}>
2019-12-04 16:39:53 +00:00
<Text style={[styles.to, { color: themes[theme].auxiliaryText }]}>{`${ I18n.t('To') }: `}</Text>
<Text style={[styles.name, { color: themes[theme].titleText }]}>{`${ name }`}</Text>
2019-07-18 17:44:02 +00:00
</Text>
</View>
2019-12-04 16:39:53 +00:00
<View style={[styles.content, { backgroundColor: themes[theme].auxiliaryBackground }]}>
2019-07-18 17:44:02 +00:00
{isMedia ? this.renderMediaContent() : this.renderInput()}
</View>
2019-12-04 16:39:53 +00:00
{ loading ? <ActivityIndicator size='large' theme={theme} absolute /> : null }
</View>
2019-07-18 17:44:02 +00:00
);
}
}
const mapStateToProps = (({ share }) => ({
user: {
id: share.user && share.user.id,
username: share.user && share.user.username,
token: share.user && share.user.token
},
baseUrl: share ? share.server : ''
}));
2019-12-04 16:39:53 +00:00
export default connect(mapStateToProps)(withTheme(ShareView));