Share extension
This commit is contained in:
parent
009de40200
commit
ffda9e528f
|
@ -30,6 +30,9 @@ import { KEY_COMMAND } from './commands';
|
||||||
import Tablet, { initTabletNav } from './tablet';
|
import Tablet, { initTabletNav } from './tablet';
|
||||||
import { SplitContext } from './split';
|
import { SplitContext } from './split';
|
||||||
import AppContainer from './AppContainer';
|
import AppContainer from './AppContainer';
|
||||||
|
import TwoFactor from './containers/TwoFactor';
|
||||||
|
import ScreenLockedView from './views/ScreenLockedView';
|
||||||
|
import ChangePasscodeView from './views/ChangePasscodeView';
|
||||||
|
|
||||||
RNScreens.enableScreens();
|
RNScreens.enableScreens();
|
||||||
|
|
||||||
|
@ -188,6 +191,9 @@ export default class Root extends React.Component {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{content}
|
{content}
|
||||||
|
<TwoFactor />
|
||||||
|
<ScreenLockedView />
|
||||||
|
<ChangePasscodeView />
|
||||||
</ThemeContext.Provider>
|
</ThemeContext.Provider>
|
||||||
</Provider>
|
</Provider>
|
||||||
</AppearanceProvider>
|
</AppearanceProvider>
|
||||||
|
|
|
@ -1,21 +1,12 @@
|
||||||
import { NavigationActions } from '@react-navigation/native';
|
import * as React from 'react';
|
||||||
|
|
||||||
let _shareNavigator;
|
const navigationRef = React.createRef();
|
||||||
|
|
||||||
function setTopLevelNavigator(navigatorRef) {
|
function navigate(name, params) {
|
||||||
_shareNavigator = navigatorRef;
|
navigationRef.current?.navigate(name, params);
|
||||||
}
|
|
||||||
|
|
||||||
function navigate(routeName, params) {
|
|
||||||
_shareNavigator.dispatch(
|
|
||||||
NavigationActions.navigate({
|
|
||||||
routeName,
|
|
||||||
params
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
navigate,
|
navigationRef,
|
||||||
setTopLevelNavigator
|
navigate
|
||||||
};
|
};
|
||||||
|
|
106
app/share.js
106
app/share.js
|
@ -1,5 +1,6 @@
|
||||||
import React, { useState, useContext } from 'react';
|
import React, { useState, useContext } from 'react';
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
import { NavigationContainer } from '@react-navigation/native';
|
import { NavigationContainer } from '@react-navigation/native';
|
||||||
import { AppearanceProvider } from 'react-native-appearance';
|
import { AppearanceProvider } from 'react-native-appearance';
|
||||||
import { createStackNavigator } from '@react-navigation/stack';
|
import { createStackNavigator } from '@react-navigation/stack';
|
||||||
|
@ -14,14 +15,12 @@ import {
|
||||||
} from './utils/theme';
|
} from './utils/theme';
|
||||||
import Navigation from './lib/ShareNavigation';
|
import Navigation from './lib/ShareNavigation';
|
||||||
import store from './lib/createStore';
|
import store from './lib/createStore';
|
||||||
import sharedStyles from './views/Styles';
|
import { isIOS, supportSystemTheme } from './utils/deviceInfo';
|
||||||
import { isNotch, isIOS, supportSystemTheme } from './utils/deviceInfo';
|
|
||||||
import { defaultHeader, onNavigationStateChange, themedHeader } from './utils/navigation';
|
import { defaultHeader, onNavigationStateChange, themedHeader } from './utils/navigation';
|
||||||
import RocketChat, { THEME_PREFERENCES_KEY } from './lib/rocketchat';
|
import RocketChat, { THEME_PREFERENCES_KEY } from './lib/rocketchat';
|
||||||
import { ThemeContext } from './theme';
|
import { ThemeContext } from './theme';
|
||||||
|
|
||||||
// Outside Stack
|
// Outside Stack
|
||||||
import AuthLoadingView from './views/AuthLoadingView';
|
|
||||||
import WithoutServersView from './views/WithoutServersView';
|
import WithoutServersView from './views/WithoutServersView';
|
||||||
|
|
||||||
// Inside Stack
|
// Inside Stack
|
||||||
|
@ -33,17 +32,25 @@ const Inside = createStackNavigator();
|
||||||
const InsideStack = () => {
|
const InsideStack = () => {
|
||||||
const { theme } = useContext(ThemeContext);
|
const { theme } = useContext(ThemeContext);
|
||||||
|
|
||||||
|
const screenOptions = {
|
||||||
|
...defaultHeader,
|
||||||
|
...themedHeader(theme)
|
||||||
|
};
|
||||||
|
screenOptions.headerStyle = {
|
||||||
|
...screenOptions.headerStyle,
|
||||||
|
// TODO: fix on multiple files PR :)
|
||||||
|
height: 57
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Inside.Navigator screenOptions={{ ...defaultHeader, ...themedHeader(theme) }}>
|
<Inside.Navigator screenOptions={screenOptions}>
|
||||||
<Inside.Screen
|
<Inside.Screen
|
||||||
name='ShareListView'
|
name='ShareListView'
|
||||||
component={ShareListView}
|
component={ShareListView}
|
||||||
options={props => ShareListView.navigationOptions({ ...props, theme })}
|
|
||||||
/>
|
/>
|
||||||
<Inside.Screen
|
<Inside.Screen
|
||||||
name='ShareView'
|
name='ShareView'
|
||||||
component={ShareView}
|
component={ShareView}
|
||||||
options={ShareView.navigationOptions}
|
|
||||||
/>
|
/>
|
||||||
<Inside.Screen
|
<Inside.Screen
|
||||||
name='SelectServerView'
|
name='SelectServerView'
|
||||||
|
@ -69,48 +76,47 @@ const OutsideStack = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const AuthContext = React.createContext();
|
|
||||||
|
|
||||||
// App
|
// App
|
||||||
const Stack = createStackNavigator();
|
const Stack = createStackNavigator();
|
||||||
export const App = () => {
|
export const App = ({ root }) => {
|
||||||
const [loading] = useState(false);
|
if (!root) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AuthContext.Provider value={{}}>
|
<Stack.Navigator screenOptions={{ headerShown: false }}>
|
||||||
<Stack.Navigator screenOptions={{ headerShown: false }}>
|
<>
|
||||||
{loading ? (
|
{root === 'outside' ? (
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
name='AuthLoading'
|
name='OutsideStack'
|
||||||
component={AuthLoadingView}
|
component={OutsideStack}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : null}
|
||||||
<>
|
{root === 'inside' ? (
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
name='OutsideStack'
|
name='InsideStack'
|
||||||
component={OutsideStack}
|
component={InsideStack}
|
||||||
/>
|
/>
|
||||||
<Stack.Screen
|
) : null}
|
||||||
name='InsideStack'
|
</>
|
||||||
component={InsideStack}
|
</Stack.Navigator>
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Stack.Navigator>
|
|
||||||
</AuthContext.Provider>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
App.propTypes = {
|
||||||
|
root: PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
class Root extends React.Component {
|
class Root extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
isLandscape: false,
|
|
||||||
theme: defaultTheme(),
|
theme: defaultTheme(),
|
||||||
themePreferences: {
|
themePreferences: {
|
||||||
currentTheme: supportSystemTheme() ? 'automatic' : 'light',
|
currentTheme: supportSystemTheme() ? 'automatic' : 'light',
|
||||||
darkLevel: 'dark'
|
darkLevel: 'dark'
|
||||||
}
|
},
|
||||||
|
root: ''
|
||||||
};
|
};
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
@ -129,10 +135,10 @@ class Root extends React.Component {
|
||||||
const token = await RNUserDefaults.get(RocketChat.TOKEN_KEY);
|
const token = await RNUserDefaults.get(RocketChat.TOKEN_KEY);
|
||||||
|
|
||||||
if (currentServer && token) {
|
if (currentServer && token) {
|
||||||
await Navigation.navigate('InsideStack');
|
this.setState({ root: 'inside' });
|
||||||
await RocketChat.shareExtensionInit(currentServer);
|
await RocketChat.shareExtensionInit(currentServer);
|
||||||
} else {
|
} else {
|
||||||
await Navigation.navigate('OutsideStack');
|
this.setState({ root: 'outside' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,32 +151,20 @@ class Root extends React.Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleLayout = (event) => {
|
|
||||||
const { width, height } = event.nativeEvent.layout;
|
|
||||||
this.setState({ isLandscape: width > height });
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isLandscape, theme } = this.state;
|
const { theme, root } = this.state;
|
||||||
return (
|
return (
|
||||||
<AppearanceProvider>
|
<AppearanceProvider>
|
||||||
<View
|
<Provider store={store}>
|
||||||
style={[sharedStyles.container, isLandscape && isNotch ? sharedStyles.notchLandscapeContainer : {}]}
|
<ThemeContext.Provider value={{ theme }}>
|
||||||
onLayout={this.handleLayout}
|
<NavigationContainer
|
||||||
>
|
ref={Navigation.navigationRef}
|
||||||
<Provider store={store}>
|
onNavigationStateChange={onNavigationStateChange}
|
||||||
<ThemeContext.Provider value={{ theme }}>
|
>
|
||||||
<NavigationContainer
|
<App root={root} />
|
||||||
ref={(navigatorRef) => {
|
</NavigationContainer>
|
||||||
Navigation.setTopLevelNavigator(navigatorRef);
|
</ThemeContext.Provider>
|
||||||
}}
|
</Provider>
|
||||||
onNavigationStateChange={onNavigationStateChange}
|
|
||||||
>
|
|
||||||
<App />
|
|
||||||
</NavigationContainer>
|
|
||||||
</ThemeContext.Provider>
|
|
||||||
</Provider>
|
|
||||||
</View>
|
|
||||||
</AppearanceProvider>
|
</AppearanceProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { TransitionPresets } from '@react-navigation/stack';
|
||||||
|
|
||||||
import { analytics, leaveBreadcrumb } from './log';
|
import { analytics, leaveBreadcrumb } from './log';
|
||||||
import { themes } from '../constants/colors';
|
import { themes } from '../constants/colors';
|
||||||
import { isIOS } from './deviceInfo';
|
|
||||||
|
|
||||||
export const defaultHeader = {
|
export const defaultHeader = {
|
||||||
headerBackTitleVisible: false,
|
headerBackTitleVisible: false,
|
||||||
|
|
|
@ -36,14 +36,14 @@ class SelectServerView extends React.Component {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
server: PropTypes.string,
|
server: PropTypes.string,
|
||||||
navigation: PropTypes.object,
|
route: PropTypes.object,
|
||||||
theme: PropTypes.string
|
theme: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
const { navigation } = this.props;
|
const { route } = this.props;
|
||||||
const servers = navigation.getParam('servers', []);
|
const servers = route.params?.servers ?? [];
|
||||||
const filteredServers = servers.filter(server => server.roomsUpdatedAt);
|
const filteredServers = servers.filter(server => server.roomsUpdatedAt);
|
||||||
this.state = {
|
this.state = {
|
||||||
servers: filteredServers
|
servers: filteredServers
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { Q } from '@nozbe/watermelondb';
|
||||||
|
|
||||||
import Navigation from '../../lib/ShareNavigation';
|
import Navigation from '../../lib/ShareNavigation';
|
||||||
import database from '../../lib/database';
|
import database from '../../lib/database';
|
||||||
import { isIOS, isAndroid } from '../../utils/deviceInfo';
|
import { isIOS } from '../../utils/deviceInfo';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import { CustomIcon } from '../../lib/Icons';
|
import { CustomIcon } from '../../lib/Icons';
|
||||||
import log from '../../utils/log';
|
import log from '../../utils/log';
|
||||||
|
@ -35,53 +35,6 @@ const getItemLayout = (data, index) => ({ length: ROW_HEIGHT, offset: ROW_HEIGHT
|
||||||
const keyExtractor = item => item.rid;
|
const keyExtractor = item => item.rid;
|
||||||
|
|
||||||
class ShareListView extends React.Component {
|
class ShareListView extends React.Component {
|
||||||
static navigationOptions = ({ route, theme }) => {
|
|
||||||
const searching = route.params?.searching;
|
|
||||||
const initSearch = route.params?.initSearch ?? (() => {});
|
|
||||||
const cancelSearch = route.params?.cancelSearch ?? (() => {});
|
|
||||||
const search = route.params?.search ?? (() => {});
|
|
||||||
|
|
||||||
if (isIOS) {
|
|
||||||
return {
|
|
||||||
headerStyle: { backgroundColor: themes[theme].headerBackground },
|
|
||||||
headerTitle: () => (
|
|
||||||
<ShareListHeader
|
|
||||||
searching={searching}
|
|
||||||
initSearch={initSearch}
|
|
||||||
cancelSearch={cancelSearch}
|
|
||||||
search={search}
|
|
||||||
theme={theme}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
headerLeft: () => (searching
|
|
||||||
? (
|
|
||||||
<CustomHeaderButtons left>
|
|
||||||
<Item title='cancel' iconName='cross' onPress={cancelSearch} />
|
|
||||||
</CustomHeaderButtons>
|
|
||||||
)
|
|
||||||
: (
|
|
||||||
<CancelModalButton
|
|
||||||
onPress={ShareExtension.close}
|
|
||||||
testID='share-extension-close'
|
|
||||||
/>
|
|
||||||
)),
|
|
||||||
headerTitle: () => <ShareListHeader searching={searching} search={search} theme={theme} />,
|
|
||||||
headerRight: () => (
|
|
||||||
searching
|
|
||||||
? null
|
|
||||||
: (
|
|
||||||
<CustomHeaderButtons>
|
|
||||||
{isAndroid ? <Item title='search' iconName='magnifier' onPress={initSearch} /> : null}
|
|
||||||
</CustomHeaderButtons>
|
|
||||||
)
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
navigation: PropTypes.object,
|
navigation: PropTypes.object,
|
||||||
server: PropTypes.string,
|
server: PropTypes.string,
|
||||||
|
@ -107,18 +60,13 @@ class ShareListView extends React.Component {
|
||||||
loading: true,
|
loading: true,
|
||||||
serverInfo: null
|
serverInfo: null
|
||||||
};
|
};
|
||||||
|
this.setHeader();
|
||||||
this.didFocusListener = props.navigation.addListener('didFocus', () => BackHandler.addEventListener('hardwareBackPress', this.handleBackPress));
|
this.didFocusListener = props.navigation.addListener('didFocus', () => BackHandler.addEventListener('hardwareBackPress', this.handleBackPress));
|
||||||
this.willBlurListener = props.navigation.addListener('willBlur', () => BackHandler.addEventListener('hardwareBackPress', this.handleBackPress));
|
this.willBlurListener = props.navigation.addListener('willBlur', () => BackHandler.addEventListener('hardwareBackPress', this.handleBackPress));
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { navigation, server } = this.props;
|
const { server } = this.props;
|
||||||
navigation.setParams({
|
|
||||||
initSearch: this.initSearch,
|
|
||||||
cancelSearch: this.cancelSearch,
|
|
||||||
search: this.search
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(async() => {
|
setTimeout(async() => {
|
||||||
try {
|
try {
|
||||||
const { value, type } = await ShareExtension.data();
|
const { value, type } = await ShareExtension.data();
|
||||||
|
@ -181,6 +129,51 @@ class ShareListView extends React.Component {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setHeader = () => {
|
||||||
|
const { searching } = this.state;
|
||||||
|
const { navigation, theme } = this.props;
|
||||||
|
|
||||||
|
if (isIOS) {
|
||||||
|
navigation.setOptions({
|
||||||
|
header: () => (
|
||||||
|
<ShareListHeader
|
||||||
|
searching={searching}
|
||||||
|
initSearch={this.initSearch}
|
||||||
|
cancelSearch={this.cancelSearch}
|
||||||
|
search={this.search}
|
||||||
|
theme={theme}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigation.setOptions({
|
||||||
|
headerLeft: () => (searching
|
||||||
|
? (
|
||||||
|
<CustomHeaderButtons left>
|
||||||
|
<Item title='cancel' iconName='cross' onPress={this.cancelSearch} />
|
||||||
|
</CustomHeaderButtons>
|
||||||
|
)
|
||||||
|
: (
|
||||||
|
<CancelModalButton
|
||||||
|
onPress={ShareExtension.close}
|
||||||
|
testID='share-extension-close'
|
||||||
|
/>
|
||||||
|
)),
|
||||||
|
headerTitle: () => <ShareListHeader searching={searching} search={this.search} theme={theme} />,
|
||||||
|
headerRight: () => (
|
||||||
|
searching
|
||||||
|
? null
|
||||||
|
: (
|
||||||
|
<CustomHeaderButtons>
|
||||||
|
<Item title='search' iconName='magnifier' onPress={this.initSearch} />
|
||||||
|
</CustomHeaderButtons>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line react/sort-comp
|
// eslint-disable-next-line react/sort-comp
|
||||||
internalSetState = (...args) => {
|
internalSetState = (...args) => {
|
||||||
const { navigation } = this.props;
|
const { navigation } = this.props;
|
||||||
|
@ -259,15 +252,11 @@ class ShareListView extends React.Component {
|
||||||
|
|
||||||
initSearch = () => {
|
initSearch = () => {
|
||||||
const { chats } = this.state;
|
const { chats } = this.state;
|
||||||
const { navigation } = this.props;
|
this.setState({ searching: true, searchResults: chats }, () => this.setHeader());
|
||||||
this.setState({ searching: true, searchResults: chats });
|
|
||||||
navigation.setParams({ searching: true });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelSearch = () => {
|
cancelSearch = () => {
|
||||||
const { navigation } = this.props;
|
this.internalSetState({ searching: false, searchResults: [], searchText: '' }, () => this.setHeader());
|
||||||
this.internalSetState({ searching: false, searchResults: [], searchText: '' });
|
|
||||||
navigation.setParams({ searching: false });
|
|
||||||
Keyboard.dismiss();
|
Keyboard.dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,29 +18,9 @@ import { isReadOnly } from '../../utils/isReadOnly';
|
||||||
import { withTheme } from '../../theme';
|
import { withTheme } from '../../theme';
|
||||||
|
|
||||||
class ShareView extends React.Component {
|
class ShareView extends React.Component {
|
||||||
static navigationOptions = ({ route }) => {
|
|
||||||
const canSend = route.params?.canSend ?? true;
|
|
||||||
|
|
||||||
return ({
|
|
||||||
title: I18n.t('Share'),
|
|
||||||
headerRight:
|
|
||||||
() => (canSend
|
|
||||||
? (
|
|
||||||
<CustomHeaderButtons>
|
|
||||||
<Item
|
|
||||||
title={I18n.t('Send')}
|
|
||||||
onPress={route.params?.sendMessage}
|
|
||||||
testID='send-message-share-view'
|
|
||||||
buttonStyle={styles.send}
|
|
||||||
/>
|
|
||||||
</CustomHeaderButtons>
|
|
||||||
)
|
|
||||||
: null)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
navigation: PropTypes.object,
|
navigation: PropTypes.object,
|
||||||
|
route: PropTypes.object,
|
||||||
theme: PropTypes.string,
|
theme: PropTypes.string,
|
||||||
user: PropTypes.shape({
|
user: PropTypes.shape({
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
|
@ -52,13 +32,13 @@ class ShareView extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
const { navigation } = this.props;
|
const { route } = this.props;
|
||||||
const rid = navigation.getParam('rid', '');
|
const rid = route.params?.rid;
|
||||||
const name = navigation.getParam('name', '');
|
const name = route.params?.name;
|
||||||
const value = navigation.getParam('value', '');
|
const value = route.params?.value;
|
||||||
const isMedia = navigation.getParam('isMedia', false);
|
const isMedia = route.params?.isMedia ?? false;
|
||||||
const fileInfo = navigation.getParam('fileInfo', {});
|
const fileInfo = route.params?.fileInfo ?? {};
|
||||||
const room = navigation.getParam('room', { rid });
|
const room = route.params?.room ?? { rid };
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
rid,
|
rid,
|
||||||
|
@ -72,30 +52,49 @@ class ShareView extends React.Component {
|
||||||
file: {
|
file: {
|
||||||
name: fileInfo ? fileInfo.name : '',
|
name: fileInfo ? fileInfo.name : '',
|
||||||
description: ''
|
description: ''
|
||||||
}
|
},
|
||||||
|
canSend: false
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setReadOnly();
|
this.setReadOnly();
|
||||||
|
this.setHeader();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
setHeader = () => {
|
||||||
|
const { canSend } = this.state;
|
||||||
const { navigation } = this.props;
|
const { navigation } = this.props;
|
||||||
navigation.setParams({ sendMessage: this._sendMessage });
|
|
||||||
|
navigation.setOptions({
|
||||||
|
title: I18n.t('Share'),
|
||||||
|
headerRight:
|
||||||
|
() => (canSend
|
||||||
|
? (
|
||||||
|
<CustomHeaderButtons>
|
||||||
|
<Item
|
||||||
|
title={I18n.t('Send')}
|
||||||
|
onPress={this.sendMessage}
|
||||||
|
testID='send-message-share-view'
|
||||||
|
buttonStyle={styles.send}
|
||||||
|
/>
|
||||||
|
</CustomHeaderButtons>
|
||||||
|
)
|
||||||
|
: null)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setReadOnly = async() => {
|
setReadOnly = async() => {
|
||||||
const { room } = this.state;
|
const { room } = this.state;
|
||||||
const { navigation, user } = this.props;
|
const { user } = this.props;
|
||||||
const { username } = user;
|
const { username } = user;
|
||||||
const readOnly = await isReadOnly(room, { username });
|
const readOnly = await isReadOnly(room, { username });
|
||||||
|
|
||||||
this.setState({ readOnly });
|
this.setState({ readOnly, canSend: !(readOnly || isBlocked(room)) });
|
||||||
navigation.setParams({ canSend: !(readOnly || isBlocked(room)) });
|
this.setHeader();
|
||||||
}
|
}
|
||||||
|
|
||||||
bytesToSize = bytes => `${ (bytes / 1048576).toFixed(2) }MB`;
|
bytesToSize = bytes => `${ (bytes / 1048576).toFixed(2) }MB`;
|
||||||
|
|
||||||
_sendMessage = async() => {
|
sendMessage = async() => {
|
||||||
const { isMedia, loading } = this.state;
|
const { isMedia, loading } = this.state;
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -31,6 +31,7 @@ const styles = StyleSheet.create({
|
||||||
|
|
||||||
class WithoutServerView extends React.Component {
|
class WithoutServerView extends React.Component {
|
||||||
static navigationOptions = {
|
static navigationOptions = {
|
||||||
|
title: 'Rocket.Chat',
|
||||||
headerLeft: () => (
|
headerLeft: () => (
|
||||||
<CancelModalButton
|
<CancelModalButton
|
||||||
onPress={ShareExtension.close}
|
onPress={ShareExtension.close}
|
||||||
|
|
2
index.js
2
index.js
|
@ -18,7 +18,7 @@ if (__DEV__) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AppRegistry.registerComponent(appName, () => require('./app/index.js').default);
|
AppRegistry.registerComponent(appName, () => require('./app/index.js').default);
|
||||||
// AppRegistry.registerComponent(shareName, () => require('./app/share.js').default);
|
AppRegistry.registerComponent(shareName, () => require('./app/share.js').default);
|
||||||
|
|
||||||
// For storybook, comment everything above and uncomment below
|
// For storybook, comment everything above and uncomment below
|
||||||
// import './storybook';
|
// import './storybook';
|
||||||
|
|
Loading…
Reference in New Issue