Compare commits
18 Commits
Author | SHA1 | Date |
---|---|---|
|
8142851fde | |
|
0ecfe0f780 | |
|
b9a3828781 | |
|
fd3f0a3417 | |
|
fa2c93fa2b | |
|
118b1352c4 | |
|
3d987cc988 | |
|
766dd8f5e4 | |
|
be718db8a5 | |
|
3be67f5a4f | |
|
77917f66f0 | |
|
7d2f4afaae | |
|
5cf9291fc9 | |
|
db0520ed7b | |
|
0583de7158 | |
|
33edacf087 | |
|
c3a80b6f1e | |
|
f15c755e03 |
|
@ -139,7 +139,7 @@ android {
|
|||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode VERSIONCODE as Integer
|
||||
versionName "4.8.0"
|
||||
versionName "4.8.1"
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String]
|
||||
missingDimensionStrategy "RNNotifications.reactNativeVersion", "reactNative60" // See note below!
|
||||
|
|
|
@ -29,7 +29,8 @@ export default StyleSheet.create({
|
|||
},
|
||||
handle: {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
alignItems: 'center',
|
||||
paddingBottom: 8
|
||||
},
|
||||
handleIndicator: {
|
||||
width: 40,
|
||||
|
|
|
@ -14,17 +14,20 @@ import { Button } from '../ActionSheet';
|
|||
import { useDimensions } from '../../dimensions';
|
||||
|
||||
export const HEADER_HEIGHT = 36;
|
||||
const ITEM_SIZE = 36;
|
||||
const CONTAINER_MARGIN = 8;
|
||||
const ITEM_MARGIN = 8;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
alignItems: 'center',
|
||||
marginHorizontal: 8
|
||||
marginHorizontal: CONTAINER_MARGIN
|
||||
},
|
||||
headerItem: {
|
||||
height: 36,
|
||||
width: 36,
|
||||
borderRadius: 20,
|
||||
marginHorizontal: 8,
|
||||
height: ITEM_SIZE,
|
||||
width: ITEM_SIZE,
|
||||
borderRadius: ITEM_SIZE / 2,
|
||||
marginHorizontal: ITEM_MARGIN,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
|
@ -84,7 +87,7 @@ HeaderFooter.propTypes = {
|
|||
};
|
||||
|
||||
const Header = React.memo(({
|
||||
handleReaction, server, message, theme
|
||||
handleReaction, server, message, isMasterDetail, theme
|
||||
}) => {
|
||||
const [items, setItems] = useState([]);
|
||||
const { width, height } = useDimensions();
|
||||
|
@ -96,8 +99,8 @@ const Header = React.memo(({
|
|||
let freqEmojis = await freqEmojiCollection.query().fetch();
|
||||
|
||||
const isLandscape = width > height;
|
||||
const size = isLandscape ? width / 2 : width;
|
||||
const quantity = (size / 50) - 1;
|
||||
const size = (isLandscape || isMasterDetail ? width / 2 : width) - (CONTAINER_MARGIN * 2);
|
||||
const quantity = (size / (ITEM_SIZE + (ITEM_MARGIN * 2))) - 1;
|
||||
|
||||
freqEmojis = freqEmojis.concat(DEFAULT_EMOJIS).slice(0, quantity);
|
||||
setItems(freqEmojis);
|
||||
|
@ -135,6 +138,7 @@ Header.propTypes = {
|
|||
handleReaction: PropTypes.func,
|
||||
server: PropTypes.string,
|
||||
message: PropTypes.object,
|
||||
isMasterDetail: PropTypes.bool,
|
||||
theme: PropTypes.string
|
||||
};
|
||||
export default withTheme(Header);
|
||||
|
|
|
@ -32,7 +32,8 @@ const MessageActions = React.memo(forwardRef(({
|
|||
Message_AllowEditing_BlockEditInMinutes,
|
||||
Message_AllowPinning,
|
||||
Message_AllowStarring,
|
||||
Message_Read_Receipt_Store_Users
|
||||
Message_Read_Receipt_Store_Users,
|
||||
isMasterDetail
|
||||
}, ref) => {
|
||||
let permissions = {};
|
||||
const { showActionSheet, hideActionSheet } = useActionSheet();
|
||||
|
@ -116,7 +117,12 @@ const MessageActions = React.memo(forwardRef(({
|
|||
const handleEdit = message => editInit(message);
|
||||
|
||||
const handleCreateDiscussion = (message) => {
|
||||
Navigation.navigate('CreateDiscussionView', { message, channel: room });
|
||||
const params = { message, channel: room, showCloseModal: true };
|
||||
if (isMasterDetail) {
|
||||
Navigation.navigate('ModalStackNavigator', { screen: 'CreateDiscussionView', params });
|
||||
} else {
|
||||
Navigation.navigate('NewMessageStackNavigator', { screen: 'CreateDiscussionView', params });
|
||||
}
|
||||
};
|
||||
|
||||
const handleUnread = async(message) => {
|
||||
|
@ -377,6 +383,7 @@ const MessageActions = React.memo(forwardRef(({
|
|||
<Header
|
||||
server={server}
|
||||
handleReaction={handleReaction}
|
||||
isMasterDetail={isMasterDetail}
|
||||
message={message}
|
||||
/>
|
||||
) : null)
|
||||
|
@ -412,7 +419,8 @@ const mapStateToProps = state => ({
|
|||
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_Read_Receipt_Store_Users: state.settings.Message_Read_Receipt_Store_Users,
|
||||
isMasterDetail: state.app.isMasterDetail
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, null, null, { forwardRef: true })(MessageActions);
|
||||
|
|
|
@ -17,7 +17,7 @@ export default class EmojiKeyboard extends React.PureComponent {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
const state = store.getState();
|
||||
this.baseUrl = state.server.server;
|
||||
this.baseUrl = state.share.server || state.server.server;
|
||||
}
|
||||
|
||||
onEmojiSelected = (emoji) => {
|
||||
|
|
|
@ -541,12 +541,14 @@ class MessageBox extends Component {
|
|||
setCommandPreview = async(command, name, params) => {
|
||||
const { rid } = this.props;
|
||||
try {
|
||||
const { preview } = await RocketChat.getCommandPreview(name, rid, params);
|
||||
this.setState({ commandPreview: preview.items, showCommandPreview: true, command });
|
||||
const { success, preview } = await RocketChat.getCommandPreview(name, rid, params);
|
||||
if (success) {
|
||||
return this.setState({ commandPreview: preview?.items, showCommandPreview: true, command });
|
||||
}
|
||||
} catch (e) {
|
||||
this.setState({ commandPreview: [], showCommandPreview: true, command: {} });
|
||||
log(e);
|
||||
}
|
||||
this.setState({ commandPreview: [], showCommandPreview: true, command: {} });
|
||||
}
|
||||
|
||||
setInput = (text) => {
|
||||
|
|
|
@ -110,7 +110,9 @@ class DB {
|
|||
Thread,
|
||||
ThreadMessage,
|
||||
Upload,
|
||||
Permission
|
||||
Permission,
|
||||
CustomEmoji,
|
||||
FrequentlyUsedEmoji
|
||||
],
|
||||
actionsEnabled: true
|
||||
});
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { InteractionManager } from 'react-native';
|
||||
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
||||
import { Q } from '@nozbe/watermelondb';
|
||||
|
||||
|
@ -132,48 +131,47 @@ export default async function() {
|
|||
const filteredSettingsIds = filteredSettings.map(s => s._id);
|
||||
|
||||
reduxStore.dispatch(addSettings(this.parseSettings(filteredSettings)));
|
||||
InteractionManager.runAfterInteractions(async() => {
|
||||
// filter server info
|
||||
const serverInfo = filteredSettings.filter(i1 => serverInfoKeys.includes(i1._id));
|
||||
const iconSetting = data.find(item => item._id === 'Assets_favicon_512');
|
||||
await serverInfoUpdate(serverInfo, iconSetting);
|
||||
|
||||
await db.action(async() => {
|
||||
const settingsCollection = db.collections.get('settings');
|
||||
const allSettingsRecords = await settingsCollection
|
||||
.query(Q.where('id', Q.oneOf(filteredSettingsIds)))
|
||||
.fetch();
|
||||
// filter server info
|
||||
const serverInfo = filteredSettings.filter(i1 => serverInfoKeys.includes(i1._id));
|
||||
const iconSetting = data.find(item => item._id === 'Assets_favicon_512');
|
||||
await serverInfoUpdate(serverInfo, iconSetting);
|
||||
|
||||
// filter settings
|
||||
let settingsToCreate = filteredSettings.filter(i1 => !allSettingsRecords.find(i2 => i1._id === i2.id));
|
||||
let settingsToUpdate = allSettingsRecords.filter(i1 => filteredSettings.find(i2 => i1.id === i2._id));
|
||||
await db.action(async() => {
|
||||
const settingsCollection = db.collections.get('settings');
|
||||
const allSettingsRecords = await settingsCollection
|
||||
.query(Q.where('id', Q.oneOf(filteredSettingsIds)))
|
||||
.fetch();
|
||||
|
||||
// Create
|
||||
settingsToCreate = settingsToCreate.map(setting => settingsCollection.prepareCreate(protectedFunction((s) => {
|
||||
s._raw = sanitizedRaw({ id: setting._id }, settingsCollection.schema);
|
||||
Object.assign(s, setting);
|
||||
})));
|
||||
// filter settings
|
||||
let settingsToCreate = filteredSettings.filter(i1 => !allSettingsRecords.find(i2 => i1._id === i2.id));
|
||||
let settingsToUpdate = allSettingsRecords.filter(i1 => filteredSettings.find(i2 => i1.id === i2._id));
|
||||
|
||||
// Update
|
||||
settingsToUpdate = settingsToUpdate.map((setting) => {
|
||||
const newSetting = filteredSettings.find(s => s._id === setting.id);
|
||||
return setting.prepareUpdate(protectedFunction((s) => {
|
||||
Object.assign(s, newSetting);
|
||||
}));
|
||||
});
|
||||
// Create
|
||||
settingsToCreate = settingsToCreate.map(setting => settingsCollection.prepareCreate(protectedFunction((s) => {
|
||||
s._raw = sanitizedRaw({ id: setting._id }, settingsCollection.schema);
|
||||
Object.assign(s, setting);
|
||||
})));
|
||||
|
||||
const allRecords = [
|
||||
...settingsToCreate,
|
||||
...settingsToUpdate
|
||||
];
|
||||
|
||||
try {
|
||||
await db.batch(...allRecords);
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
return allRecords.length;
|
||||
// Update
|
||||
settingsToUpdate = settingsToUpdate.map((setting) => {
|
||||
const newSetting = filteredSettings.find(s => s._id === setting.id);
|
||||
return setting.prepareUpdate(protectedFunction((s) => {
|
||||
Object.assign(s, newSetting);
|
||||
}));
|
||||
});
|
||||
|
||||
const allRecords = [
|
||||
...settingsToCreate,
|
||||
...settingsToUpdate
|
||||
];
|
||||
|
||||
try {
|
||||
await db.batch(...allRecords);
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
return allRecords.length;
|
||||
});
|
||||
} catch (e) {
|
||||
log(e);
|
||||
|
|
|
@ -288,6 +288,8 @@ const RocketChat = {
|
|||
const serversDB = database.servers;
|
||||
reduxStore.dispatch(shareSelectServer(server));
|
||||
|
||||
RocketChat.setCustomEmojis();
|
||||
|
||||
// set User info
|
||||
try {
|
||||
const userId = await RNUserDefaults.get(`${ RocketChat.TOKEN_KEY }-${ server }`);
|
||||
|
@ -320,7 +322,7 @@ const RocketChat = {
|
|||
|
||||
updateJitsiTimeout(roomId) {
|
||||
// RC 0.74.0
|
||||
return this.post('jitsi.updateTimeout', { roomId });
|
||||
return this.post('video-conference/jitsi.update-timeout', { roomId });
|
||||
},
|
||||
|
||||
register(credentials) {
|
||||
|
|
|
@ -260,6 +260,21 @@ function bouncy(
|
|||
const WIDTH = 300;
|
||||
const HEIGHT = 300;
|
||||
|
||||
class Image extends React.PureComponent {
|
||||
static propTypes = {
|
||||
imageComponentType: PropTypes.string
|
||||
}
|
||||
|
||||
render() {
|
||||
const { imageComponentType } = this.props;
|
||||
|
||||
const Component = ImageComponent(imageComponentType);
|
||||
|
||||
return <Component {...this.props} />;
|
||||
}
|
||||
}
|
||||
const AnimatedImage = Animated.createAnimatedComponent(Image);
|
||||
|
||||
// it was picked from https://github.com/software-mansion/react-native-reanimated/tree/master/Example/imageViewer
|
||||
// and changed to use FastImage animated component
|
||||
export class ImageViewer extends React.Component {
|
||||
|
@ -386,12 +401,9 @@ export class ImageViewer extends React.Component {
|
|||
|
||||
render() {
|
||||
const {
|
||||
uri, width, height, theme, imageComponentType, ...props
|
||||
uri, width, height, imageComponentType, theme, ...props
|
||||
} = this.props;
|
||||
|
||||
const Component = ImageComponent(imageComponentType);
|
||||
const AnimatedFastImage = Animated.createAnimatedComponent(Component);
|
||||
|
||||
// The below two animated values makes it so that scale appears to be done
|
||||
// from the top left corner of the image view instead of its center. This
|
||||
// is required for the "scale focal point" math to work correctly
|
||||
|
@ -416,7 +428,7 @@ export class ImageViewer extends React.Component {
|
|||
onGestureEvent={this._onPanEvent}
|
||||
onHandlerStateChange={this._onPanEvent}
|
||||
>
|
||||
<AnimatedFastImage
|
||||
<AnimatedImage
|
||||
style={[
|
||||
styles.image,
|
||||
{
|
||||
|
@ -435,6 +447,7 @@ export class ImageViewer extends React.Component {
|
|||
]
|
||||
}
|
||||
]}
|
||||
imageComponentType={imageComponentType}
|
||||
resizeMode='contain'
|
||||
source={{ uri }}
|
||||
{...props}
|
||||
|
|
|
@ -54,8 +54,7 @@ export const FadeFromCenterModal = {
|
|||
const forStackAndroid = ({
|
||||
current,
|
||||
inverted,
|
||||
layouts: { screen },
|
||||
closing
|
||||
layouts: { screen }
|
||||
}) => {
|
||||
const translateX = multiply(
|
||||
current.progress.interpolate({
|
||||
|
@ -65,13 +64,12 @@ const forStackAndroid = ({
|
|||
inverted
|
||||
);
|
||||
|
||||
const opacity = conditional(
|
||||
closing,
|
||||
current.progress,
|
||||
const opacity = multiply(
|
||||
current.progress.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: [0, 1]
|
||||
})
|
||||
}),
|
||||
inverted
|
||||
);
|
||||
|
||||
return {
|
||||
|
|
|
@ -46,9 +46,9 @@ export const navigationTheme = (theme) => {
|
|||
|
||||
// Gets the current screen from navigation state
|
||||
export const getActiveRoute = (state) => {
|
||||
const route = state.routes[state.index];
|
||||
const route = state?.routes[state?.index];
|
||||
|
||||
if (route.state) {
|
||||
if (route?.state) {
|
||||
// Dive into nested navigators
|
||||
return getActiveRoute(route.state);
|
||||
}
|
||||
|
@ -56,4 +56,4 @@ export const getActiveRoute = (state) => {
|
|||
return route;
|
||||
};
|
||||
|
||||
export const getActiveRouteName = state => getActiveRoute(state).name;
|
||||
export const getActiveRouteName = state => getActiveRoute(state)?.name;
|
||||
|
|
|
@ -70,10 +70,15 @@ class AttachmentView extends React.Component {
|
|||
setHeader = () => {
|
||||
const { route, navigation, theme } = this.props;
|
||||
const attachment = route.params?.attachment;
|
||||
const { title } = attachment;
|
||||
let { title } = attachment;
|
||||
try {
|
||||
title = decodeURI(title);
|
||||
} catch {
|
||||
// Do nothing
|
||||
}
|
||||
const options = {
|
||||
title,
|
||||
headerLeft: () => <CloseModalButton testID='close-attachment-view' navigation={navigation} buttonStyle={{ color: themes[theme].previewTintColor }} />,
|
||||
title: decodeURI(title),
|
||||
headerRight: () => <SaveButton testID='save-image' onPress={this.handleSave} buttonStyle={{ color: themes[theme].previewTintColor }} />,
|
||||
headerBackground: () => <View style={{ flex: 1, backgroundColor: themes[theme].previewBackground }} />,
|
||||
headerTintColor: themes[theme].previewTintColor,
|
||||
|
|
|
@ -16,6 +16,7 @@ import RocketChat from '../../lib/rocketchat';
|
|||
import { withTheme } from '../../theme';
|
||||
import protectedFunction from '../../lib/methods/helpers/protectedFunction';
|
||||
import SafeAreaView from '../../containers/SafeAreaView';
|
||||
import log from '../../utils/log';
|
||||
|
||||
const SectionTitle = React.memo(({ title, theme }) => (
|
||||
<Text
|
||||
|
@ -183,26 +184,30 @@ class NotificationPreferencesView extends React.Component {
|
|||
const { room } = this.state;
|
||||
const db = database.active;
|
||||
|
||||
await db.action(async() => {
|
||||
await room.update(protectedFunction((r) => {
|
||||
r[key] = value;
|
||||
}));
|
||||
});
|
||||
|
||||
try {
|
||||
const result = await RocketChat.saveNotificationSettings(this.rid, params);
|
||||
if (result.success) {
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
// do nothing
|
||||
}
|
||||
await db.action(async() => {
|
||||
await room.update(protectedFunction((r) => {
|
||||
r[key] = value;
|
||||
}));
|
||||
});
|
||||
|
||||
await db.action(async() => {
|
||||
await room.update(protectedFunction((r) => {
|
||||
r[key] = room[key];
|
||||
}));
|
||||
});
|
||||
try {
|
||||
const result = await RocketChat.saveNotificationSettings(this.rid, params);
|
||||
if (result.success) {
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
await db.action(async() => {
|
||||
await room.update(protectedFunction((r) => {
|
||||
r[key] = room[key];
|
||||
}));
|
||||
});
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
}
|
||||
|
||||
onValueChangeSwitch = (key, value) => this.saveNotificationSettings(key, value, { [key]: value ? '1' : '0' });
|
||||
|
|
|
@ -145,10 +145,12 @@ class RegisterView extends React.Component {
|
|||
await loginRequest({ user: email, password });
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.data && e.data.errorType === 'username-invalid') {
|
||||
if (e.data?.errorType === 'username-invalid') {
|
||||
return loginRequest({ user: email, password });
|
||||
}
|
||||
showErrorAlert(e.data.error, I18n.t('Oops'));
|
||||
if (e.data?.error) {
|
||||
showErrorAlert(e.data.error, I18n.t('Oops'));
|
||||
}
|
||||
}
|
||||
this.setState({ saving: false });
|
||||
}
|
||||
|
|
|
@ -755,7 +755,7 @@ class RoomView extends React.Component {
|
|||
if (handleCommandScroll(event)) {
|
||||
const offset = input === 'UIKeyInputUpArrow' ? 100 : -100;
|
||||
this.offset += offset;
|
||||
this.flatList.scrollToOffset({ offset: this.offset });
|
||||
this.flatList?.scrollToOffset({ offset: this.offset });
|
||||
} else if (handleCommandRoomActions(event)) {
|
||||
this.goRoomActionsView();
|
||||
} else if (handleCommandSearchMessages(event)) {
|
||||
|
|
|
@ -411,7 +411,7 @@ class RoomsListView extends React.Component {
|
|||
let tempChats = [];
|
||||
let chats = [];
|
||||
if (sortBy === 'alphabetical') {
|
||||
chats = orderBy(data, ['name'], ['asc']);
|
||||
chats = orderBy(data, [`${ this.useRealName ? 'fname' : 'name' }`], ['asc']);
|
||||
} else {
|
||||
chats = orderBy(data, ['roomUpdatedAt'], ['desc']);
|
||||
}
|
||||
|
@ -504,12 +504,7 @@ class RoomsListView extends React.Component {
|
|||
closeSearchHeader();
|
||||
}
|
||||
setTimeout(() => {
|
||||
const offset = isAndroid ? 0 : SCROLL_OFFSET;
|
||||
if (this.scroll.scrollTo) {
|
||||
this.scroll.scrollTo({ x: 0, y: offset, animated: true });
|
||||
} else if (this.scroll.scrollToOffset) {
|
||||
this.scroll.scrollToOffset({ offset });
|
||||
}
|
||||
this.scrollToTop();
|
||||
}, 200);
|
||||
});
|
||||
};
|
||||
|
@ -538,9 +533,7 @@ class RoomsListView extends React.Component {
|
|||
search: result,
|
||||
searching: true
|
||||
});
|
||||
if (this.scroll && this.scroll.scrollTo) {
|
||||
this.scroll.scrollTo({ x: 0, y: 0, animated: true });
|
||||
}
|
||||
this.scrollToTop();
|
||||
}, 300);
|
||||
|
||||
getRoomTitle = item => RocketChat.getRoomTitle(item)
|
||||
|
@ -561,15 +554,17 @@ class RoomsListView extends React.Component {
|
|||
this.goRoom({ item, isMasterDetail });
|
||||
};
|
||||
|
||||
scrollToTop = () => {
|
||||
const offset = isAndroid ? 0 : SCROLL_OFFSET;
|
||||
if (this.scroll?.scrollToOffset) {
|
||||
this.scroll.scrollToOffset({ offset });
|
||||
}
|
||||
}
|
||||
|
||||
toggleSort = () => {
|
||||
const { toggleSortDropdown } = this.props;
|
||||
|
||||
const offset = isAndroid ? 0 : SCROLL_OFFSET;
|
||||
if (this.scroll.scrollTo) {
|
||||
this.scroll.scrollTo({ x: 0, y: offset, animated: true });
|
||||
} else if (this.scroll.scrollToOffset) {
|
||||
this.scroll.scrollToOffset({ offset });
|
||||
}
|
||||
this.scrollToTop();
|
||||
setTimeout(() => {
|
||||
toggleSortDropdown();
|
||||
}, 100);
|
||||
|
|
|
@ -123,7 +123,7 @@ class ShareView extends Component {
|
|||
item.error = error;
|
||||
|
||||
// get video thumbnails
|
||||
if (item.mime?.match(/video/)) {
|
||||
if (item.mime?.match?.(/video/)) {
|
||||
try {
|
||||
const { uri } = await VideoThumbnails.getThumbnailAsync(item.path);
|
||||
item.uri = uri;
|
||||
|
|
|
@ -141,7 +141,15 @@ class Sidebar extends Component {
|
|||
|
||||
get currentItemKey() {
|
||||
const { state } = this.props;
|
||||
return state.routeNames[state.index];
|
||||
return state?.routeNames[state?.index];
|
||||
}
|
||||
|
||||
onPressUser = () => {
|
||||
const { navigation, isMasterDetail } = this.props;
|
||||
if (isMasterDetail) {
|
||||
return;
|
||||
}
|
||||
navigation.closeDrawer();
|
||||
}
|
||||
|
||||
renderAdmin = () => {
|
||||
|
@ -210,7 +218,7 @@ class Sidebar extends Component {
|
|||
|
||||
render() {
|
||||
const {
|
||||
user, Site_Name, baseUrl, useRealName, allowStatusMessage, isMasterDetail, theme, navigation
|
||||
user, Site_Name, baseUrl, useRealName, allowStatusMessage, isMasterDetail, theme
|
||||
} = this.props;
|
||||
|
||||
if (!user) {
|
||||
|
@ -229,7 +237,7 @@ class Sidebar extends Component {
|
|||
]}
|
||||
{...scrollPersistTaps}
|
||||
>
|
||||
<TouchableWithoutFeedback onPress={() => navigation.closeDrawer()} testID='sidebar-close-drawer'>
|
||||
<TouchableWithoutFeedback onPress={this.onPressUser} testID='sidebar-close-drawer'>
|
||||
<View style={styles.header} theme={theme}>
|
||||
<Avatar
|
||||
text={user.username}
|
||||
|
|
|
@ -127,7 +127,7 @@ class ThreadMessagesView extends React.Component {
|
|||
// eslint-disable-next-line react/sort-comp
|
||||
init = () => {
|
||||
if (!this.subscription) {
|
||||
this.load();
|
||||
return this.load();
|
||||
}
|
||||
try {
|
||||
const lastThreadSync = new Date();
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>4.8.0</string>
|
||||
<string>4.8.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>4.8.0</string>
|
||||
<string>4.8.1</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
|
|
Loading…
Reference in New Issue