Merge branch 'development' into nt/use-query-notifications

# Conflicts:
#	src/providers/ecency/ecency.ts
This commit is contained in:
Nouman Tahir 2022-09-26 15:27:18 +05:00
commit 31d9a45016
18 changed files with 291 additions and 252 deletions

View File

@ -25,16 +25,8 @@ class ContainerHeaderView extends PureComponent {
// Component Functions
render() {
const {
color,
defaultTitle,
fontSize,
hasSeperator,
iconName,
isBoldTitle,
title,
isCenter,
} = this.props;
const { color, defaultTitle, fontSize, hasSeperator, iconName, isBoldTitle, title, isCenter } =
this.props;
return (
<View style={[styles.wrapper, hasSeperator && styles.hasTopBorder]}>

View File

@ -37,16 +37,8 @@ class MainButton extends Component {
};
_getBody = () => {
const {
isLoading,
text,
secondText,
iconColor,
iconName,
source,
iconType,
textStyle,
} = this.props;
const { isLoading, text, secondText, iconColor, iconName, source, iconType, textStyle } =
this.props;
if (isLoading) {
this._getIndicator();

View File

@ -56,6 +56,7 @@ const NotificationLineView = ({
if (
notification.type === 'vote' ||
notification.type === 'reblog' ||
notification.type === 'favorites' ||
(notification.type === 'mention' && notification.post)
) {
_moreinfo = notification.title || notification.permlink;

View File

@ -1,4 +1,4 @@
import React, { memo } from 'react';
import React, { memo, useMemo } from 'react';
import RenderHTML, { CustomRendererProps, Element, TNode } from 'react-native-render-html';
import styles from './postHtmlRendererStyles';
import { LinkData, parseLinkData } from './linkDataParser';
@ -152,22 +152,22 @@ export const PostHtmlRenderer = memo(
onElementIsImage(imgUrl);
}
//this avoids invalid rendering of first element of table pushing rest of columsn to extreme right.
if(element.tagName === 'table'){
if (element.tagName === 'table') {
console.log('table detected')
element.children.forEach((child)=>{
if(child.name === 'tr'){
element.children.forEach((child) => {
if (child.name === 'tr') {
let headerIndex = -1;
let colIndex = -1;
child.children.forEach((gChild, index) => {
//check if element of row in table is not a column while it's other siblings are columns
if(gChild.type === 'tag'){
if(gChild.name !== 'td' && headerIndex === -1){
if (gChild.type === 'tag') {
if (gChild.name !== 'td' && headerIndex === -1) {
headerIndex = index;
}else if(colIndex === -1){
} else if (colIndex === -1) {
colIndex = index
}
}
@ -175,7 +175,7 @@ export const PostHtmlRenderer = memo(
//if row contans a header with column siblings
//remove first child and place it as first separate row in table
if(headerIndex !== -1 && colIndex !== -1 && headerIndex < colIndex){
if (headerIndex !== -1 && colIndex !== -1 && headerIndex < colIndex) {
console.log("time to do some switching", headerIndex, colIndex);
const header = child.children[headerIndex];
const headerRow = new Element('tr', {}, [header]);
@ -286,7 +286,7 @@ export const PostHtmlRenderer = memo(
// const tableProps = useHtmlTableProps(props);
let maxColumns = 0;
props.tnode.children.forEach((child)=>
props.tnode.children.forEach((child) =>
maxColumns = child.children.length > maxColumns ? child.children.length : maxColumns
)
@ -328,56 +328,99 @@ export const PostHtmlRenderer = memo(
};
return (
<RenderHTML
source={{ html: body }}
contentWidth={contentWidth}
baseStyle={{ ...styles.baseStyle, width: contentWidth }}
classesStyles={{
const tagsStyles = useMemo(
() => ({
a: styles.a,
img: styles.img,
table: styles.table,
tr: { ...styles.tr, width: contentWidth }, //center tag causes tr to have 0 width if not exclusivly set, contentWidth help avoid that
th: { ...styles.th, minWidth: _minTableColWidth },
td: { ...styles.td, minWidth: _minTableColWidth },
div: { ...styles.div, maxWidth: contentWidth }, //makes sure width covers the available horizontal space for view and not exceed the contentWidth if parent bound id not defined
blockquote: styles.blockquote,
code: styles.code,
li: styles.li,
p: styles.p,
h6: styles.h6
}),
[contentWidth]
);
const baseStyle = useMemo(
() => (
{ ...styles.baseStyle, width: contentWidth }
),
[contentWidth]
);
const classesStyles = useMemo(
() => (
{
phishy: styles.phishy,
'text-justify': styles.textJustify,
'text-center': styles.textCenter,
}}
tagsStyles={{
body: styles.body,
a: styles.a,
img: styles.img,
table: styles.table,
tr: { ...styles.tr, width: contentWidth }, //center tag causes tr to have 0 width if not exclusivly set, contentWidth help avoid that
th: { ...styles.th, minWidth: _minTableColWidth },
td: { ...styles.td, minWidth: _minTableColWidth },
div: { ...styles.div, maxWidth: contentWidth }, //makes sure width covers the available horizontal space for view and not exceed the contentWidth if parent bound id not defined
blockquote: styles.blockquote,
code: styles.code,
li: styles.li,
p: styles.p,
h6: styles.h6
}}
domVisitors={{
onElement: _onElement,
}}
renderers={{
}
),
[],
);
const renderers = useMemo(
() => (
{
img: _imageRenderer,
a: _anchorRenderer,
p: _paraRenderer,
iframe: _iframeRenderer,
table: _tableRenderer
}}
} as any
),
[],
);
const domVisitors = useMemo(
() => (
{
onElement: _onElement,
}
),
[],
);
const customHTMLElementModels = useMemo(
() => (
{
iframe: iframeModel,
}
),
[],
);
const renderersProps = useMemo(
() => (
{
iframe: {
scalesPageToFit: true
},
}
),
[],
);
return (
<RenderHTML
source={{ html: body }}
contentWidth={contentWidth}
baseStyle={baseStyle}
classesStyles={classesStyles}
tagsStyles={tagsStyles}
domVisitors={domVisitors}
renderers={renderers}
onHTMLLoaded={onLoaded && onLoaded}
defaultTextProps={{
selectable: true,
}}
customHTMLElementModels={{
iframe: iframeModel,
}}
renderersProps={{
iframe: {
scalesPageToFit: true,
webViewProps: {
/* Any prop you want to pass to iframe WebViews */
},
},
}}
customHTMLElementModels={customHTMLElementModels}
renderersProps={renderersProps}
WebView={WebView}
/>
);

View File

@ -56,13 +56,8 @@ class TabBar extends PureComponent {
};
_renderUnderline = () => {
const {
tabs,
tabUnderlineDefaultWidth,
tabUnderlineScaleX,
scrollValue,
underlineStyle,
} = this.props;
const { tabs, tabUnderlineDefaultWidth, tabUnderlineScaleX, scrollValue, underlineStyle } =
this.props;
const { activeColor } = this.state;
const containerWidth = getWindowDimensions().nativeWidth;

View File

@ -141,6 +141,7 @@
"unvote": "downvoted",
"reply": "replied to",
"mention": "mentioned in",
"favorites": "made new post",
"follow": "followed you",
"unfollow": "unfollowed you",
"ignore": "ignored you",
@ -227,6 +228,7 @@
"vote": "Vote",
"comment": "Comment",
"mention": "Mention",
"favorite": "Favorites",
"reblog": "Reblog",
"transfers": "Transfers",
"delegations": "Delegations"

View File

@ -416,6 +416,9 @@ export const setNotificationSettings = async ({ type, action }) => {
case 'notification.mention':
setting.mentionNotification = action;
break;
case 'notification.favorite':
setting.favoriteNotification = action;
break;
case 'notification.reblog':
setting.reblogNotification = action;
break;
@ -524,6 +527,7 @@ export const getSettings = async () => {
voteNotification: true,
commentNotification: true,
mentionNotification: true,
favoriteNotification: true,
reblogNotification: true,
transfersNotification: true,
isPinCodeOpen: false,

View File

@ -4,6 +4,7 @@ import {
CHANGE_COMMENT_NOTIFICATION,
CHANGE_FOLLOW_NOTIFICATION,
CHANGE_MENTION_NOTIFICATION,
CHANGE_FAVORITE_NOTIFICATION,
CHANGE_REBLOG_NOTIFICATION,
CHANGE_TRANSFERS_NOTIFICATION,
CHANGE_ALL_NOTIFICATION_SETTINGS,
@ -31,7 +32,7 @@ import {
SET_IS_BIOMETRIC_ENABLED,
SET_ENC_UNLOCK_PIN,
SET_POST_UPVOTE_PERCENT,
SET_COMMENT_UPVOTE_PERCENT
SET_COMMENT_UPVOTE_PERCENT,
} from '../constants/constants';
export const login = (payload) => ({
@ -51,9 +52,6 @@ export const isLoginDone = () => ({
type: IS_LOGIN_DONE,
});
// Settings actions
export const setLanguage = (payload) => ({
payload,
@ -65,7 +63,6 @@ export const setApi = (payload) => ({
type: SET_API,
});
export const setPostUpvotePercent = (payload) => ({
payload,
type: SET_POST_UPVOTE_PERCENT,
@ -107,6 +104,12 @@ export const changeNotificationSettings = (payload) => {
type: CHANGE_MENTION_NOTIFICATION,
};
case 'notification.favorite':
return {
payload: payload.action,
type: CHANGE_FAVORITE_NOTIFICATION,
};
case 'notification.reblog':
return {
payload: payload.action,
@ -135,10 +138,10 @@ export const isDarkTheme = (payload) => ({
type: IS_DARK_THEME,
});
export const setColorTheme = (payload:number) => ({
export const setColorTheme = (payload: number) => ({
payload,
type: SET_COLOR_THEME
})
type: SET_COLOR_THEME,
});
export const isPinCodeOpen = (payload) => ({
payload,
@ -166,11 +169,11 @@ export const isDefaultFooter = (payload) => ({
export const setCurrency = (currency) => async (dispatch) => {
const currencySymbol = getSymbolFromCurrency(currency);
const currencyRate = await getCurrencyRate(currency)
const currencyRate = await getCurrencyRate(currency);
dispatch({
type: SET_CURRENCY,
payload: { currency, currencyRate, currencySymbol },
})
});
};
export const setPinCode = (data) => ({
@ -183,34 +186,32 @@ export const isRenderRequired = (payload) => ({
type: IS_RENDER_REQUIRED,
});
export const setLastAppVersion = (versionNumber:string) => ({
payload:versionNumber,
type: SET_LAST_APP_VERSION
})
export const setLastAppVersion = (versionNumber: string) => ({
payload: versionNumber,
type: SET_LAST_APP_VERSION,
});
export const setSettingsMigrated = (isMigrated:boolean) => ({
payload:isMigrated,
type: SET_SETTINGS_MIGRATED
})
export const setSettingsMigrated = (isMigrated: boolean) => ({
payload: isMigrated,
type: SET_SETTINGS_MIGRATED,
});
export const setHidePostsThumbnails = (shouldHide:boolean) => ({
payload:shouldHide,
export const setHidePostsThumbnails = (shouldHide: boolean) => ({
payload: shouldHide,
type: HIDE_POSTS_THUMBNAILS,
});
export const setIsTermsAccepted = (isTermsAccepted:boolean) => ({
payload:isTermsAccepted,
type: SET_TERMS_ACCEPTED
})
export const setIsBiometricEnabled = (enabled:boolean) => ({
payload:enabled,
type: SET_IS_BIOMETRIC_ENABLED
})
export const setEncryptedUnlockPin = (encryptedUnlockPin:string) => ({
payload:encryptedUnlockPin,
type: SET_ENC_UNLOCK_PIN
})
export const setIsTermsAccepted = (isTermsAccepted: boolean) => ({
payload: isTermsAccepted,
type: SET_TERMS_ACCEPTED,
});
export const setIsBiometricEnabled = (enabled: boolean) => ({
payload: enabled,
type: SET_IS_BIOMETRIC_ENABLED,
});
export const setEncryptedUnlockPin = (encryptedUnlockPin: string) => ({
payload: encryptedUnlockPin,
type: SET_ENC_UNLOCK_PIN,
});

View File

@ -27,6 +27,7 @@ export const CHANGE_FOLLOW_NOTIFICATION = 'CHANGE_FOLLOW_NOTIFICATION';
export const CHANGE_VOTE_NOTIFICATION = 'CHANGE_VOTE_NOTIFICATION';
export const CHANGE_COMMENT_NOTIFICATION = 'CHANGE_COMMENT_NOTIFICATION';
export const CHANGE_MENTION_NOTIFICATION = 'CHANGE_MENTION_NOTIFICATION';
export const CHANGE_FAVORITE_NOTIFICATION = 'CHANGE_FAVORITE_NOTIFICATION';
export const CHANGE_REBLOG_NOTIFICATION = 'CHANGE_REBLOG_NOTIFICATION';
export const CHANGE_TRANSFERS_NOTIFICATION = 'CHANGE_TRANSFERS_NOTIFICATION';
export const CHANGE_ALL_NOTIFICATION_SETTINGS = 'CHANGE_ALL_NOTIFICATION_SETTINGS';

View File

@ -2,6 +2,7 @@ import {
CHANGE_COMMENT_NOTIFICATION,
CHANGE_FOLLOW_NOTIFICATION,
CHANGE_MENTION_NOTIFICATION,
CHANGE_FAVORITE_NOTIFICATION,
CHANGE_REBLOG_NOTIFICATION,
CHANGE_TRANSFERS_NOTIFICATION,
CHANGE_VOTE_NOTIFICATION,
@ -29,17 +30,17 @@ import {
HIDE_POSTS_THUMBNAILS,
SET_TERMS_ACCEPTED,
SET_IS_BIOMETRIC_ENABLED,
SET_ENC_UNLOCK_PIN
SET_ENC_UNLOCK_PIN,
} from '../constants/constants';
interface State {
api: string;
currency: {
currency: string,
currencyRate: number,
currencySymbol: string,
},
isConnected: boolean|null, // internet connectivity
currency: string;
currencyRate: number;
currencySymbol: string;
};
isConnected: boolean | null; // internet connectivity
isDarkTheme: boolean;
colorTheme: number;
isDefaultFooter: boolean; //TODO: remove present of isDefaultFooter as it's no longer in use
@ -47,31 +48,32 @@ interface State {
isLoginDone: boolean;
isLogingOut: boolean;
isNotificationOpen: boolean;
language: string,
language: string;
loading: boolean; // It is lock to all screen and shows loading animation.
notificationDetails: {
commentNotification: boolean,
followNotification: boolean,
mentionNotification: boolean,
reblogNotification: boolean,
transfersNotification: boolean,
voteNotification: boolean,
},
commentNotification: boolean;
followNotification: boolean;
mentionNotification: boolean;
favoriteNotification: boolean;
reblogNotification: boolean;
transfersNotification: boolean;
voteNotification: boolean;
};
postUpvotePercent: number;
commentUpvotePercent: number;
nsfw: string;
pin: string|null; //encrypted pin used for encrypting sensitive user data
pin: string | null; //encrypted pin used for encrypting sensitive user data
isPinCodeOpen: boolean;
isRenderRequired: boolean;
encUnlockPin: string; //ecryped pin used for user defined lock screen pass code
lastAppVersion:string;
lastAppVersion: string;
settingsMigratedV2: boolean;
hidePostsThumbnails: boolean;
isTermsAccepted: boolean;
isBiometricEnabled: boolean;
}
const initialState:State = {
const initialState: State = {
api: 'rpc.ecency.com',
currency: {
currency: 'usd',
@ -92,6 +94,7 @@ const initialState:State = {
commentNotification: true,
followNotification: true,
mentionNotification: true,
favoriteNotification: true,
reblogNotification: true,
transfersNotification: true,
voteNotification: true,
@ -103,14 +106,14 @@ const initialState:State = {
isPinCodeOpen: false,
isRenderRequired: false,
encUnlockPin: '',
lastAppVersion:'',
lastAppVersion: '',
settingsMigratedV2: false,
hidePostsThumbnails: false,
isTermsAccepted: false,
isBiometricEnabled: false
isBiometricEnabled: false,
};
export default function (state = initialState, action):State {
export default function (state = initialState, action): State {
switch (action.type) {
case LOGIN:
return {
@ -176,6 +179,13 @@ export default function (state = initialState, action):State {
mentionNotification: action.payload,
},
});
case CHANGE_FAVORITE_NOTIFICATION:
return Object.assign({}, state, {
notificationDetails: {
...state.notificationDetails,
favoriteNotification: action.payload,
},
});
case CHANGE_REBLOG_NOTIFICATION:
return Object.assign({}, state, {
notificationDetails: {
@ -203,6 +213,7 @@ export default function (state = initialState, action):State {
notificationDetails: {
...state.notificationDetails,
mentionNotification: action.payload.mentionNotification,
favoriteNotification: action.payload.favoriteNotification,
reblogNotification: action.payload.reblogNotification,
transfersNotification: action.payload.transfersNotification,
voteNotification: action.payload.voteNotification,
@ -217,7 +228,7 @@ export default function (state = initialState, action):State {
case SET_COLOR_THEME:
return {
...state,
colorTheme:action.payload
colorTheme: action.payload,
};
case IS_PIN_CODE_OPEN:
return Object.assign({}, state, {
@ -249,42 +260,42 @@ export default function (state = initialState, action):State {
return Object.assign({}, state, {
isRenderRequired: action.payload,
});
case SET_LAST_APP_VERSION:
return {
...state,
lastAppVersion:action.payload
}
lastAppVersion: action.payload,
};
case SET_SETTINGS_MIGRATED:
return {
...state,
settingsMigratedV2:action.payload
}
settingsMigratedV2: action.payload,
};
case HIDE_POSTS_THUMBNAILS:
return {
...state,
hidePostsThumbnails:action.payload
}
hidePostsThumbnails: action.payload,
};
case SET_TERMS_ACCEPTED:
return {
...state,
isTermsAccepted:action.payload
}
isTermsAccepted: action.payload,
};
case SET_IS_BIOMETRIC_ENABLED:
return {
...state,
isBiometricEnabled:action.payload
}
isBiometricEnabled: action.payload,
};
case SET_ENC_UNLOCK_PIN:
return {
...state,
encUnlockPin:action.payload
}
encUnlockPin: action.payload,
};
default:
return state;

View File

@ -40,7 +40,7 @@ const persistConfig = {
key: 'root',
// Storage Method (React Native)
storage: AsyncStorage,
version: 0, // New version 0, default or previous version -1, versions are useful migrations
version: 1, // New version 0, default or previous version -1, versions are useful migrations
// Blacklist (Don't Save Specific Reducers)
blacklist: ['communities', 'user', 'ui'],
timeout: 0,

View File

@ -13,7 +13,7 @@ import messaging from '@react-native-firebase/messaging';
import PushNotification from 'react-native-push-notification';
import VersionNumber from 'react-native-version-number';
import ReceiveSharingIntent from 'react-native-receive-sharing-intent';
import SplashScreen from 'react-native-splash-screen'
import SplashScreen from 'react-native-splash-screen';
// Constants
import AUTH_TYPE from '../../../constants/authType';
@ -89,14 +89,12 @@ import MigrationHelpers from '../../../utils/migrationHelpers';
import { deepLinkParser } from '../../../utils/deepLinkParser';
import bugsnapInstance from '../../../config/bugsnag';
let firebaseOnNotificationOpenedAppListener = null;
let firebaseOnMessageListener = null;
let removeAppearanceListener = null;
class ApplicationContainer extends Component {
_pinCodeTimer:any = null
_pinCodeTimer: any = null;
constructor(props) {
super(props);
@ -109,7 +107,6 @@ class ApplicationContainer extends Component {
}
componentDidMount = () => {
const { dispatch } = this.props;
this._setNetworkListener();
@ -133,20 +130,19 @@ class ApplicationContainer extends Component {
this._fetchApp();
ReceiveSharingIntent.getReceivedFiles(
files => {
(files) => {
navigate({
routeName: ROUTES.SCREENS.EDITOR,
params: { hasSharedIntent: true, files },
});
// files returns as JSON Array example
//[{ filePath: null, text: null, weblink: null, mimeType: null, contentUri: null, fileName: null, extension: null }]
ReceiveSharingIntent.clearReceivedFiles(); // clear Intents
ReceiveSharingIntent.clearReceivedFiles(); // clear Intents
},
(error) => {
console.log('error :>> ', error);
},
);
};
componentDidUpdate(prevProps, prevState) {
@ -167,7 +163,6 @@ class ApplicationContainer extends Component {
}
componentWillUnmount() {
const { isPinCodeOpen: _isPinCodeOpen } = this.props;
//TOOD: listen for back press and cancel all pending api requests;
@ -225,15 +220,14 @@ class ApplicationContainer extends Component {
_handleDeepLink = async (url = '') => {
const { currentAccount, intl } = this.props;
if(!url){
if (!url) {
return;
}
try{
try {
const deepLinkData = await deepLinkParser(url, currentAccount);
const { routeName, params, key } = deepLinkData || {};
if (routeName && key) {
navigate({
routeName,
@ -241,10 +235,9 @@ class ApplicationContainer extends Component {
key: key,
});
}
} catch(err){
this._handleAlert(err.message)
} catch (err) {
this._handleAlert(err.message);
}
};
_compareAndPromptForUpdate = async () => {
@ -309,16 +302,15 @@ class ApplicationContainer extends Component {
);
};
_handleAppStateChange = (nextAppState) => {
const { isPinCodeOpen:_isPinCodeOpen } = this.props;
const { isPinCodeOpen: _isPinCodeOpen } = this.props;
const { appState } = this.state;
if (appState.match(/inactive|background/) && nextAppState === 'active') {
this._refreshGlobalProps();
if (_isPinCodeOpen && this._pinCodeTimer) {
clearTimeout(this._pinCodeTimer);
}
}
}
if (appState.match(/active|forground/) && nextAppState === 'inactive') {
@ -330,12 +322,10 @@ class ApplicationContainer extends Component {
});
};
_fetchApp = async () => {
const {dispatch, settingsMigratedV2} = this.props;
const { dispatch, settingsMigratedV2 } = this.props;
await MigrationHelpers.migrateSettings(dispatch, settingsMigratedV2)
await MigrationHelpers.migrateSettings(dispatch, settingsMigratedV2);
this._refreshGlobalProps();
await this._getUserDataFromRealm();
@ -345,15 +335,15 @@ class ApplicationContainer extends Component {
};
_startPinCodeTimer = () => {
const {isPinCodeOpen:_isPinCodeOpen} = this.props;
const { isPinCodeOpen: _isPinCodeOpen } = this.props;
if (_isPinCodeOpen) {
this._pinCodeTimer = setTimeout(() => {
navigate({
routeName:ROUTES.SCREENS.PINCODE
})
}, 1 * 60 * 1000);
this._pinCodeTimer = setTimeout(() => {
navigate({
routeName: ROUTES.SCREENS.PINCODE,
});
}, 1 * 60 * 1000);
}
};
};
_pushNavigate = (notification) => {
const { dispatch } = this.props;
@ -361,7 +351,7 @@ class ApplicationContainer extends Component {
let key = null;
let routeName = null;
if (!!notification) {
if (notification) {
const push = get(notification, 'data');
const type = get(push, 'type', '');
const fullPermlink =
@ -467,7 +457,6 @@ class ApplicationContainer extends Component {
this.setState({
foregroundNotificationData: remoteMessage,
});
});
firebaseOnNotificationOpenedAppListener = messaging().onNotificationOpenedApp(
@ -492,7 +481,6 @@ class ApplicationContainer extends Component {
}
};
_refreshGlobalProps = () => {
const { actions } = this.props;
actions.fetchGlobalProperties();
@ -556,11 +544,10 @@ class ApplicationContainer extends Component {
await switchAccount(realmObject[0].username);
}
realmObject[0].name = currentUsername;
// If in dev mode pin code does not show
if (_isPinCodeOpen) {
navigate({routeName:ROUTES.SCREENS.PINCODE})
navigate({ routeName: ROUTES.SCREENS.PINCODE });
} else if (!_isPinCodeOpen) {
const encryptedPin = encryptKey(Config.DEFAULT_PIN, Config.PIN_KEY);
dispatch(savePinCode(encryptedPin));
@ -568,7 +555,6 @@ class ApplicationContainer extends Component {
if (isConnected) {
this._fetchUserDataFromDsteem(realmObject[0]);
}
return realmObject[0];
@ -655,11 +641,10 @@ class ApplicationContainer extends Component {
}
};
//update notification settings and update push token for each signed accoutn useing access tokens
_registerDeviceForNotifications = (settings?: any) => {
const { currentAccount, otherAccounts, notificationDetails, isNotificationsEnabled } = this.props;
const { currentAccount, otherAccounts, notificationDetails, isNotificationsEnabled } =
this.props;
const isEnabled = settings ? !!settings.notification : isNotificationsEnabled;
settings = settings || notificationDetails;
@ -675,28 +660,31 @@ class ApplicationContainer extends Component {
}
this._enableNotification(account.name, isEnabled, settings, accessToken);
}
};
//updateing fcm token with settings;
otherAccounts.forEach((account) => {
//since there can be more than one accounts, process access tokens separate
if (account?.local?.accessToken) {
_enabledNotificationForAccount(account)
_enabledNotificationForAccount(account);
} else {
console.warn("access token not present, reporting to bugsnag")
bugsnapInstance.notify(new Error(`Reporting missing access token in other accounts section: account:${account.name} with local data ${JSON.stringify(account?.local)}`))
console.warn('access token not present, reporting to bugsnag');
bugsnapInstance.notify(
new Error(
`Reporting missing access token in other accounts section: account:${
account.name
} with local data ${JSON.stringify(account?.local)}`,
),
);
//fallback to current account access token to register atleast logged in account
if (currentAccount.name === account.name) {
_enabledNotificationForAccount(currentAccount)
_enabledNotificationForAccount(currentAccount);
}
}
});
};
_connectNotificationServer = (username) => {
/* eslint no-undef: "warn" */
const ws = new WebSocket(`${Config.ACTIVITY_WEBSOCKET_URL}?user=${username}`);
@ -720,7 +708,6 @@ class ApplicationContainer extends Component {
currentAccount: { name, local },
dispatch,
intl,
} = this.props;
removeUserData(name)
@ -742,7 +729,7 @@ class ApplicationContainer extends Component {
});
setExistUser(false);
dispatch(isPinCodeOpen(false));
dispatch(setEncryptedUnlockPin(encryptKey(Config.DEFAULT_KEU, Config.PIN_KEY)))
dispatch(setEncryptedUnlockPin(encryptKey(Config.DEFAULT_KEU, Config.PIN_KEY)));
if (local.authType === AUTH_TYPE.STEEM_CONNECT) {
removeSCAccount(name);
}
@ -771,6 +758,7 @@ class ApplicationContainer extends Component {
commentNotification: 4,
reblogNotification: 5,
transfersNotification: 6,
favoriteNotification: 13,
};
Object.keys(settings).map((item) => {
@ -836,7 +824,6 @@ class ApplicationContainer extends Component {
dispatch(fetchSubscribedCommunities(_currentAccount.username));
};
UNSAFE_componentWillReceiveProps(nextProps) {
const {
isDarkTheme: _isDarkTheme,

View File

@ -50,7 +50,8 @@ const RegisterScreen = ({ navigation, route }) => {
}, []);
const _handleEmailChange = (value) => {
const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const re =
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
setIsEmailValid(re.test(value));
setEmail(value);
};

View File

@ -39,9 +39,8 @@ const CommunitiesResultsContainer = ({ children, searchValue }) => {
// handle cache when searchResultsScreen data updates in communities reducer
useEffect(() => {
if (subscribingCommunitiesInSearchResultsScreen && selectedCommunityItem) {
const { status } = subscribingCommunitiesInSearchResultsScreen[
selectedCommunityItem.communityId
];
const { status } =
subscribingCommunitiesInSearchResultsScreen[selectedCommunityItem.communityId];
if (status === statusMessage.SUCCESS) {
dispatch(updateSubscribedCommunitiesCache(selectedCommunityItem));
}

View File

@ -6,6 +6,7 @@ import VersionNumber from 'react-native-version-number';
import Config from 'react-native-config';
import { injectIntl } from 'react-intl';
import messaging from '@react-native-firebase/messaging';
import { withNavigation } from '@react-navigation/compat';
import { languageRestart } from '../../../utils/I18nUtils';
import THEME_OPTIONS from '../../../constants/options/theme';
@ -53,7 +54,6 @@ import { VALUE as CURRENCY_VALUE } from '../../../constants/options/currency';
import { VALUE as LANGUAGE_VALUE } from '../../../constants/options/language';
import settingsTypes from '../../../constants/settingsTypes';
// Utilities
import { sendEmail } from '../../../utils/sendEmail';
import { encryptKey, decryptKey } from '../../../utils/crypto';
@ -62,7 +62,6 @@ import { encryptKey, decryptKey } from '../../../utils/crypto';
import SettingsScreen from '../screen/settingsScreen';
import { SERVER_LIST } from '../../../constants/options/api';
import ROUTES from '../../../constants/routeNames';
import { withNavigation } from '@react-navigation/compat';
/*
* Props Name Description Value
@ -212,6 +211,7 @@ class SettingsContainer extends Component {
case 'notification.vote':
case 'notification.comment':
case 'notification.mention':
case 'notification.favorite':
case 'notification.reblog':
case 'notification.transfers':
this._handleNotification(action, actionType);
@ -229,12 +229,11 @@ class SettingsContainer extends Component {
isReset: true,
isOldPinVerified: true,
oldPinCode: Config.DEFAULT_PIN,
})
});
} else {
navigation.navigate(ROUTES.SCREENS.PINCODE, {
callback: () => this._enableDefaultUnlockPin(action),
})
});
}
break;
@ -242,7 +241,7 @@ class SettingsContainer extends Component {
navigation.navigate(ROUTES.SCREENS.PINCODE, {
callback: () => dispatch(setIsBiometricEnabled(action)),
});
break;
case settingsTypes.SHOW_HIDE_IMGS:
dispatch(setHidePostsThumbnails(!isHideImages));
@ -261,6 +260,7 @@ class SettingsContainer extends Component {
comment: 4,
reblog: 5,
transfers: 6,
favorite: 13,
};
const notifyTypes = [];
@ -301,14 +301,14 @@ class SettingsContainer extends Component {
switch (actionType) {
case 'reset_pin':
navigation.navigate(ROUTES.SCREENS.PINCODE, {
isReset:true
})
isReset: true,
});
break;
case 'feedback':
this._handleSendFeedback();
break;
case settingsTypes.DELETE_ACCOUNT:
this._handleDeleteAccount();
break;
@ -433,8 +433,7 @@ class SettingsContainer extends Component {
],
}),
);
}
};
_clearUserData = async () => {
const { otherAccounts, dispatch } = this.props;
@ -474,7 +473,6 @@ class SettingsContainer extends Component {
}, 500);
};
_enableDefaultUnlockPin = (isEnabled) => {
const { dispatch, encUnlockPin } = this.props;
@ -524,6 +522,7 @@ const mapStateToProps = (state) => ({
commentNotification: state.application.notificationDetails.commentNotification,
followNotification: state.application.notificationDetails.followNotification,
mentionNotification: state.application.notificationDetails.mentionNotification,
favoriteNotification: state.application.notificationDetails.favoriteNotification,
reblogNotification: state.application.notificationDetails.reblogNotification,
transfersNotification: state.application.notificationDetails.transfersNotification,
voteNotification: state.application.notificationDetails.voteNotification,

View File

@ -37,6 +37,7 @@ const SettingsScreen = ({
commentNotification,
followNotification,
mentionNotification,
favoriteNotification,
reblogNotification,
transfersNotification,
voteNotification,
@ -247,6 +248,15 @@ const SettingsScreen = ({
isOn={mentionNotification}
handleOnChange={handleOnChange}
/>
<SettingsItem
title={intl.formatMessage({
id: 'settings.notification.favorite',
})}
type="toggle"
actionType="notification.favorite"
isOn={favoriteNotification}
handleOnChange={handleOnChange}
/>
<SettingsItem
title={intl.formatMessage({
id: 'settings.notification.reblog',

View File

@ -104,7 +104,7 @@ export const migrateUserEncryption = async (dispatch, currentAccount, encUserPin
}
try{
try {
const pinData = {
pinCode: Config.DEFAULT_PIN,
username: currentAccount.username,
@ -112,7 +112,7 @@ export const migrateUserEncryption = async (dispatch, currentAccount, encUserPin
};
const response = updatePinCode(pinData)
const _currentAccount = currentAccount;
_currentAccount.local = response;
@ -125,10 +125,10 @@ export const migrateUserEncryption = async (dispatch, currentAccount, encUserPin
const encryptedPin = encryptKey(Config.DEFAULT_PIN, Config.PIN_KEY);
dispatch(setPinCode(encryptedPin));
} catch(err){
} catch (err) {
console.warn('pin update failure: ', err);
}
dispatch(setEncryptedUnlockPin(encUserPin))
@ -139,54 +139,58 @@ export const migrateUserEncryption = async (dispatch, currentAccount, encUserPin
_currentAccount.local = realmData[0];
try {
const pinHash = encryptKey(Config.DEFAULT_PIN, Config.PIN_KEY);
//migration script for previously mast key based logged in user not having access token
if (
realmData[0].authType !== AUTH_TYPE.STEEM_CONNECT &&
realmData[0].accessToken === ''
) {
_currentAccount = await migrateToMasterKeyWithAccessToken(
_currentAccount,
realmData[0],
pinHash,
);
}
const pinHash = encryptKey(Config.DEFAULT_PIN, Config.PIN_KEY);
//migration script for previously mast key based logged in user not having access token
if (
realmData[0].authType !== AUTH_TYPE.STEEM_CONNECT &&
realmData[0].accessToken === ''
) {
_currentAccount = await migrateToMasterKeyWithAccessToken(
_currentAccount,
realmData[0],
pinHash,
);
}
//refresh access token
const encryptedAccessToken = await refreshSCToken(_currentAccount.local, Config.DEFAULT_PIN);
_currentAccount.local.accessToken = encryptedAccessToken;
//refresh access token
const encryptedAccessToken = await refreshSCToken(_currentAccount.local, Config.DEFAULT_PIN);
_currentAccount.local.accessToken = encryptedAccessToken;
} catch (error) {
onFailure(error)
}
//get unread notifications
try {
_currentAccount.unread_activity_count = await getUnreadNotificationCount();
_currentAccount.pointsSummary = await getPointsSummary(_currentAccount.username);
_currentAccount.mutes = await getMutes(_currentAccount.username);
_currentAccount.unread_activity_count = await getUnreadNotificationCount();
_currentAccount.pointsSummary = await getPointsSummary(_currentAccount.username);
_currentAccount.mutes = await getMutes(_currentAccount.username);
} catch (err) {
console.warn(
'Optional user data fetch failed, account can still function without them',
err,
);
console.warn(
'Optional user data fetch failed, account can still function without them',
err,
);
}
dispatch(updateCurrentAccount({ ..._currentAccount }));
dispatch(fetchSubscribedCommunities(_currentAccount.username));
}
const reduxMigrations = {
0: (state) => {
const upvotePercent = state.application.upvotePercent;
state.application.postUpvotePercent = upvotePercent;
state.application.commentUpvotePercent = upvotePercent
state.application.upvotePercent = undefined;
return state
const upvotePercent = state.application.upvotePercent;
state.application.postUpvotePercent = upvotePercent;
state.application.commentUpvotePercent = upvotePercent
state.application.upvotePercent = undefined;
return state
},
1: (state) => {
state.application.notificationDetails.favoriteNotification = true
return state;
}
}
}
export default {
migrateSettings,

View File

@ -125,12 +125,9 @@ export default (url) => {
}
if (
[
'https://ecency.com',
'https://hive.blog',
'https://peakd.com',
'https://leofinance.io',
].some((x) => url.startsWith(x))
['https://ecency.com', 'https://hive.blog', 'https://peakd.com', 'https://leofinance.io'].some(
(x) => url.startsWith(x),
)
) {
return parseAuthorPermlink(url);
}