Unverified Commit 155df774 authored by Diego Mello's avatar Diego Mello Committed by GitHub
Browse files

[NEW] Clear cache (#1660)

parent 8814fc53
......@@ -22,9 +22,10 @@ export function loginFailure(err) {
};
}
export function logout() {
export function logout(forcedByServer = false) {
return {
type: types.LOGOUT
type: types.LOGOUT,
forcedByServer
};
}
......
......@@ -147,6 +147,7 @@ export default {
Copy: 'Copy',
Permalink: 'Permalink',
Certificate_password: 'Certificate Password',
Clear_cache: 'Clear local server cache',
Whats_the_password_for_your_certificate: 'What\'s the password for your certificate?',
Create_account: 'Create an account',
Create_Channel: 'Create Channel',
......@@ -466,6 +467,7 @@ export default {
you_were_mentioned: 'you were mentioned',
you: 'you',
You: 'You',
Logged_out_by_server: 'You\'ve been logged out by the server. Please log in again.',
You_need_to_access_at_least_one_RocketChat_server_to_share_something: 'You need to access at least one Rocket.Chat server to share something.',
Your_certificate: 'Your Certificate',
Your_invite_link_will_expire_after__usesLeft__uses: 'Your invite link will expire after {{usesLeft}} uses.',
......
......@@ -453,6 +453,27 @@ const RocketChat = {
console.log(error);
}
},
async clearCache({ server }) {
try {
const serversDB = database.servers;
await serversDB.action(async() => {
const serverCollection = serversDB.collections.get('servers');
const serverRecord = await serverCollection.find(server);
await serverRecord.update((s) => {
s.roomsUpdatedAt = null;
});
});
} catch (e) {
// Do nothing
}
try {
const db = database.active;
await db.action(() => db.unsafeResetDatabase());
} catch (e) {
// Do nothing
}
},
registerPushToken() {
return new Promise(async(resolve) => {
const token = getDeviceToken();
......
......@@ -121,6 +121,8 @@ const start = function* start({ root }) {
yield Navigation.navigate('SetUsernameView');
} else if (root === 'outside') {
yield Navigation.navigate('OutsideStack');
} else if (root === 'loading') {
yield Navigation.navigate('AuthLoading');
}
RNBootSplash.hide();
};
......
import {
put, call, takeLatest, select, take, fork, cancel
put, call, takeLatest, select, take, fork, cancel, race, delay
} from 'redux-saga/effects';
import RNUserDefaults from 'rn-user-defaults';
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
......@@ -19,8 +19,8 @@ import log from '../utils/log';
import I18n from '../i18n';
import database from '../lib/database';
import EventEmitter from '../utils/events';
import Navigation from '../lib/Navigation';
import { inviteLinksRequest } from '../actions/inviteLinks';
import { showErrorAlert } from '../utils/info';
const getServer = state => state.server.server;
const loginWithPasswordCall = args => RocketChat.loginWithPassword(args);
......@@ -38,7 +38,7 @@ const handleLoginRequest = function* handleLoginRequest({ credentials, logoutOnE
return yield put(loginSuccess(result));
} catch (e) {
if (logoutOnError && (e.data && e.data.message && /you've been logged out by the server/i.test(e.data.message))) {
yield put(logout());
yield put(logout(true));
} else {
yield put(loginFailure(e));
}
......@@ -142,27 +142,35 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
}
};
const handleLogout = function* handleLogout() {
Navigation.navigate('AuthLoading');
const handleLogout = function* handleLogout({ forcedByServer }) {
yield put(appStart('loading'));
const server = yield select(getServer);
if (server) {
try {
yield call(logoutCall, { server });
const serversDB = database.servers;
// all servers
const serversCollection = serversDB.collections.get('servers');
const servers = yield serversCollection.query().fetch();
// see if there're other logged in servers and selects first one
if (servers.length > 0) {
const newServer = servers[0].id;
const token = yield RNUserDefaults.get(`${ RocketChat.TOKEN_KEY }-${ newServer }`);
if (token) {
return yield put(selectServerRequest(newServer));
// if the user was logged out by the server
if (forcedByServer) {
yield put(appStart('outside'));
showErrorAlert(I18n.t('Logged_out_by_server'), I18n.t('Oops'));
EventEmitter.emit('NewServer', { server });
} else {
const serversDB = database.servers;
// all servers
const serversCollection = serversDB.collections.get('servers');
const servers = yield serversCollection.query().fetch();
// see if there're other logged in servers and selects first one
if (servers.length > 0) {
const newServer = servers[0].id;
const token = yield RNUserDefaults.get(`${ RocketChat.TOKEN_KEY }-${ newServer }`);
if (token) {
return yield put(selectServerRequest(newServer));
}
}
// if there's no servers, go outside
yield put(appStart('outside'));
}
// if there's no servers, go outside
yield put(appStart('outside'));
} catch (e) {
yield put(appStart('outside'));
log(e);
......@@ -185,7 +193,11 @@ const root = function* root() {
while (true) {
const params = yield take(types.LOGIN.SUCCESS);
const loginSuccessTask = yield fork(handleLoginSuccess, params);
yield take(types.SERVER.SELECT_REQUEST);
// yield take(types.SERVER.SELECT_REQUEST);
yield race({
selectRequest: take(types.SERVER.SELECT_REQUEST),
timeout: delay(2000)
});
yield cancel(loginSuccessTask);
}
};
......
import React from 'react';
import {
View, Linking, ScrollView, AsyncStorage, SafeAreaView, Switch, Text, Share, Clipboard
View, Linking, ScrollView, AsyncStorage, Switch, Text, Share, Clipboard
} from 'react-native';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { SafeAreaView } from 'react-navigation';
import { logout as logoutAction } from '../../actions/login';
import { logout as logoutAction, loginRequest as loginRequestAction } from '../../actions/login';
import { toggleMarkdown as toggleMarkdownAction } from '../../actions/markdown';
import { toggleCrashReport as toggleCrashReportAction } from '../../actions/crashReport';
import { SWITCH_TRACK_COLOR, themes } from '../../constants/colors';
......@@ -15,7 +16,7 @@ import ListItem from '../../containers/ListItem';
import { DisclosureImage } from '../../containers/DisclosureIndicator';
import Separator from '../../containers/Separator';
import I18n from '../../i18n';
import { MARKDOWN_KEY, CRASH_REPORT_KEY } from '../../lib/rocketchat';
import RocketChat, { MARKDOWN_KEY, CRASH_REPORT_KEY } from '../../lib/rocketchat';
import {
getReadableVersion, getDeviceModel, isAndroid
} from '../../utils/deviceInfo';
......@@ -33,6 +34,7 @@ import { withSplit } from '../../split';
import Navigation from '../../lib/Navigation';
import { LISTENER } from '../../containers/Toast';
import EventEmitter from '../../utils/events';
import { appStart as appStartAction } from '../../actions';
import { onReviewPress } from '../../utils/review';
const SectionSeparator = React.memo(({ theme }) => (
......@@ -80,7 +82,10 @@ class SettingsView extends React.Component {
toggleCrashReport: PropTypes.func,
theme: PropTypes.string,
split: PropTypes.bool,
logout: PropTypes.func.isRequired
logout: PropTypes.func.isRequired,
loginRequest: PropTypes.func,
token: PropTypes.string,
appStart: PropTypes.func
}
logout = () => {
......@@ -91,6 +96,15 @@ class SettingsView extends React.Component {
logout();
}
clearCache = async() => {
const {
server: { server }, loginRequest, token, appStart
} = this.props;
await appStart('loading');
await RocketChat.clearCache({ server });
await loginRequest({ resume: token }, true);
}
toggleMarkdown = (value) => {
AsyncStorage.setItem(MARKDOWN_KEY, JSON.stringify(value));
const { toggleMarkdown } = this.props;
......@@ -163,25 +177,6 @@ class SettingsView extends React.Component {
return <DisclosureImage theme={theme} />;
}
renderLogout = () => {
const { theme } = this.props;
return (
<>
<Separator theme={theme} />
<ListItem
title={I18n.t('Logout')}
testID='settings-logout'
onPress={this.logout}
right={this.renderDisclosure}
color={themes[theme].dangerColor}
theme={theme}
/>
<Separator theme={theme} />
<ItemInfo theme={theme} />
</>
);
}
renderMarkdownSwitch = () => {
const { useMarkdown } = this.props;
return (
......@@ -210,20 +205,18 @@ class SettingsView extends React.Component {
<SafeAreaView
style={[sharedStyles.container, { backgroundColor: themes[theme].auxiliaryBackground }]}
testID='settings-view'
forceInset={{ vertical: 'never' }}
>
<StatusBar theme={theme} />
<ScrollView
{...scrollPersistTaps}
contentContainerStyle={[
sharedStyles.listContentContainer,
styles.listWithoutBorderBottom,
{ borderColor: themes[theme].separatorColor }
]}
contentContainerStyle={styles.listPadding}
showsVerticalScrollIndicator={false}
testID='settings-view-list'
>
{split ? (
<>
<Separator theme={theme} />
<SidebarView theme={theme} />
<SectionSeparator theme={theme} />
<ListItem
......@@ -234,10 +227,10 @@ class SettingsView extends React.Component {
right={this.renderDisclosure}
theme={theme}
/>
<Separator theme={theme} />
</>
) : null}
<Separator theme={theme} />
<ListItem
title={I18n.t('Contact_us')}
onPress={this.sendEmail}
......@@ -319,9 +312,7 @@ class SettingsView extends React.Component {
right={() => this.renderMarkdownSwitch()}
theme={theme}
/>
<SectionSeparator theme={theme} />
<Separator theme={theme} />
<ListItem
title={I18n.t('Send_crash_report')}
testID='settings-view-crash-report'
......@@ -334,7 +325,25 @@ class SettingsView extends React.Component {
theme={theme}
/>
{ split ? this.renderLogout() : null }
<Separator theme={theme} />
<ListItem
title={I18n.t('Clear_cache')}
testID='settings-clear-cache'
onPress={this.clearCache}
right={this.renderDisclosure}
color={themes[theme].dangerColor}
theme={theme}
/>
<Separator theme={theme} />
<ListItem
title={I18n.t('Logout')}
testID='settings-logout'
onPress={this.logout}
right={this.renderDisclosure}
color={themes[theme].dangerColor}
theme={theme}
/>
<Separator theme={theme} />
</ScrollView>
</SafeAreaView>
);
......@@ -343,14 +352,17 @@ class SettingsView extends React.Component {
const mapStateToProps = state => ({
server: state.server,
token: state.login.user && state.login.user.token,
useMarkdown: state.markdown.useMarkdown,
allowCrashReport: state.crashReport.allowCrashReport
});
const mapDispatchToProps = dispatch => ({
logout: () => dispatch(logoutAction()),
loginRequest: (...params) => dispatch(loginRequestAction(...params)),
toggleMarkdown: params => dispatch(toggleMarkdownAction(params)),
toggleCrashReport: params => dispatch(toggleCrashReportAction(params))
toggleCrashReport: params => dispatch(toggleCrashReportAction(params)),
appStart: params => dispatch(appStartAction(params))
});
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(withSplit(SettingsView)));
......@@ -7,12 +7,11 @@ export default StyleSheet.create({
...sharedStyles.separatorVertical,
height: 36
},
listWithoutBorderBottom: {
borderBottomWidth: 0
listPadding: {
paddingVertical: 36
},
infoContainer: {
padding: 15,
marginBottom: 40
padding: 15
},
infoText: {
fontSize: 14,
......
......@@ -8,7 +8,6 @@ import equal from 'deep-equal';
import { Q } from '@nozbe/watermelondb';
import Touch from '../../utils/touch';
import { logout as logoutAction } from '../../actions/login';
import Avatar from '../../containers/Avatar';
import Status from '../../containers/Status/Status';
import RocketChat from '../../lib/rocketchat';
......@@ -44,7 +43,6 @@ class Sidebar extends Component {
navigation: PropTypes.object,
Site_Name: PropTypes.string.isRequired,
user: PropTypes.object,
logout: PropTypes.func.isRequired,
activeItemKey: PropTypes.string,
theme: PropTypes.string,
loadingServer: PropTypes.bool,
......@@ -157,11 +155,6 @@ class Sidebar extends Component {
}
}
logout = () => {
const { logout } = this.props;
logout();
}
sidebarNavigate = (route) => {
const { navigation } = this.props;
navigation.navigate(route);
......@@ -228,13 +221,6 @@ class Sidebar extends Component {
current={activeItemKey === 'AdminPanelStack'}
/>
) : null}
<Separator theme={theme} />
<SidebarItem
text={I18n.t('Logout')}
left={<CustomIcon name='sign-out' size={20} color={themes[theme].titleText} />}
onPress={this.logout}
testID='sidebar-logout'
/>
</>
);
}
......@@ -298,10 +284,11 @@ class Sidebar extends Component {
<CustomIcon name='arrow-down' size={20} style={[styles.headerIcon, showStatus && styles.inverted, { color: themes[theme].titleText }]} />
</Touch>
{!split || showStatus ? <Separator theme={theme} /> : null}
{!split ? <Separator theme={theme} /> : null}
{!showStatus && !split ? this.renderNavigation() : null}
{showStatus ? this.renderStatus() : null}
{!split ? <Separator theme={theme} /> : null}
</ScrollView>
</SafeAreaView>
);
......@@ -322,8 +309,4 @@ const mapStateToProps = state => ({
loadingServer: state.server.loading
});
const mapDispatchToProps = dispatch => ({
logout: () => dispatch(logoutAction())
});
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(withSplit(Sidebar)));
export default connect(mapStateToProps)(withTheme(withSplit(Sidebar)));
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment