...
 
Commits (3)
......@@ -21,8 +21,11 @@ import {
import { Provider, observer } from 'mobx-react/native';
import RNBootSplash from 'react-native-bootsplash';
import FlashMessage from 'react-native-flash-message';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import NavigationService from './src/navigation/NavigationService';
import NavigationService, {
setTopLevelNavigator,
} from './src/navigation/NavigationService';
import KeychainModalScreen from './src/keychain/KeychainModalScreen';
import BlockchainTransactionModalScreen from './src/blockchain/transaction-modal/BlockchainTransactionModalScreen';
import NavigationStack from './src/navigation/NavigationStack';
......@@ -55,6 +58,12 @@ import boostedContentService from './src/common/services/boosted-content.service
import translationService from './src/common/services/translation.service';
import ThemedStyles from './src/styles/ThemedStyles';
import {
NavigationContainer,
DarkTheme,
DefaultTheme,
} from '@react-navigation/native';
let deepLinkUrl = '';
const statusBarStyle = Platform.OS === 'ios' ? 'dark-content' : 'default';
......@@ -95,7 +104,7 @@ sessionService.onLogin(async () => {
// hide splash
RNBootSplash.hide({ duration: 250 });
NavigationService.navigate(sessionService.initialScreen);
NavigationService.navigate('App', { screen: sessionService.initialScreen});
// check onboarding progress and navigate if necessary
stores.onboarding.getProgress(sessionService.initialScreen !== 'OnboardingScreenNew');
......@@ -111,7 +120,7 @@ sessionService.onLogin(async () => {
try {
// handle deep link (if the app is opened by one)
if (deepLinkUrl) {
deeplinkService.navigate(deepLinkUrl);
deeplinkService.navigate('App', { screen: deepLinkUrl});
deepLinkUrl = '';
}
......@@ -206,6 +215,13 @@ class App extends Component<Props, State> {
* On component did mount
*/
async componentDidMount() {
this.appInit();
}
/**
* App initialization
*/
async appInit() {
try {
// load app setting before start
const results = await Promise.all([settingsStore.init(), Linking.getInitialURL()]);
......@@ -224,7 +240,7 @@ class App extends Component<Props, State> {
if (!token) {
logService.info('[App] there is no active session');
RNBootSplash.hide({ duration: 250 });
NavigationService.navigate('Login');
// NavigationService.navigate('Auth', { screen: 'Login'});
} else {
logService.info('[App] session initialized');
}
......@@ -309,19 +325,23 @@ class App extends Component<Props, State> {
return null;
}
const isLoggedIn = sessionService.userLoggedIn;
const app = (
<Provider key="app" {...stores}>
<ErrorBoundary message="An error occurred" containerStyle={CS.centered}>
<StatusBar barStyle={statusBarStyle} />
<NavigationStack
screenProps={ThemedStyles.theme} // force screen re-render when theme change
ref={navigatorRef => {
NavigationService.setTopLevelNavigator(navigatorRef);
}}
/>
<FlashMessage renderCustomContent={this.renderNotification} />
</ErrorBoundary>
</Provider>
<SafeAreaProvider>
<NavigationContainer
ref={navigatorRef => setTopLevelNavigator(navigatorRef)}
theme={ThemedStyles.navTheme}
>
<Provider key="app" {...stores}>
<ErrorBoundary message="An error occurred" containerStyle={CS.centered}>
<StatusBar barStyle={statusBarStyle} />
<NavigationStack key={ThemedStyles.theme} isLoggedIn={isLoggedIn}/>
<FlashMessage renderCustomContent={this.renderNotification} />
</ErrorBoundary>
</Provider>
</NavigationContainer>
</SafeAreaProvider>
);
const keychainModal = (
......
......@@ -26,6 +26,7 @@ if (process.env.JEST_WORKER_ID === undefined) {
// for dev only log into the console
if (__DEV__) {
console.log(hint.originalException);
console.log('sentry', event, hint);
return null;
}
......@@ -39,7 +40,7 @@ if (process.env.JEST_WORKER_ID === undefined) {
onError(error => {
console.log(error);
logService.exception(error);
})
});
// react-native-exception-handler global handlers
if (!__DEV__) {
......
......@@ -43,13 +43,13 @@ describe('Activity screen component', () => {
it('renders correctly with an entity as param', async () => {
navigation = {
push: jest.fn(),
state: {
route: {
routeName: 'some',
params: {entity: activitiesServiceFaker().load(1).activities[0]}
}
};
entitiesService.single.mockResolvedValue(ActivityModel.create(navigation.state.params.entity));
entitiesService.single.mockResolvedValue(ActivityModel.create(navigation.route.entity));
screen = shallow(
<ActivityScreen navigation={navigation}/>
......
......@@ -20,8 +20,8 @@
android.useAndroidX=true
android.enableJetifier=true
# MYAPP_RELEASE_STORE_FILE=minds.keystore
# MYAPP_RELEASE_KEY_ALIAS=alias_name
MYAPP_RELEASE_STORE_FILE=minds.keystore
MYAPP_RELEASE_KEY_ALIAS=alias_name
org.gradle.jvmargs=-Xmx2048m
systemProp.org.gradle.internal.http.connectionTimeout=180000
systemProp.org.gradle.internal.http.socketTimeout=180000
......
......@@ -5,7 +5,7 @@ import "./global";
import { AppRegistry, Platform } from 'react-native';
import App from './App';
import { useScreens } from 'react-native-screens';
useScreens(Platform.OS !== 'ios');
useScreens();
// const modules = require.getModules();
// const moduleIds = Object.keys(modules);
......
......@@ -207,6 +207,8 @@ PODS:
- React
- react-native-randombytes (3.5.3):
- React
- react-native-safe-area-context (0.7.2):
- React
- react-native-sqlite-storage (4.1.0):
- React
- react-native-video (5.0.2):
......@@ -259,6 +261,8 @@ PODS:
- React
- RNCAsyncStorage (1.6.2):
- React
- RNCMaskedView (0.1.6):
- React
- RNConvertPhAsset (1.0.3):
- React
- RNDeviceInfo (4.0.1):
......@@ -273,13 +277,13 @@ PODS:
- React
- RNFS (2.16.2):
- React
- RNGestureHandler (1.5.0):
- RNGestureHandler (1.5.6):
- React
- RNLocalize (1.3.1):
- React
- RNReanimated (1.4.0):
- RNReanimated (1.7.0):
- React
- RNScreens (2.0.0-alpha.11):
- RNScreens (2.0.0-beta.2):
- React
- RNSentry (1.2.2):
- React
......@@ -325,6 +329,7 @@ DEPENDENCIES:
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
- react-native-notifications (from `../node_modules/react-native-notifications`)
- react-native-randombytes (from `../node_modules/react-native-randombytes`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- react-native-sqlite-storage (from `../node_modules/react-native-sqlite-storage`)
- react-native-video (from `../node_modules/react-native-video`)
- react-native-webview (from `../node_modules/react-native-webview`)
......@@ -343,6 +348,7 @@ DEPENDENCIES:
- ReactNativeExceptionHandler (from `../node_modules/react-native-exception-handler`)
- RNBootSplash (from `../node_modules/react-native-bootsplash`)
- "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)"
- "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)"
- RNConvertPhAsset (from `../node_modules/react-native-convert-ph-asset`)
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
- RNExitApp (from `../node_modules/react-native-exit-app`)
......@@ -411,6 +417,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-notifications"
react-native-randombytes:
:path: "../node_modules/react-native-randombytes"
react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context"
react-native-sqlite-storage:
:path: "../node_modules/react-native-sqlite-storage"
react-native-video:
......@@ -445,6 +453,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-bootsplash"
RNCAsyncStorage:
:path: "../node_modules/@react-native-community/async-storage"
RNCMaskedView:
:path: "../node_modules/@react-native-community/masked-view"
RNConvertPhAsset:
:path: "../node_modules/react-native-convert-ph-asset"
RNDeviceInfo:
......@@ -501,6 +511,7 @@ SPEC CHECKSUMS:
react-native-netinfo: fa32a5bb986924e9be82a261c262039042dde81e
react-native-notifications: 163ddedac6fcc8d850ea15b06abdadcacdff00f1
react-native-randombytes: 3638d24759d67c68f6ccba60c52a7a8a8faa6a23
react-native-safe-area-context: 4b3d1b9ebb040a4814a222703e7434b20c95fcf5
react-native-sqlite-storage: f06bfba10f67f989c00b6a699b9c2b80a816edbe
react-native-video: d01ed7ff1e38fa7dcc6c15c94cf505e661b7bfd0
react-native-webview: deb4a57eee4906e992e2f84bb087a15fd302378e
......@@ -518,16 +529,17 @@ SPEC CHECKSUMS:
ReactNativeExceptionHandler: 8025d98049c25f186835a3af732dd7c9974d6dce
RNBootSplash: 161de9d2b5dc2af37c2777063b8e6d844ab2a6ff
RNCAsyncStorage: 60a80e72d95bf02a01cace55d3697d9724f0d77f
RNCMaskedView: a88953beefbd347a29072d9eba90e42945fe291e
RNConvertPhAsset: 9b366b8a1abc194b76572712c6f7dd89c9e4e37f
RNDeviceInfo: 687c1b2ab6d86ff1ca1208783320cd144138c7f2
RNExitApp: c4e052df2568b43bec8a37c7cd61194d4cfee2c3
RNFastImage: 9b0c22643872bb7494c8d87bbbb66cc4c0d9e7a2
RNFileShareIntent: 783adf7c4386c6024dd5dfeb96cc7836948f8b47
RNFS: 0d4191b1052bef9ce70deff00a5b4169c62bbd9b
RNGestureHandler: a4ddde1ffc6e590c8127b8b7eabfdade45475c74
RNGestureHandler: 911d3b110a7a233a34c4f800e7188a84b75319c6
RNLocalize: 07eb7a91d10021cdf59d80061ebf3adb8a5b5688
RNReanimated: b2ab0b693dddd2339bd2f300e770f6302d2e960c
RNScreens: ad3661f864ef18d952e9a4799b6791683e33c1fc
RNReanimated: 031fe8d9ea93c2bd689a40f05320ef9d96f74d7f
RNScreens: 5e4758109c6d35f9a009ce72af873df907548020
RNSentry: 9cfa3717b1e6bf9ad4b124683e78e3b98b01d3af
RNShare: 8b171d4b43c1d886917fdd303bf7a4b87167b05c
RNSVG: f6177f8d7c095fada7cfee2e4bb7388ba426064c
......
{
"name": "Minds",
"version": "3.12.0",
"version": "3.16.0",
"private": true,
"scripts": {
"android": "react-native run-android",
......@@ -21,7 +21,11 @@
"@react-native-community/art": "^1.0.2",
"@react-native-community/async-storage": "^1.3.4",
"@react-native-community/cameraroll": "^1.3.0",
"@react-native-community/masked-view": "^0.1.6",
"@react-native-community/netinfo": "^4.4.0",
"@react-navigation/bottom-tabs": "^5.0.3",
"@react-navigation/native": "^5.0.3",
"@react-navigation/stack": "^5.0.3",
"@sentry/react-native": "^1.2.2",
"crypto-js": "^3.1.9-1",
"detox": "^14.8.1",
......@@ -52,7 +56,7 @@
"react-native-file-type": "^0.0.8",
"react-native-flash-message": "^0.1.15",
"react-native-fs": "^2.16.1",
"react-native-gesture-handler": "^1.4.1",
"react-native-gesture-handler": "^1.5.6",
"react-native-image-picker": "algera/react-native-image-picker#8cc7fc453c3b5f0f8d7b2cb6cf25690008740d0e",
"react-native-image-progress": "^1.1.1",
"react-native-jitsi-meet": "Minds/react-native-jitsi-meet#a8362eecfbbbd93f64775cdcea24e3e9485461de",
......@@ -67,9 +71,10 @@
"react-native-qrcode-svg": "^5.2.0",
"react-native-randombytes": "^3.5.3",
"react-native-read-more-text": "devbelieve365/react-native-read-more-text",
"react-native-reanimated": "^1.3.0",
"react-native-reanimated": "^1.7.0",
"react-native-redash": "^8.6.0",
"react-native-screens": "^2.0.0-alpha.11",
"react-native-safe-area-context": "^0.7.2",
"react-native-screens": "^2.0.0-beta.2",
"react-native-share": "^2.0.0",
"react-native-snap-carousel": "^3.8.2",
"react-native-sqlite-storage": "^4.1.0",
......@@ -78,9 +83,6 @@
"react-native-vector-icons": "^6.6.0",
"react-native-video": "^5.0.2",
"react-native-webview": "^7.4.2",
"react-navigation": "^4.0.10",
"react-navigation-stack": "^1.10.2",
"react-navigation-tabs": "^2.5.6",
"rn-apk": "^0.2.9",
"rne-modal-tooltip": "gist:b28c003d87c619674def0878473338a0",
"socket.io-client": "^2.3.0",
......
......@@ -22,8 +22,8 @@ export default class ForgotScreen extends Component {
*/
render() {
const code =
this.props.navigation.state.params &&
this.props.navigation.state.params.code;
this.props.route.params &&
this.props.route.params.code;
const CS = ThemedStyles.style;
return (
......
......@@ -7,7 +7,6 @@ import {
Animated,
Text,
TouchableOpacity,
SafeAreaView,
ScrollView,
Platform,
KeyboardAvoidingView,
......@@ -19,6 +18,7 @@ import i18nService from '../common/services/i18n.service';
import sessionService from '../common/services/session.service';
import ThemedStyles from '../styles/ThemedStyles';
import { SafeAreaView } from 'react-native-safe-area-context';
const LOGO_HEIGHT = 80;
const LOGO_HEIGHT_SMALL = 40;
......@@ -27,12 +27,6 @@ const LOGO_HEIGHT_SMALL = 40;
* Login screen
*/
export default class LoginScreen extends Component {
/**
* Disable navigation bar
*/
static navigationOptions = {
header: null
}
state = {
keyboard: false,
......
......@@ -115,7 +115,7 @@ export default class ResetPassword extends PureComponent {
if (!this.state.sent ) {
this.setState({sending: true});
const state = navigation.getCurrentState();
const state = navigation.dangerouslyGetState();
try {
const data = await authService.reset(state.params.username, this.state.password, state.params.code);
......
......@@ -69,15 +69,15 @@ export default class BlockchainWalletDetailsScreen extends Component {
this.setState({
editable: false,
importable: false,
address: this.props.navigation.state.params.address,
edit: !!this.props.navigation.state.params.edit,
new: this.props.navigation.state.params.new,
address: this.props.route.params.address,
edit: !!this.props.route.params.edit,
new: this.props.route.params.new,
offchain: false,
tokens: null,
eth: null,
});
this.load(this.props.navigation.state.params.address);
this.load(this.props.route.params.address);
}
componentDidMount() {
......
......@@ -31,7 +31,7 @@ export default class BlockchainWalletImportScreen extends Component {
};
componentWillMount() {
const params = this.props.navigation.state.params || {};
const params = this.props.route.params || {};
this.setState({
importingRemote: !!params.address,
......@@ -81,7 +81,7 @@ export default class BlockchainWalletImportScreen extends Component {
async import() {
await this.props.blockchainWallet.import(this.state.privateKey);
const params = this.props.navigation.state.params || {};
const params = this.props.route.params || {};
if (params.onSuccess) {
params.onSuccess();
......
......@@ -23,7 +23,7 @@ import {
import ActionSheet from 'react-native-actionsheet';
import { Header } from 'react-navigation-stack';
import { Header } from '@react-navigation/stack';
import { inject, observer } from 'mobx-react/native';
......@@ -41,7 +41,7 @@ import ThumbDownAction from '../newsfeed/activity/actions/ThumbDownAction';
import RemindAction from '../newsfeed/activity/actions/RemindAction';
import CommentsAction from '../newsfeed/activity/actions/CommentsAction';
import shareService from '../share/ShareService';
import commentsStoreProvider from '../comments/CommentsStoreProvider';
import Provider from '../comments/CommentsStoreProvider';
import CommentList from '../comments/CommentList';
import CenteredLoading from '../common/components/CenteredLoading';
import logService from '../common/services/log.service';
......@@ -86,7 +86,7 @@ export default class BlogsViewScreen extends Component {
* Component did mount
*/
async componentDidMount() {
const params = this.props.navigation.state.params;
const params = this.props.route.params;
try {
if (params.blog) {
if (params.blog._list && params.blog._list.metadataService) {
......@@ -267,6 +267,7 @@ export default class BlogsViewScreen extends Component {
entity={this.props.blogsView.blog}
store={this.comments}
navigation={this.props.navigation}
route={this.props.route}
keyboardVerticalOffset = {Header.HEIGHT - 65}
/>
:
......
......@@ -37,7 +37,7 @@ export default class BoostConsoleScreen extends Component {
* On component will mount
*/
componentWillMount() {
const filter = this.props.navigation.state.params.filter;
const filter = this.props.route.params.filter;
if (filter) {
this.props.boost.setFilter(filter);
......
......@@ -271,7 +271,7 @@ export default class BoostScreen extends Component {
}
buildAllowedTypes() {
const entity = this.props.navigation.state.params.entity;
const entity = this.props.route.params.entity;
if (!entity || !entity.type) {
this.setState({});
......@@ -400,7 +400,7 @@ export default class BoostScreen extends Component {
}
async _submitBoost() {
const entity = this.props.navigation.state.params.entity;
const entity = this.props.route.params.entity;
this.setState({ inProgress: true });
let guid = null;
......
......@@ -4,8 +4,8 @@ import {
StyleSheet,
TouchableOpacity,
Image,
FlatList,
Platform,
FlatList
} from 'react-native';
import CameraRoll from '@react-native-community/cameraroll';
......@@ -14,11 +14,9 @@ import Icon from 'react-native-vector-icons/Ionicons';
import CenteredLoading from '../common/components/CenteredLoading';
import androidPermissionsService from '../common/services/android-permissions.service';
import testID from '../common/helpers/testID';
import logService from '../common/services/log.service';
import { CommonStyle } from '../styles/Common';
import { View } from 'react-native-animatable';
/**
* Gallery View
*/
......@@ -109,20 +107,23 @@ export default class CaptureGallery extends PureComponent {
* Render
*/
render() {
if (!this.state.imagesLoaded) {
return <CenteredLoading />;
}
return (
<FlatList
ref={this.setListRef}
ListHeaderComponent={this.props.header}
data={this.state.photos}
renderItem={this.renderTile}
onEndReached={this._loadPhotos}
ListFooterComponent={this.state.loading ? <CenteredLoading /> : null}
numColumns={3}
/>
<View style={[CommonStyle.backgroundWhite, CommonStyle.flexContainer]}>
{this.state.imagesLoaded ? (
<FlatList
ref={this.setListRef}
ListHeaderComponent={this.props.header}
data={this.state.photos}
renderItem={this.renderTile}
style={CommonStyle.flexContainer}
onEndReached={this._loadPhotos}
ListFooterComponent={this.state.loading ? <CenteredLoading /> : null}
numColumns={3}
/>
) : (
<CenteredLoading />
)}
</View>
);
}
......
......@@ -11,7 +11,7 @@ import { observer, inject } from 'mobx-react/native';
import { Icon } from 'react-native-elements'
import {
NavigationActions
} from 'react-navigation';
} from '@react-navigation/native';
import colors from '../styles/Colors';
import HashtagService from '../common/services/hashtag.service'
......@@ -40,19 +40,20 @@ import TextInput from '../common/components/TextInput';
import TabIcon from '../tabs/TabIcon';
import TopbarNew from '../topbar/TopbarNew';
export default
@inject('user', 'capture')
@observer
export default class CapturePoster extends Component {
/**
* Disable navigation bar
*/
static navigationOptions = ({ navigation }) => ({
tabBarIcon: ({ tintColor }) => (
<TabIcon name="md-add-circle-outline" size={44} color={tintColor} />
),
headerRight: navigation.state.params && navigation.state.params.headerRight
});
class CapturePoster extends Component {
// /**
// * Disable navigation bar
// */
// static navigationOptions = ({ route }) => ({
// tabBarIcon: ({ tintColor }) => (
// <TabIcon name="md-add-circle-outline" size={44} color={tintColor} />
// ),
// headerRight: route && route.headerRight
// });
state = {
postImageUri: '',
......@@ -67,27 +68,11 @@ export default class CapturePoster extends Component {
time_created: null,
};
/**
* On component will mount
*/
componentWillMount() {
const { setParams } = this.props.navigation;
let { params } = this.props.navigation.state;
if (!params) params = {};
setParams({
headerRight: <CapturePostButton
onPress={() => !params.isRemind ? this.submit() : this.remind()}
text={params.isRemind ? i18n.t('capture.remind').toUpperCase() : i18n.t('capture.post').toUpperCase()}
testID="CapturePostButton"
/>
});
}
/**
* On component did mount
*/
componentDidMount() {
const { params } = this.props.navigation.state;
let { params } = this.props.route;
if (params) {
this.props.capture.reset();
......@@ -106,6 +91,24 @@ export default class CapturePoster extends Component {
}
}
const { setOptions } = this.props.navigation;
if (!params) {
params = {};
}
setOptions({
headerRight: () => (
<CapturePostButton
onPress={() => (!params.isRemind ? this.submit() : this.remind())}
text={
params.isRemind
? i18n.t('capture.remind').toUpperCase()
: i18n.t('capture.post').toUpperCase()
}
testID="CapturePostButton"
/>
)
});
this.loadNsfwFromPersistentStorage();
}
......@@ -130,7 +133,7 @@ export default class CapturePoster extends Component {
* Show context
*/
showContext () {
let group = this.props.navigation.state.params ? this.props.navigation.state.params.group : null;
let group = this.props.route.params ? this.props.route.params.group : null;
return group? <Text style={styles.title}> {i18n.t('capture.postingIn', {group: group.name})} </Text> :null;
}
......@@ -140,17 +143,19 @@ export default class CapturePoster extends Component {
*/
navToPrevious(entity, group) {
const {state, dispatch, goBack} = this.props.navigation;
const {dispatch, goBack} = this.props.navigation;
const params = {
const { params } = this.props.route;
const routeParams = {
prepend: ActivityModel.checkOrCreate(entity),
};
if (group) params.group = group;
if (group) routeParams.group = group;
dispatch(NavigationActions.setParams({
params,
key: state.params.parentKey, // passed from index
routeParams,
key: params.parentKey, // passed from index
}));
goBack(null);
......@@ -204,7 +209,7 @@ export default class CapturePoster extends Component {
* Render
*/
render() {
const params = this.props.navigation.state.params || {};
const params = this.props.route.params || {};
return params.isRemind ? this.renderRemind() : this.renderNormal();
}
......@@ -215,11 +220,10 @@ export default class CapturePoster extends Component {
renderNormal() {
const navigation = this.props.navigation;
const params = navigation.state.params || {};
const params = this.props.route.params || {};
return (
<View style={CS.flexContainer} testID="capturePosterView">
<TopbarNew title={i18n.t('tabTitleNotifications')}/>
<CaptureGallery
onSelected={this.onAttachedMedia}
header={this.getHeader(true)}
......@@ -238,9 +242,6 @@ export default class CapturePoster extends Component {
*/
renderRemind() {
const text = this.props.capture.text;
const navigation = this.props.navigation;
const params = navigation.state.params || {};
return (
<View style={CS.flexContainer}>
......@@ -261,9 +262,9 @@ export default class CapturePoster extends Component {
* Get remind card
*/
getRemind() {
const { params } = this.props.navigation.state;
const ShowComponent = params.entity.subtype == 'blog' ? BlogCard : Activity;
return <ShowComponent hideTabs={true} entity={params.entity} />
const { params } = this.props.route;
const ShowComponent = params.entity.subtype === 'blog' ? BlogCard : Activity;
return <ShowComponent hideTabs={true} entity={params.entity} />;
}
/**
......@@ -311,7 +312,7 @@ export default class CapturePoster extends Component {
*/
onAttachedMedia = async (response) => {
const attachment = this.props.capture.attachment;
let group = this.props.navigation.state.params ? this.props.navigation.state.params.group : null
let group = this.props.route.params ? this.props.route.params.group : null
let extra = null;
if (group) {
......@@ -342,7 +343,7 @@ export default class CapturePoster extends Component {
* Create a remind
*/
async remind() {
const { params } = this.props.navigation.state;
const { params } = this.props.route;
const message = this.props.capture.text;
const metadata = params.entity.getClientMetadata();
......@@ -351,7 +352,7 @@ export default class CapturePoster extends Component {
...metadata
};
let group = this.props.navigation.state.params ? this.props.navigation.state.params.group : null
let group = this.props.route.params ? this.props.route.params.group : null
if(HashtagService.slice(message).length > HashtagService.maxHashtags){ //if hashtag count greater than 5
Alert.alert(i18n.t('capture.maxHashtags', {maxHashtags: HashtagService.maxHashtags}));
......@@ -417,8 +418,8 @@ export default class CapturePoster extends Component {
newPost = Object.assign(newPost, this.props.capture.embed.meta);
}
if (this.props.navigation.state.params && this.props.navigation.state.params.group) {
newPost.container_guid = this.props.navigation.state.params.group.guid;
if (this.props.route.params && this.props.route.params.group) {
newPost.container_guid = this.props.route.params.group.guid;
}
if (this.props.capture.tags && this.props.capture.tags.length) {
......@@ -446,8 +447,8 @@ export default class CapturePoster extends Component {
if (this.props.onComplete) {
this.props.onComplete(response.entity);
} else if (this.props.navigation.state.params && this.props.navigation.state.params.group) {
this.navToPrevious(response.entity, this.props.navigation.state.params.group);
} else if (this.props.route.params && this.props.route.params.group) {
this.navToPrevious(response.entity, this.props.route.params.group);
} else {
this.navToPrevious(response.entity);
}
......
......@@ -50,19 +50,12 @@ class ChannelScreen extends Component {
guid: null,
};
/**
* Disable navigation bar
*/
static navigationOptions = {
header: null,
};
/**
* Load data on mount
*/
async componentWillMount() {
this.disposeEnter = this.props.navigation.addListener('didFocus', (s) => {
const params = this.props.navigation.state.params;
const params = this.props.route.params;
const store = this.props.channel.store(this.guid);
if (params && params.prepend) {
if (store.channel && store.channel.isOwner && store.channel.isOwner()) {
......@@ -84,7 +77,7 @@ class ChannelScreen extends Component {
* Initial load
*/
async initialLoad() {
const params = this.props.navigation.state.params;
const params = this.props.route.params;
if (params.entity) {
// load channel from endpoint
......@@ -102,7 +95,7 @@ class ChannelScreen extends Component {
*/
componentWillUnmount() {
if (this.disposeEnter) {
this.disposeEnter.remove();
this.disposeEnter();
}
this.props.channel.garbageCollect();
this.props.channel.store(this.guid).markInactive();
......@@ -182,7 +175,7 @@ class ChannelScreen extends Component {
}
get guid() {
const params = this.props.navigation.state.params;
const params = this.props.route.params;
let guid = params.entity ? params.entity.guid : params.guid;
......
......@@ -120,6 +120,7 @@ class Comment extends Component {
onInputFocus={this.onInputFocus}
onCommentFocus={this.onCommentFocus}
navigation={this.props.navigation}
route={this.props.route}
/>
}
......
......@@ -54,6 +54,7 @@ type PropsType = {
store: any,
user: any,
navigation: any,
route: any,
onInputFocus?: Function,
onCommentFocus?: Function
};
......@@ -280,7 +281,7 @@ class CommentList extends React.Component<PropsType, StateType> {
*/
loadComments = async (loadingMore: boolean = false, descending: boolean = true): Promise<void> => {
let guid;
const scrollToBottom = this.props.navigation.state.params.scrollToBottom;
const scrollToBottom = this.props.route.params.scrollToBottom;
if (this.props.entity) {
guid = this.props.entity.guid;
......@@ -453,6 +454,7 @@ class CommentList extends React.Component<PropsType, StateType> {
onTextInputfocus={this.onChildFocus}
onCommentFocus={this.onCommentFocus}
navigation={this.props.navigation}
route={this.props.route}
commentFocusCall={this.commentFocusCall}
index={row.index}
/>
......
......@@ -72,21 +72,21 @@ class DiscoveryScreen extends Component {
minimumViewTime: 300,
};
static navigationOptions = {
tabBarIcon: ({ tintColor }) => (
featuresService.has('navigation-2020')
? <TabIcon name="hashtag" color={tintColor} />
: <Icon name="search" size={24} color={tintColor} />
),
tabBarOnPress: ({ navigation, defaultHandler }) => {
// tab button tapped again?
if (navigation.isFocused()) {
stores.discovery.reload();
return;
}
defaultHandler();
}
}
// static navigationOptions = {
// tabBarIcon: ({ tintColor }) => (
// featuresService.has('navigation-2020')
// ? <TabIcon name="hashtag" color={tintColor} />
// : <Icon name="search" size={24} color={tintColor} />
// ),
// tabBarOnPress: ({ navigation, defaultHandler }) => {
// // tab button tapped again?
// if (navigation.isFocused()) {
// stores.discovery.reload();
// return;
// }
// defaultHandler();
// }
// }
/**
* constructor
......@@ -94,9 +94,9 @@ class DiscoveryScreen extends Component {
constructor(props) {
super(props);
this.props.discovery.init();
// this.props.discovery.init();
const params = this.props.navigation.state.params;
const params = this.props.route.params;
if (params && params.type) {
this.props.discovery.filters.setType(params.type);
}
......@@ -134,11 +134,11 @@ class DiscoveryScreen extends Component {
*/
componentWillUnmount() {
if (this.disposeEnter) {
this.disposeEnter.remove();
this.disposeEnter();
}
if (this.disposeLeave) {
this.disposeLeave.remove();
this.disposeLeave();
}
}
......
......@@ -13,7 +13,7 @@ import {
Platform,
} from 'react-native';
import { Header } from 'react-navigation-stack';
import { Header } from '@react-navigation/stack';
import {
observer,
......@@ -85,7 +85,7 @@ export default class GroupViewScreen extends Component {
* Load initial data
*/
async initialLoad() {
const params = this.props.navigation.state.params;
const params = this.props.route.params;
if (params.group) {
// load group and update async
......@@ -113,13 +113,13 @@ export default class GroupViewScreen extends Component {
}
componentDidMount() {
const params = this.props.navigation.state.params;
const params = this.props.route.params;
// load data async
this.initialLoad();
this.disposeEnter = this.props.navigation.addListener('didFocus', (s) => {
const params = this.props.navigation.state.params;
const params = this.props.route.params;
if (params && params.prepend) {
this.props.groupView.prepend(params.prepend);
// we clear the parameter to prevent prepend it again on goBack
......@@ -149,7 +149,7 @@ export default class GroupViewScreen extends Component {
componentWillUnmount() {
this.props.groupView.clear();
if (this.disposeEnter) {
this.disposeEnter.remove();
this.disposeEnter();
}
}
......@@ -214,6 +214,7 @@ export default class GroupViewScreen extends Component {
entity={group.group}
store={this.comments}
navigation={this.props.navigation}
route={this.props.route}
keyboardVerticalOffset = {Header.HEIGHT - 65}
/>
);
......
......@@ -39,7 +39,7 @@ export default class GroupsBarItem extends Component {
}
navToGroup = () => {
navigationService.push('GroupView', {group: this.props.group});
navigationService.navigate('GroupView', {group: this.props.group});
}
render() {
......
......@@ -22,7 +22,6 @@ let FORWARD_DURATION = 7;
import {observer} from 'mobx-react/native';
import Icon from 'react-native-vector-icons/Ionicons';
import {withNavigation} from 'react-navigation';
import {CommonStyle as CS} from '../styles/Common';
import colors from '../styles/Colors';
import ExplicitImage from '../common/components/explicit/ExplicitImage';
......@@ -31,6 +30,7 @@ import i18n from '../common/services/i18n.service';
import attachmentService from '../common/services/attachment.service';
import videoPlayerService from '../common/services/video-player.service';
import apiService from '../common/services/api.service';
import NavigationService from '../navigation/NavigationService';
const isIOS = Platform.OS === 'ios';
......@@ -86,7 +86,7 @@ class MindsVideo extends Component {
onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
});
this.onScreenBlur = this.props.navigation.addListener('didBlur', () => {
this.onScreenBlur = NavigationService.addListener('didBlur', () => {
this.pause();
});
}
......@@ -95,7 +95,9 @@ class MindsVideo extends Component {
* On component will unmount
*/
componentWillUnmount() {
this.onScreenBlur.remove();
if (this.onScreenBlur) {
this.onScreenBlur();
}
if (videoPlayerService.current === this) {
videoPlayerService.clear();
}
......@@ -663,4 +665,4 @@ let styles = StyleSheet.create({
},
});
export default withNavigation(MindsVideo);
export default MindsVideo;
......@@ -62,7 +62,6 @@ export default class VideoCard extends Component {
}
}
const styles = StyleSheet.create({
headertextcontainer: {
padding: 8,
......@@ -80,10 +79,10 @@ const styles = StyleSheet.create({
flex:1,
},
ownerContainer: {
flex:1,
flex:1,
flexDirection: 'row',
alignSelf: 'flex-start',
padding:3 ,
alignSelf: 'flex-start',
padding:3 ,
alignItems: 'center',
justifyContent: 'center'
},
......
......@@ -67,7 +67,7 @@ class MessengerScreen extends Component {
componentWillUnmount() {
this.props.messengerList.unlisten();
if (this.disposeEnter) {
this.disposeEnter.remove();
this.disposeEnter();
}
//this.disposeLeave();
}
......
import { NavigationActions, StackActions, SwitchActions } from 'react-navigation';
import { NavigationActions, StackActions, SwitchActions } from '@react-navigation/native';
let _navigator;
let _navigator = null;
function getStateFrom(nav) {
let state = nav.routes[nav.index];
if (state.routes) {
state = getStateFrom(state);
if (nav.routes && nav.routes[nav.index].state) {
return getStateFrom(nav.routes[nav.index].state);
}
return state;
return nav.routes[nav.index];
}
function setTopLevelNavigator(navigatorRef) {
export function setTopLevelNavigator(navigatorRef) {
_navigator = navigatorRef;
}
......@@ -19,24 +18,17 @@ function getState() {
}
function getCurrentState() {
return getStateFrom(_navigator.state.nav);
const root = _navigator.getRootState();
return getStateFrom(root);
}
function navigate(routeName, params) {
_navigator.dispatch(
NavigationActions.navigate({
routeName,
params,
})
);
function navigate(...args) {
_navigator.navigate(...args);
}
function push(routeName, params) {
function push(...args) {
_navigator.dispatch(
StackActions.push({
routeName,
params,
})
StackActions.push(...args)
);
}
......@@ -58,6 +50,10 @@ function reset(routeName, params) {
_navigator.dispatch(resetAction);
}
function addListener(name, fn) {
return _navigator.addListener(name,fn);
}
// add other navigation functions that you need and export them
export default {
......@@ -68,5 +64,6 @@ export default {
getCurrentState,
push,
setTopLevelNavigator,
goBack
goBack,
addListener,
};
\ No newline at end of file
This diff is collapsed.
......@@ -46,8 +46,11 @@ class ActivityScreen extends Component {
this.loadEntity();
}
/**
* Load entity
*/
async loadEntity() {
const params = this.props.navigation.state.params;
const params = this.props.route.params;
if (params.entity && (params.entity.guid || params.entity.entity_guid)) {
......@@ -141,6 +144,7 @@ class ActivityScreen extends Component {
store={this.comments}
navigation={this.props.navigation}
onInputFocus={this.onFocus}
route={this.props.route}
/>
:
<View style={CS.flexColumnCentered}>
......
......@@ -31,26 +31,26 @@ import i18n from '../common/services/i18n.service';
@observer
export default class NewsfeedScreen extends Component {
static navigationOptions = {
tabBarIcon: ({ tintColor }) => (
featuresService.has('navigation-2020')
? <TabIcon name="md-home" color={tintColor} />
: <IonIcon name="md-home" size={24} color={tintColor} />
),
tabBarOnPress: ({ navigation, defaultHandler }) => {
// tab button tapped again?
if (navigation.isFocused()) {
if (stores.newsfeed.filter == 'subscribed') {
stores.newsfeed.scrollToTop();
stores.newsfeed.feedStore.refresh(true)
} else {
stores.newsfeed.refresh();
}
return;
}
defaultHandler();
}
}
// static navigationOptions = {
// tabBarIcon: ({ tintColor }) => (
// featuresService.has('navigation-2020')
// ? <TabIcon name="md-home" color={tintColor} />
// : <IonIcon name="md-home" size={24} color={tintColor} />
// ),
// tabBarOnPress: ({ navigation, defaultHandler }) => {
// // tab button tapped again?
// if (navigation.isFocused()) {
// if (stores.newsfeed.filter == 'subscribed') {
// stores.newsfeed.scrollToTop();
// stores.newsfeed.feedStore.refresh(true)
// } else {
// stores.newsfeed.refresh();
// }
// return;
// }
// defaultHandler();
// }
// }
/**
* Nav to activity full screen
......@@ -63,6 +63,7 @@ export default class NewsfeedScreen extends Component {
* Load data on mount
*/
componentDidMount() {
this.loadFeed();
// this.props.newsfeed.loadBoosts();
......@@ -84,6 +85,7 @@ export default class NewsfeedScreen extends Component {
// load groups after the feed
await this.groupsBar.wrappedInstance.initialLoad();
// load discovery after the feed is loaded
this.props.discovery.init();
this.props.discovery.fetch();
}
......@@ -92,7 +94,7 @@ export default class NewsfeedScreen extends Component {
*/
componentWillUnmount() {
if (this.disposeEnter) {
this.disposeEnter.remove();
this.disposeEnter();
}
}
......
import React, {
PureComponent
useCallback
} from 'react';
import {
......@@ -12,6 +12,7 @@ import Counter from './Counter';
import withPreventDoubleTap from '../../../common/components/PreventDoubleTap';
import testID from '../../../common/helpers/testID';
import { FLAG_REMIND } from '../../../common/Permissions';
import { useRoute, useNavigation } from '@react-navigation/native';
// prevent double tap in touchable
const TouchableOpacityCustom = withPreventDoubleTap(TouchableOpacity);
......@@ -19,44 +20,38 @@ const TouchableOpacityCustom = withPreventDoubleTap(TouchableOpacity);
/**
* Remind Action Component
*/
export default class RemindAction extends PureComponent {
export default function({ entity, size = 20, vertical = false }) {
const color = entity.can(FLAG_REMIND)
? entity.reminds > 0
? CS.colorPrimary
: CS.colorAction
: CS.colorLightGreyed;
static defaultProps = {
size: 20,
};
/**
* Render
*/
render() {
const canRemind = this.props.entity.can(FLAG_REMIND);
const color = canRemind ? (this.props.entity['reminds'] > 0 ? CS.colorPrimary : CS.colorAction) : CS.colorLightGreyed;
return (
<TouchableOpacityCustom
style={[CS.flexContainer, CS.centered, this.props.vertical === true ? CS.columnAlignCenter : CS.rowJustifyCenter]}
onPress={this.remind}
{...testID('Remind activity button')}
>
<Icon style={[color, CS.marginRight]} name='repeat' size={this.props.size} />
<Counter count={this.props.entity['reminds']} size={this.props.size * 0.70} />
</TouchableOpacityCustom>
)
}
const route = useRoute();
const navigation = useNavigation();
/**
* Open remind
*/
remind = () => {
const remind = useCallback(() => {
// check permission and show alert
if (!this.props.entity.can(FLAG_REMIND, true)) return;
const { state } = this.props.navigation
this.props.navigation.push('Capture', {isRemind: true, entity: this.props.entity, parentKey: state.key});
}
if (!entity.can(FLAG_REMIND, true)) return;
const { key } = route;
navigation.push('Capture', {isRemind: true, entity, parentKey: key});
}, [route, entity, navigation]);
return (
<TouchableOpacityCustom
style={[
CS.flexContainer,
CS.centered,
vertical === true ? CS.columnAlignCenter : CS.rowJustifyCenter,
]}
onPress={remind}
{...testID('Remind activity button')}>
<Icon style={[color, CS.marginRight]} name='repeat' size={size} />
<Counter count={entity['reminds']} size={size * 0.70} />
</TouchableOpacityCustom>
);
}
......@@ -89,7 +89,7 @@ export default class NotificationsScreen extends Component {
// clear data to free memory
this.props.notifications.list.clearList();
if (this.disposeEnter) {
this.disposeEnter.remove();
this.disposeEnter();
}
}
......
......@@ -22,9 +22,10 @@ export default class NotificationIcon extends Component {
*/
render() {
const tintColor = this.props.tintColor;
const size = this.props.size || 24;
return (
<View style={styles.container}>
<CIcon name="bell" size={24} color={tintColor} />
<CIcon name="bell" size={size} color={tintColor} />
{ this.props.notifications.unread ? <FAIcon name="circle" size={10} color='#E02020' style={styles.unread} /> : null}
</View>
);
......
......@@ -40,10 +40,10 @@ export default
@observer
class SettingsScreen extends Component {
static navigationOptions = {
title: 'Settings',
leftHandedInitial: false,
};
// static navigationOptions = {
// title: 'Settings',
// leftHandedInitial: false,
// };
state = {
showLanguages: false,
......@@ -158,8 +158,6 @@ class SettingsScreen extends Component {
icon: (<Icon name='power-settings-new' size={ICON_SIZE} style={[styles.icon, CS.colorPrimaryText]} />),
onPress: () => {
authService.logout();
this.props.navigation.navigate( 'Login');
}
},
{
......
......@@ -55,7 +55,6 @@ class SettingsService {
try {
await api.delete('api/v1/channel');
await sessionService.logout();
navigationService.navigate('Login');
} catch (e) {
Alert.alert('Error disabling the channel');
}
......@@ -69,7 +68,6 @@ class SettingsService {
try {
await api.post('api/v2/settings/delete', { password });
await sessionService.logout();
navigationService.navigate('Login');
} catch (e) {
Alert.alert('Error deleting the channel');
}
......
......@@ -51,8 +51,7 @@ class SettingsStore {
appStore.hashtag.setAll(!this.useHashtags);
// theme
ThemedStyles.theme = data[5][1] || 0;
ThemedStyles.init();
ThemedStyles.setTheme(data[5][1] || 0);
return this;
}
......
......@@ -2,6 +2,7 @@ import { StyleSheet } from 'react-native';
import { observable, action, reaction } from 'mobx';
import { DARK_THEME, LIGHT_THEME } from './Colors';
import { DefaultTheme, DarkTheme } from '@react-navigation/native';
const repetitions = 8;
const step = 5;
......@@ -41,6 +42,9 @@ class ThemedStylesStore {
*/
@observable theme = -1;
navTheme = null;
defaultScreenOptions = null;
/**
* Style
*/
......@@ -54,18 +58,38 @@ class ThemedStylesStore {
this.generateStyle();
}
/**
* Set dark theme
*/
@action
setDark() {
this.theme = 1;
this.generateStyle();
}
/**
* Set light theme
*/
@action
setLight() {
this.theme = 0;
this.generateStyle();
}
/**
* Set theme
* @param {number} value
*/
@action
setTheme(value) {
this.theme = value;
this.generateStyle();
}
/**
* On theme change reaction
* @param {Function} fn
*/
onThemeChange(fn) {
return reaction(() => [this.theme], async args => await fn(...args), {
fireImmediately: false,
......@@ -74,7 +98,7 @@ class ThemedStylesStore {
/**
* Get color of theme based on property
* @param {String} prop
* @param {String} prop
*/
getColor(prop) {
const theme = this.theme ? DARK_THEME : LIGHT_THEME;
......@@ -88,6 +112,25 @@ class ThemedStylesStore {
const theme = this.theme ? DARK_THEME : LIGHT_THEME;
const baseTheme = this.theme === 0 ? DefaultTheme : DarkTheme;
this.navTheme = {
...baseTheme,
colors: {
...baseTheme.colors,
background: 'transparent',
// card: theme.backgroundSecondary, // generates an error on ios
text: theme.primary_text,
primary: theme.icon
},
};
this.defaultScreenOptions = {
headerStyle: {
backgroundColor: theme.secondary_background,
},
};
this.style = StyleSheet.create({
...dynamicStyles,
// containers
......
......@@ -99,7 +99,6 @@ export default class MoreScreen extends Component {
icon: (<Icon name='power-settings-new' size={ICON_SIZE} style={ styles.icon } />),
onPress: () => {
authService.logout();
this.props.navigation.navigate('Login');
}
}
];
......
......@@ -38,19 +38,12 @@ import ThemedStyles from '../styles/ThemedStyles';
const ICON_SIZE = 24;
/**
* More screen, new design (menu)
*/
* More screen, new design (menu)
*/
export default
@inject('user')
class MoreScreenNew extends Component {
static navigationOptions = {
title: 'Minds',
tabBarIcon: ({ tintColor }) => (
<TabIcon name="md-menu" size={24} color={tintColor} />
),
};
navToChannel = () => this.props.navigation.push('Channel', { guid: this.props.user.me.guid })
/**
......@@ -125,7 +118,6 @@ class MoreScreenNew extends Component {
icon: (<Icon name='power-settings-new' size={ICON_SIZE} style={ CS.colorIcon } />),
onPress: () => {
authService.logout();
this.props.navigation.navigate('Login');
}
}
];
......@@ -133,23 +125,36 @@ class MoreScreenNew extends Component {
return list;
}
/**
* Recieve a list a return a view container with a list of items
* @param {Array} list
*/
renderList = list => {
render() {
const avatar = this.getAvatar(),
channel = this.props.user.me;
const CS = ThemedStyles.style;
return (
<ScrollView
<SafeAreaView style={[
CS.flexContainer,
CS.backgroundPrimary,
]}>
<ScrollView
style={[
styles.container,
CS.flexContainer,
CS.backgroundPrimary,
CS.marginTop4x,
CS.marginTop11x,
]}
>
<View style={styles.headerContainer} >
<TouchableOpacity onPress={this.navToChannel}>
<Image source={avatar} style={styles.wrappedAvatar}/>
</TouchableOpacity>
<Text style={[CS.titleText, CS.colorPrimaryText, CS.marginTop2x]}>{channel.name}</Text>
<Text style={[CS.subTitleText, CS.colorSecondaryText, CS.fontNormal]}>@{channel.username}</Text>
<Text style={[CS.subTitleText, CS.colorSecondaryText, CS.fontNormal, CS.marginTop3x]}>
{`${abbrev(channel.subscribers_count, 0)} ${i18n.t('subscribers')} · ${abbrev(channel.subscriptions_count, 0)} ${i18n.t('subscriptions')}`}
</Text>
</View>
{
list.map((l, i) => (
this.getOptionsList().map((l, i) => (
<ListItem
key={i}
title={l.name}
......@@ -165,35 +170,7 @@ class MoreScreenNew extends Component {
))
}
</ScrollView>
)
}
render() {
const avatar = this.getAvatar(),
channel = this.props.user.me;
const CS = ThemedStyles.style;
return (
<SafeAreaView style={[
CS.flexContainer,
CS.backgroundPrimary,
]}>
{/* CHANNEL DATA */}
<View style={styles.headerContainer} >
<TouchableOpacity onPress={this.navToChannel}>
<Image source={avatar} style={styles.wrappedAvatar}/>
</TouchableOpacity>
<Text style={[CS.titleText, CS.colorPrimaryText, CS.marginTop2x]}>{channel.name}</Text>
<Text style={[CS.subTitleText, CS.colorSecondaryText, CS.fontNormal]}>@{channel.username}</Text>
<Text style={[CS.subTitleText, CS.colorSecondaryText, CS.fontNormal, CS.marginTop3x]}>
{`${abbrev(channel.subscribers_count, 0)} ${i18n.t('subscribers')} · ${abbrev(channel.subscriptions_count, 0)} ${i18n.t('subscriptions')}`}
</Text>
</View>
{/* MENU */}
{this.renderList(this.getOptionsList())}
</SafeAreaView>
);
}
......
import React, {Component} from 'react';
import IonIcon from 'react-native-vector-icons/Ionicons';
import FAIcon from 'react-native-vector-icons/FontAwesome';
import EvilIcons from 'react-native-vector-icons/EvilIcons';
import Fontisto from 'react-native-vector-icons/Fontisto';
import Entypo from 'react-native-vector-icons/Entypo';
import { CommonStyle as CS } from '../styles/Common';
export default class TabIcon extends Component {
......@@ -9,8 +11,22 @@ export default class TabIcon extends Component {
const {name, size, color} = this.props;
let icon;
switch (name) {
case 'md-add-circle-outline':
case 'md-home':
case 'plus':
return (
<EvilIcons
name={name}
style={color ? {color: color} : CS.colorIcon}
size={size ? size : 24}
/>
)
case 'home':
return (
<Entypo
name={name}
style={color ? {color: color} : CS.colorIcon}
size={size ? size : 24}
/>
)
case 'md-notifications':
case 'md-menu':
icon = (
......@@ -23,7 +39,7 @@ export default class TabIcon extends Component {
break;
case 'hashtag':
icon = (
<FAIcon
<Fontisto
name={name}
style={color ? {color: color} : CS.colorIcon}
size={size ? size : 24}
......
import React, {
Component
} from 'react';
import React, { useCallback } from 'react';
import { createMaterialTopTabNavigator } from 'react-navigation-tabs';
import {
jumpTo,
SafeAreaView
} from 'react-navigation';
import {
Platform,
Dimensions,
} from 'react-native';
const { height, width } = Dimensions.get('window');
const aspectRatio = height/width;
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
import { View, Platform, TouchableOpacity } from 'react-native';
import NewsfeedScreen from '../newsfeed/NewsfeedScreen';
import NotificationsScreen from '../notifications/NotificationsScreen';
import DiscoveryScreen from '../discovery/DiscoveryScreen';
import featuresService from '../common/services/features.service';
import { withErrorBoundaryScreen } from '../common/components/ErrorBoundary';
import isIphoneX from '../common/helpers/isIphoneX';
import CapturePoster from '../capture/CapturePoster';
import TopbarNew from '../topbar/TopbarNew';
import MoreScreenNew from './MoreScreenNew';
import ThemedStyles from '../styles/ThemedStyles';
import TabIcon from './TabIcon';
import NotificationIcon from '../notifications/NotificationsTabIcon';
import AppStores from '../../AppStores';
import { MINDS_CDN_URI } from '../config/Config';
import { Avatar } from 'react-native-elements';
let screens = {
/**
* Main tabs
* @param {Object} props
*/
const Tabs = function({navigation}) {
const isIOS = Platform.OS === 'ios';
Newsfeed: {
screen: withErrorBoundaryScreen(NewsfeedScreen),
navigationOptions: {
tabBarTestID:'Newsfeed tab button',
tabBarAccessibilityLabel: 'Newsfeed tab button',
},
},
Discovery: {
screen: withErrorBoundaryScreen(DiscoveryScreen),
navigationOptions: {
tabBarTestID:'Discovery tab button',
tabBarAccessibilityLabel: 'Discovery tab button',
},
},
Capture: {
screen: withErrorBoundaryScreen(CapturePoster),
navigationOptions: {
tabBarTestID:'Capture tab button',
tabBarAccessibilityLabel: 'Capture tab button',
},
},
Notifications: {
screen: withErrorBoundaryScreen(NotificationsScreen),
navigationOptions: {
tabBarTestID:'Notifications tab button',
tabBarAccessibilityLabel: 'Notifications tab button',
},
},
Menu: {
screen: withErrorBoundaryScreen(MoreScreenNew),
navigationOptions: {
tabBarTestID:'Menu tab button',
tabBarAccessibilityLabel: 'Menu tab button',
},
},
};
const navToCapture = useCallback(() => navigation.push('Capture'), [
navigation,
]);
return (
<Tab.Navigator
initialRouteName="Newsfeed"
tabBarOptions={{
showLabel: false,
showIcon: true,
activeTintColor: ThemedStyles.getColor('link'),
inactiveTintColor: ThemedStyles.getColor('icon'),
style: {
borderTopWidth: 0,
backgroundColor: ThemedStyles.getColor('secondary_background'),
height: isIOS ? 90 : 65,
paddingTop: isIOS ? 20 : 2,
},
tabStyle: {
height: 66,
width: 66,
...ThemedStyles.style.centered,
},
}}
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName,
iconsize = 28;
switch (route.name) {
case 'Menu':
return (
<View>
{focused && <View style={[styles.acitivity]} />}
<Avatar
rounded
source={{
uri:
MINDS_CDN_URI +
'icon/' +
AppStores.user.me.guid +
'/medium/' +
AppStores.user.me.icontime,
}}
width={34}
height={34}
testID="AvatarButton"
/>
</View>
);
break;
case 'Newsfeed':
iconName = 'home';
iconsize = 33;
break;
case 'Discovery':
iconName = 'hashtag';
break;
case 'Notifications':
return <NotificationIcon tintColor={color} size={iconsize} />;
case 'Capture':
iconName = 'plus';
iconsize = 66;
break;
}
const Tabs = (
createMaterialTopTabNavigator(screens, {
tabBarPosition: 'bottom',
animationEnabled: false,
swipeEnabled: true,
lazy: false,
removeClippedSubviews: false,
tabBarOptions: {
showLabel: false,
showIcon: true,
activeTintColor: '#0091FF',
inactiveTintColor: '#777777',
style: {
backgroundColor: ThemedStyles.getColor('secondary_background'),
height: 70,
},
indicatorStyle: {
marginBottom: isIphoneX ? 10 : null,
backgroundColor: 'transparent'
},
iconStyle: {
height: 44,
width: 44,
...ThemedStyles.style.centered,
}
},
initialRouteName: 'Newsfeed',
navigationOptions: {
header: null,
}
})
);
// You can return any component that you like here!
return <TabIcon name={iconName} size={iconsize} color={color} />;
},
})}>
<Tab.Screen
name="Newsfeed"
component={NewsfeedScreen}
options={{ tabBarTestID: 'Menu tab button', headerShown: false }}
/>
<Tab.Screen
name="Discovery"
component={DiscoveryScreen}
options={{ tabBarTestID: 'Discovery tab button' }}
/>
<Tab.Screen
name="Capture"
component={View}
options={{
tabBarTestID: 'Capture tab button',
tabBarButton: props => (
<TouchableOpacity {...props} onPress={navToCapture} />
),
}}
/>
<Tab.Screen
name="Notifications"
component={NotificationsScreen}
options={{ tabBarTestID: 'Notifications tab button' }}
/>
<Tab.Screen
name="Menu"
component={MoreScreenNew}
options={{ tabBarTestID: 'Menu tab button' }}
/>
</Tab.Navigator>
);
};
const inset = { bottom: 'always', top: 'never' };
const styles = {
acitivity: {
zIndex: 9990,
top: -5,
left: -5,
right: -5,
bottom: -5,
borderWidth: 2.5,
borderRadius: 35,
position: 'absolute',
borderColor: colors.primary,
},
};
export default Tabs;
......@@ -16,15 +16,15 @@ import { Avatar } from 'react-native-elements';
import { MINDS_CDN_URI } from '../config/Config';
import featuresService from '../common/services/features.service';
import { SafeAreaView } from 'react-navigation';
import isIphoneX from '../common/helpers/isIphoneX';
import testID from '../common/helpers/testID';
import SearchComponent from './SearchComponent';
import navigation from '../navigation/NavigationService';
import ThemedStyles from '../styles/ThemedStyles';
import { SafeAreaConsumer } from 'react-native-safe-area-context';
const forceInset = isIphoneX ? {top: 32} : null
const forceInset = isIphoneX ? {top: 10} : null
@inject('user')
@inject('wallet')
......@@ -46,60 +46,59 @@ export default class TopbarNew extends Component {
const user = this.props.user;
return (
<SafeAreaView style={[styles.container, CS.backgroundSecondary]} forceInset={forceInset}>
<View style={styles.topbar}>
<View style={[styles.topbarLeft, CS.marginLeft2x]}>
<Text style={[CS.titleText, CS.colorPrimaryText, styles.lineHeight0]} >{this.props.title}</Text>
<SafeAreaConsumer>
{insets => (
<View style={[styles.container, CS.backgroundSecondary, {paddingTop: insets.top}]}>
<View style={styles.topbar}>
<View style={[styles.topbarLeft, CS.marginLeft4x]}>
<Text style={[CS.titleText, CS.colorPrimaryText, styles.lineHeight0]} >{this.props.title}</Text>
</View>
<View style={styles.topbarRight}>
<Icon name="chat-bubble-outline" size={24} style={[styles.button, CS.colorIcon]}/>
<SearchComponent user={this.props.user} navigation={navigation} />
</View>
</View>
<View style={styles.topbarRight}>
<Icon name="chat-bubble-outline" size={24} style={[styles.button, CS.colorIcon]}/>
<SearchComponent user={this.props.user} navigation={navigation} />
</View>
</View>
</SafeAreaView>
</View>
)}
</SafeAreaConsumer>
);
}
}
let topbarHeight = 56;
let topbarHeight = 50;
let topMargin = 0;
if (Platform.OS == 'ios') {
topbarHeight = 56;
topbarHeight = 80;
}
const styles = StyleSheet.create({
lineHeight0: {
lineHeight:0,
lineHeight: 28,
},
container: {
height: topbarHeight,
display: 'flex',
flexDirection: 'row',
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: '#EEE',
paddingBottom: 8,
},
topbar: {
flex: 1,
alignItems: 'flex-end',
flexDirection: 'row',
paddingBottom: 5,
},
topbarLeft: {
alignItems: 'flex-end',
justifyContent: 'flex-end',
flexDirection: 'row'
},
topbarCenter: {
flex: 1,
alignItems: 'center',
padding: 2,
},
topbarRight: {
flex: 1,
justifyContent: 'flex-end',
flexDirection: 'row',
paddingRight: 4,
marginRight: 5,
paddingTop: 4,
},
button: {
......
......@@ -44,7 +44,7 @@ export default class WalletBalanceTokens extends Component {
// clear data to free memory
this.wallet.ledger.list.clearList();
if (this.disposeEnter) {
this.disposeEnter.remove();
this.disposeEnter();
}
}
......
......@@ -69,7 +69,7 @@ export default class FabScreen extends Component {
}
async loadUserAndSetDefaults() {
const params = this.props.navigation.state.params;
const params = this.props.route.params;
// if there is no default data we reset the store
if (!params || !params.default) {
......
This diff is collapsed.