diff --git a/locale/da/texts.po b/locale/da/texts.po
index d5cb9eac0..c42056faa 100644
--- a/locale/da/texts.po
+++ b/locale/da/texts.po
@@ -61,7 +61,7 @@ msgstr "[Sidste] dddd [•] HH:mm"
msgid "DD MMM YYYY [•] HH:mm"
msgstr "DD MMM YYYY [•] HH:mm"
-#: src/utils.js:159
+#: src/utils.js:160
msgid "Invalid address"
msgstr "Ugyldig adresse"
diff --git a/locale/pt-br/texts.po b/locale/pt-br/texts.po
index dae12e7e5..c502c4226 100644
--- a/locale/pt-br/texts.po
+++ b/locale/pt-br/texts.po
@@ -61,7 +61,7 @@ msgstr "[Última] dddd [•] HH:mm"
msgid "DD MMM YYYY [•] HH:mm"
msgstr "DD MMM YYYY [•] HH:mm"
-#: src/utils.js:159
+#: src/utils.js:160
msgid "Invalid address"
msgstr "Endereço inválido"
diff --git a/locale/ru-ru/texts.po b/locale/ru-ru/texts.po
index d06c178fe..ae00bf6ee 100644
--- a/locale/ru-ru/texts.po
+++ b/locale/ru-ru/texts.po
@@ -62,7 +62,7 @@ msgstr "[Последний] dddd [•] HH:mm"
msgid "DD MMM YYYY [•] HH:mm"
msgstr "DD MMM YYYY [•] HH:mm"
-#: src/utils.js:159
+#: src/utils.js:160
msgid "Invalid address"
msgstr "Неправильный адрес"
diff --git a/locale/texts.pot b/locale/texts.pot
index ffc40232d..2cb15ab4b 100644
--- a/locale/texts.pot
+++ b/locale/texts.pot
@@ -52,7 +52,7 @@ msgstr ""
msgid "DD MMM YYYY [•] HH:mm"
msgstr ""
-#: src/utils.js:159
+#: src/utils.js:160
msgid "Invalid address"
msgstr ""
diff --git a/src/components/EditInfoContainer.js b/src/components/EditInfoContainer.js
new file mode 100644
index 000000000..202e49ccc
--- /dev/null
+++ b/src/components/EditInfoContainer.js
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) Hathor Labs and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import React from 'react';
+import {
+ StyleSheet,
+ View,
+ TouchableOpacity
+} from 'react-native';
+import { COLORS } from '../styles/themes';
+
+import { PenIcon } from './Icons/Pen.icon';
+
+export const EditInfoContainer = ({ center, onPress, children }) => (
+
+
+
+ {children}
+
+
+
+
+
+
+);
+
+const styles = StyleSheet.create({
+ editInfoWrapperCentered: {
+ alignSelf: 'center',
+ },
+ editInfoContainer: {
+ paddingVertical: 8,
+ paddingLeft: 8,
+ paddingRight: 40,
+ borderRadius: 8,
+ backgroundColor: COLORS.white,
+ },
+ editInfoContainerCentered: {
+ paddingLeft: 40,
+ },
+ alignCenter: {
+ alignItems: 'center',
+ },
+ editIcon: {
+ position: 'absolute',
+ display: 'flex',
+ justifyContent: 'center',
+ top: 0,
+ right: 0,
+ bottom: 0,
+ width: 24,
+ height: '100%',
+ marginVertical: 8,
+ marginRight: 8,
+ },
+});
diff --git a/src/components/HathorHeader.js b/src/components/HathorHeader.js
index 493a9e404..f6a174b2a 100644
--- a/src/components/HathorHeader.js
+++ b/src/components/HathorHeader.js
@@ -30,6 +30,9 @@ const HathorHeader = ({
const left = React.Children.toArray(children).find(
(child) => child.type.displayName === HathorHeaderLeft.displayName
);
+ const central = React.Children.toArray(children).find(
+ (child) => child.type.displayName === HathorHeaderCentral.displayName
+ );
const right = React.Children.toArray(children).find(
(child) => child.type.displayName === HathorHeaderRight.displayName
);
@@ -40,6 +43,7 @@ const HathorHeader = ({
&& (
{left}
+ {central}
{right}
)}
@@ -70,10 +74,14 @@ const InnerWrapper = ({ children }) => (
const HathorHeaderLeft = ({ children }) => ({children});
HathorHeaderLeft.displayName = 'HathorHeaderLeft';
+const HathorHeaderCentral = ({ style, children }) => {children};
+HathorHeaderCentral.displayName = 'HathorHeaderCentral';
+
const HathorHeaderRight = ({ children }) => {children};
HathorHeaderRight.displayName = 'HathorHeaderRight';
HathorHeader.Left = HathorHeaderLeft;
+HathorHeader.Central = HathorHeaderCentral;
HathorHeader.Right = HathorHeaderRight;
const CancelButton = ({ onCancel }) => (
@@ -118,7 +126,7 @@ const RightComponent = ({ rightElement, onCancel }) => {
const styles = StyleSheet.create({
wrapper: {
- height: STYLE.headerHeight,
+ minHeight: STYLE.headerHeight,
flexDirection: 'row',
alignItems: 'flex-end',
borderColor: COLORS.borderColor,
diff --git a/src/components/ModalBase.js b/src/components/ModalBase.js
new file mode 100644
index 000000000..2b24b7acf
--- /dev/null
+++ b/src/components/ModalBase.js
@@ -0,0 +1,116 @@
+/**
+ * Copyright (c) Hathor Labs and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import React from 'react';
+import {
+ StyleSheet,
+ View,
+ Text,
+} from 'react-native';
+import Modal from 'react-native-modal';
+
+import { COLORS } from '../styles/themes';
+import NewHathorButton from './NewHathorButton';
+
+const ModalBase = ({ styleModal, styleWrapper, show, onDismiss, children }) => {
+ const hasChildren = children != null;
+
+ const title = hasChildren && React.Children.toArray(children).find(
+ (child) => child.type.displayName === Title.displayName
+ );
+ const body = hasChildren && React.Children.toArray(children).find(
+ (child) => child.type.displayName === Body.displayName
+ );
+ const button = hasChildren && React.Children.toArray(children).find(
+ (child) => child.type.displayName === Button.displayName
+ );
+ const discreteButton = hasChildren && React.Children.toArray(children).find(
+ (child) => child.type.displayName === DiscreteButton.displayName
+ );
+
+ return (
+
+
+ {title && title}
+ {body && body}
+ {button && button}
+ {discreteButton && discreteButton}
+
+
+ );
+};
+
+const Title = ({ children }) => (
+
+
+ {children}
+
+
+);
+Title.displayName = 'ModalBaseTitle';
+
+/**
+ * @param {Object} props
+ * @property {ReactNode} props.children
+ * @property {StyleProp} props.style
+ */
+const Body = ({ style, children }) => (
+
+ {children}
+
+);
+Body.displayName = 'ModalBaseBody';
+
+const Button = ({ title, disabled, secondary, danger, onPress }) => (
+
+);
+Button.displayName = 'ModalBaseButton';
+
+const DiscreteButton = ({ title, onPress }) => (
+
+);
+DiscreteButton.displayName = 'ModalBaseDiscreteButton';
+
+ModalBase.Title = Title;
+ModalBase.Body = Body;
+ModalBase.Button = Button;
+ModalBase.DiscreteButton = DiscreteButton;
+
+const styles = StyleSheet.create({
+ wrapper: {
+ borderRadius: 8,
+ paddingVertical: 24,
+ paddingHorizontal: 16,
+ backgroundColor: COLORS.white,
+ },
+ titleWrapper: {
+ paddingBottom: 20,
+ },
+ title: {
+ color: 'black',
+ fontSize: 18,
+ lineHeight: 20,
+ },
+ discreteButton: {
+ marginTop: 8,
+ },
+});
+
+export { ModalBase }
diff --git a/src/components/NewHathorButton.js b/src/components/NewHathorButton.js
index a1603e949..1afe5e5d1 100644
--- a/src/components/NewHathorButton.js
+++ b/src/components/NewHathorButton.js
@@ -21,6 +21,11 @@ const NewHathorButton = (props) => {
textStyle.push(style.textDisabled);
}
+ if (props.discrete) {
+ wrapperViewStyle.push(style.wrapperDiscrete);
+ textStyle.push(style.textDiscrete);
+ }
+
if (props.secondary) {
wrapperViewStyle.push(style.wrapperSecondary);
textStyle.push(style.textSecondary);
@@ -34,6 +39,11 @@ const NewHathorButton = (props) => {
}
}
+ if (props.danger) {
+ wrapperViewStyle.push(style.wrapperSecondaryDanger);
+ textStyle.push(style.textSecondaryDanger);
+ }
+
return (
@@ -79,6 +89,14 @@ const style = StyleSheet.create({
wrapperSecondaryDisabled: {
borderColor: COLORS.textColorShadow,
},
+ wrapperDiscrete: {
+ backgroundColor: COLORS.backgroundColor,
+ borderColor: COLORS.backgroundColor,
+ borderWidth: 1.5,
+ },
+ wrapperSecondaryDanger: {
+ borderColor: COLORS.errorBgColor,
+ },
touchable: {
flex: 1,
flexDirection: 'row',
@@ -101,6 +119,12 @@ const style = StyleSheet.create({
textDisabled: {
color: COLORS.textColorShadow,
},
+ textDiscrete: {
+ color: COLORS.freeze300,
+ },
+ textSecondaryDanger: {
+ color: COLORS.errorBgColor,
+ },
});
export default NewHathorButton;
diff --git a/src/components/TextLabel.js b/src/components/TextLabel.js
new file mode 100644
index 000000000..702e17d2d
--- /dev/null
+++ b/src/components/TextLabel.js
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) Hathor Labs and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import React from 'react';
+import {
+ StyleSheet,
+ Text,
+} from 'react-native';
+
+export const TextLabel = ({ pb8, bold, children }) => (
+ {children}
+);
+
+const styles = StyleSheet.create({
+ textLabel: {
+ fontSize: 12,
+ lineHeight: 20,
+ color: 'hsla(0, 0%, 38%, 1)',
+ },
+ pb8: {
+ paddingBottom: 8,
+ },
+ bold: {
+ fontWeight: 'bold',
+ },
+});
diff --git a/src/components/TextValue.js b/src/components/TextValue.js
new file mode 100644
index 000000000..952616385
--- /dev/null
+++ b/src/components/TextValue.js
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) Hathor Labs and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import React from 'react';
+import {
+ StyleSheet,
+ Text,
+} from 'react-native';
+
+export const TextValue = ({ bold, pb4, children }) => (
+ {children}
+);
+
+const styles = StyleSheet.create({
+ textValue: {
+ fontSize: 14,
+ lineHeight: 20,
+ color: 'black',
+ },
+ pb4: {
+ paddingBottom: 4,
+ },
+ bold: {
+ fontWeight: 'bold',
+ },
+});
diff --git a/src/utils.js b/src/utils.js
index e950f1354..281c5d790 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -11,6 +11,7 @@ import React from 'react';
import { t } from 'ttag';
import { Linking, Platform, Text } from 'react-native';
import { getStatusBarHeight } from 'react-native-status-bar-height';
+import moment from 'moment';
import baseStyle from './styles/init';
import { KEYCHAIN_USER, NANO_CONTRACT_FEATURE_TOGGLE } from './constants';
import { STORE } from './store';
@@ -403,3 +404,12 @@ export const isPushNotificationAvailableForUser = (state) => (
export const getNanoContractFeatureToggle = (state) => (
state.featureToggles[NANO_CONTRACT_FEATURE_TOGGLE]
);
+
+/**
+ * Get timestamp in specific format.
+ *
+ * @param {number} timestamp
+ *
+ * @returns {string} formatted timestamp
+ */
+export const getTimestampFormat = (timestamp) => moment.unix(timestamp).format(t`DD MMM YYYY [•] HH:mm`)