Repository: kiwicom/mobile
Pull request #692 (2018-06-04 08:13:46)

MMB: Add header share button


Patch:
diff --git a/app/MMB/src/components/HeaderShareButton.js b/app/MMB/src/components/HeaderShareButton.js
new file mode 100644
index 00000000..2ccedce0
--- /dev/null
+++ b/app/MMB/src/components/HeaderShareButton.js
@@ -0,0 +1,64 @@
+// @flow
+
+import * as React from 'react';
+import { Share, Platform } from 'react-native';
+import {
+  TextIcon,
+  HeaderRightButton,
+  Color,
+  StyleSheet,
+} from '@kiwicom/mobile-shared';
+import { DateFormatter, GetDeviceLocale } from '@kiwicom/mobile-localization';
+
+import BookingDetailContext from '../context/BookingDetailContext';
+
+type PropsWithContext = {|
+  +arrivalCityId: string,
+  +arrivalTime: Date,
+|};
+
+class HeaderShareButton extends React.Component<PropsWithContext> {
+  onPress = () => {
+    const lang = GetDeviceLocale().split('-')[0] || 'en';
+    const message = `https://kiwi.com/share?date=${DateFormatter(
+      this.props.arrivalTime,
+    ).formatForMachine()}&city_id=${
+      this.props.arrivalCityId
+    }&source=manageMyBooking&lang=${lang}&type=flight`;
+
+    Platform.select({
+      ios: Share.share({ url: message }),
+      android: Share.share({ message }),
+    });
+  };
+
+  render = () => (
+    <HeaderRightButton onPress={this.onPress}>
+      {Platform.select({
+        ios: <TextIcon code="&#xe083;" style={styles.icon} />,
+        android: <TextIcon code="&#xe068;" style={styles.icon} />,
+      })}
+    </HeaderRightButton>
+  );
+}
+
+export default function HeaderShareButtonWithContext() {
+  return (
+    <BookingDetailContext.Consumer>
+      {({ arrivalCityId, arrivalTime }) => (
+        <HeaderShareButton
+          arrivalCityId={arrivalCityId}
+          arrivalTime={arrivalTime}
+        />
+      )}
+    </BookingDetailContext.Consumer>
+  );
+}
+
+const styles = StyleSheet.create({
+  icon: {
+    fontSize: 21,
+    color: Color.brand,
+    alignSelf: 'flex-start',
+  },
+});
diff --git a/app/MMB/src/context/BookingDetailContext.js b/app/MMB/src/context/BookingDetailContext.js
index c466e0cc..908e4e8e 100644
--- a/app/MMB/src/context/BookingDetailContext.js
+++ b/app/MMB/src/context/BookingDetailContext.js
@@ -5,10 +5,14 @@ import * as React from 'react';
 type BookingDetail = {|
   +isPastBooking: boolean,
   +bookingId: string,
+  +arrivalCityId: string,
+  +arrivalTime: Date,
 |};
 const defaultState = {
   isPastBooking: false,
   bookingId: '',
+  arrivalCityId: '',
+  arrivalTime: new Date(),
   actions: {
     setBookingDetail: () => {},
   },
@@ -34,16 +38,20 @@ class Provider extends React.Component<Props, State> {
     super(props);
 
     this.state = {
-      isPastBooking: false,
-      bookingId: '',
+      ...defaultState,
       actions: {
         setBookingDetail: this.setBookingDetail,
       },
     };
   }
 
-  setBookingDetail = ({ isPastBooking, bookingId }: BookingDetail) => {
-    this.setState({ isPastBooking, bookingId });
+  setBookingDetail = ({
+    isPastBooking,
+    bookingId,
+    arrivalCityId,
+    arrivalTime,
+  }: BookingDetail) => {
+    this.setState({ isPastBooking, bookingId, arrivalCityId, arrivalTime });
   };
 
   render = () => (
diff --git a/app/MMB/src/navigation/DetailScreen.js b/app/MMB/src/navigation/DetailScreen.js
index ea35447b..4b872656 100644
--- a/app/MMB/src/navigation/DetailScreen.js
+++ b/app/MMB/src/navigation/DetailScreen.js
@@ -5,6 +5,7 @@ import { HeaderTitle, type NavigationType } from '@kiwicom/mobile-navigation';
 import { AdaptableLayout } from '@kiwicom/mobile-shared';
 import { Translation } from '@kiwicom/mobile-localization';
 
+import HeaderShareButton from '../components/HeaderShareButton';
 import Layout from '../components/Layout';
 import MainMenuContainer from '../MainMenuContainer';
 import HelpSubmenu, { HelpSubmenuItems } from '../scenes/help';
@@ -100,6 +101,7 @@ export default class DetailsScreen extends React.Component<Props, State> {
           <Translation id="mmb.main_menu.title" />
         </HeaderTitle>
       ),
+      headerRight: <HeaderShareButton />,
     };
   };
 
diff --git a/app/MMB/src/scenes/list/__generated__/FlightListContainerQuery.graphql.js b/app/MMB/src/scenes/list/__generated__/FlightListContainerQuery.graphql.js
index 2ae09101..01a9362c 100644
--- a/app/MMB/src/scenes/list/__generated__/FlightListContainerQuery.graphql.js
+++ b/app/MMB/src/scenes/list/__generated__/FlightListContainerQuery.graphql.js
@@ -1,6 +1,6 @@
 /**
  * @flow
- * @relayHash 45e9c19bdc5c54d636d54f6b18e34778
+ * @relayHash 9554b4b5d03231ea48f1eec254a5de52
  */
 
 /* eslint-disable */
@@ -106,6 +106,8 @@ fragment CityImage_image on BookingInterface {
 
 fragment CityImage_arrival on RouteStop {
   ...FromToRow_arrival
+  cityId
+  time
 }
 
 fragment CityImage_departure on RouteStop {
@@ -207,6 +209,13 @@ v7 = {
   "storageKey": null
 },
 v8 = {
+  "kind": "ScalarField",
+  "alias": null,
+  "name": "time",
+  "args": null,
+  "storageKey": null
+},
+v9 = {
   "kind": "LinkedField",
   "alias": null,
   "name": "airport",
@@ -235,17 +244,11 @@ v8 = {
     }
   ]
 },
-v9 = [
-  {
-    "kind": "ScalarField",
-    "alias": null,
-    "name": "time",
-    "args": null,
-    "storageKey": null
-  },
-  v8
+v10 = [
+  v8,
+  v9
 ],
-v10 = {
+v11 = {
   "kind": "LinkedField",
   "alias": null,
   "name": "departure",
@@ -253,12 +256,20 @@ v10 = {
   "args": null,
   "concreteType": "RouteStop",
   "plural": false,
-  "selections": v9
+  "selections": v10
 },
-v11 = [
+v12 = [
+  v9,
+  {
+    "kind": "ScalarField",
+    "alias": null,
+    "name": "cityId",
+    "args": null,
+    "storageKey": null
+  },
   v8
 ],
-v12 = {
+v13 = {
   "kind": "LinkedField",
   "alias": null,
   "name": "arrival",
@@ -266,9 +277,9 @@ v12 = {
   "args": null,
   "concreteType": "RouteStop",
   "plural": false,
-  "selections": v11
+  "selections": v12
 },
-v13 = [
+v14 = [
   {
     "kind": "LinkedField",
     "alias": null,
@@ -318,8 +329,8 @@ v13 = [
                 "concreteType": "Trip",
                 "plural": false,
                 "selections": [
-                  v10,
-                  v12
+                  v11,
+                  v13
                 ]
               },
               v2
@@ -348,8 +359,8 @@ v13 = [
                 "concreteType": "Trip",
                 "plural": false,
                 "selections": [
-                  v12,
-                  v10
+                  v13,
+                  v11
                 ]
               },
               v2
@@ -377,7 +388,7 @@ v13 = [
                 "args": null,
                 "concreteType": "RouteStop",
                 "plural": false,
-                "selections": v11
+                "selections": v12
               },
               {
                 "kind": "LinkedField",
@@ -387,7 +398,7 @@ v13 = [
                 "args": null,
                 "concreteType": "RouteStop",
                 "plural": false,
-                "selections": v9
+                "selections": v10
               },
               v2
             ]
@@ -402,7 +413,7 @@ return {
   "operationKind": "query",
   "name": "FlightListContainerQuery",
   "id": null,
-  "text": "query FlightListContainerQuery {\n  future: allBookings(only: FUTURE) {\n    ...FlightListContainer_future\n  }\n  past: allBookings(only: PAST) {\n    ...FlightListContainer_past\n  }\n}\n\nfragment FlightListContainer_future on BookingConnection {\n  ...FlightList\n}\n\nfragment FlightListContainer_past on BookingConnection {\n  ...FlightList\n}\n\nfragment FlightList on BookingConnection {\n  edges {\n    node {\n      id\n      type\n      oneWay {\n        ...OneWayFlight_booking\n        id\n      }\n      return {\n        ...ReturnFlight_booking\n        id\n      }\n      multicity {\n        ...MulticityFlight_booking\n        id\n      }\n    }\n  }\n}\n\nfragment OneWayFlight_booking on BookingOneWay {\n  ...CityImage_image\n  trip {\n    departure {\n      ...CityImage_departure\n    }\n    arrival {\n      ...CityImage_arrival\n    }\n  }\n}\n\nfragment ReturnFlight_booking on BookingReturn {\n  ...CityImage_image\n  outbound {\n    arrival {\n      ...CityImage_arrival\n    }\n    departure {\n      ...CityImage_departure\n    }\n  }\n}\n\nfragment MulticityFlight_booking on BookingMulticity {\n  ...CityImage_image\n  end {\n    ...CityImage_arrival\n  }\n  start {\n    ...CityImage_departure\n  }\n}\n\nfragment CityImage_image on BookingInterface {\n  databaseId\n  passengerCount\n  isPastBooking\n  destinationImageUrl(dimensions: _375x165)\n  ...ImageBadges\n}\n\nfragment CityImage_arrival on RouteStop {\n  ...FromToRow_arrival\n}\n\nfragment CityImage_departure on RouteStop {\n  ...DateAndPassengerCount_departure\n  ...FromToRow_departure\n}\n\nfragment DateAndPassengerCount_departure on RouteStop {\n  time\n}\n\nfragment FromToRow_departure on RouteStop {\n  airport {\n    city {\n      name\n    }\n  }\n}\n\nfragment FromToRow_arrival on RouteStop {\n  airport {\n    city {\n      name\n    }\n  }\n}\n\nfragment ImageBadges on BookingInterface {\n  status\n  databaseId\n  isPastBooking\n}\n",
+  "text": "query FlightListContainerQuery {\n  future: allBookings(only: FUTURE) {\n    ...FlightListContainer_future\n  }\n  past: allBookings(only: PAST) {\n    ...FlightListContainer_past\n  }\n}\n\nfragment FlightListContainer_future on BookingConnection {\n  ...FlightList\n}\n\nfragment FlightListContainer_past on BookingConnection {\n  ...FlightList\n}\n\nfragment FlightList on BookingConnection {\n  edges {\n    node {\n      id\n      type\n      oneWay {\n        ...OneWayFlight_booking\n        id\n      }\n      return {\n        ...ReturnFlight_booking\n        id\n      }\n      multicity {\n        ...MulticityFlight_booking\n        id\n      }\n    }\n  }\n}\n\nfragment OneWayFlight_booking on BookingOneWay {\n  ...CityImage_image\n  trip {\n    departure {\n      ...CityImage_departure\n    }\n    arrival {\n      ...CityImage_arrival\n    }\n  }\n}\n\nfragment ReturnFlight_booking on BookingReturn {\n  ...CityImage_image\n  outbound {\n    arrival {\n      ...CityImage_arrival\n    }\n    departure {\n      ...CityImage_departure\n    }\n  }\n}\n\nfragment MulticityFlight_booking on BookingMulticity {\n  ...CityImage_image\n  end {\n    ...CityImage_arrival\n  }\n  start {\n    ...CityImage_departure\n  }\n}\n\nfragment CityImage_image on BookingInterface {\n  databaseId\n  passengerCount\n  isPastBooking\n  destinationImageUrl(dimensions: _375x165)\n  ...ImageBadges\n}\n\nfragment CityImage_arrival on RouteStop {\n  ...FromToRow_arrival\n  cityId\n  time\n}\n\nfragment CityImage_departure on RouteStop {\n  ...DateAndPassengerCount_departure\n  ...FromToRow_departure\n}\n\nfragment DateAndPassengerCount_departure on RouteStop {\n  time\n}\n\nfragment FromToRow_departure on RouteStop {\n  airport {\n    city {\n      name\n    }\n  }\n}\n\nfragment FromToRow_arrival on RouteStop {\n  airport {\n    city {\n      name\n    }\n  }\n}\n\nfragment ImageBadges on BookingInterface {\n  status\n  databaseId\n  isPastBooking\n}\n",
   "metadata": {},
   "fragment": {
     "kind": "Fragment",
@@ -458,7 +469,7 @@ return {
         "args": v0,
         "concreteType": "BookingConnection",
         "plural": false,
-        "selections": v13
+        "selections": v14
       },
       {
         "kind": "LinkedField",
@@ -468,7 +479,7 @@ return {
         "args": v1,
         "concreteType": "BookingConnection",
         "plural": false,
-        "selections": v13
+        "selections": v14
       }
     ]
   }
diff --git a/app/MMB/src/scenes/list/__generated__/FlightsQuery.graphql.js b/app/MMB/src/scenes/list/__generated__/FlightsQuery.graphql.js
index 05aedab7..28f930ab 100644
--- a/app/MMB/src/scenes/list/__generated__/FlightsQuery.graphql.js
+++ b/app/MMB/src/scenes/list/__generated__/FlightsQuery.graphql.js
@@ -1,6 +1,6 @@
 /**
  * @flow
- * @relayHash 15420c45c91501d12f199feb796f0fa2
+ * @relayHash c3031b1059688bc1e53c43d409694cdf
  */
 
 /* eslint-disable */
@@ -106,6 +106,8 @@ fragment CityImage_image on BookingInterface {
 
 fragment CityImage_arrival on RouteStop {
   ...FromToRow_arrival
+  cityId
+  time
 }
 
 fragment CityImage_departure on RouteStop {
@@ -207,6 +209,13 @@ v7 = {
   "storageKey": null
 },
 v8 = {
+  "kind": "ScalarField",
+  "alias": null,
+  "name": "time",
+  "args": null,
+  "storageKey": null
+},
+v9 = {
   "kind": "LinkedField",
   "alias": null,
   "name": "airport",
@@ -235,17 +244,11 @@ v8 = {
     }
   ]
 },
-v9 = [
-  {
-    "kind": "ScalarField",
-    "alias": null,
-    "name": "time",
-    "args": null,
-    "storageKey": null
-  },
-  v8
+v10 = [
+  v8,
+  v9
 ],
-v10 = {
+v11 = {
   "kind": "LinkedField",
   "alias": null,
   "name": "departure",
@@ -253,12 +256,20 @@ v10 = {
   "args": null,
   "concreteType": "RouteStop",
   "plural": false,
-  "selections": v9
+  "selections": v10
 },
-v11 = [
+v12 = [
+  v9,
+  {
+    "kind": "ScalarField",
+    "alias": null,
+    "name": "cityId",
+    "args": null,
+    "storageKey": null
+  },
   v8
 ],
-v12 = {
+v13 = {
   "kind": "LinkedField",
   "alias": null,
   "name": "arrival",
@@ -266,9 +277,9 @@ v12 = {
   "args": null,
   "concreteType": "RouteStop",
   "plural": false,
-  "selections": v11
+  "selections": v12
 },
-v13 = [
+v14 = [
   {
     "kind": "LinkedField",
     "alias": null,
@@ -318,8 +329,8 @@ v13 = [
                 "concreteType": "Trip",
                 "plural": false,
                 "selections": [
-                  v10,
-                  v12
+                  v11,
+                  v13
                 ]
               },
               v2
@@ -348,8 +359,8 @@ v13 = [
                 "concreteType": "Trip",
                 "plural": false,
                 "selections": [
-                  v12,
-                  v10
+                  v13,
+                  v11
                 ]
               },
               v2
@@ -377,7 +388,7 @@ v13 = [
                 "args": null,
                 "concreteType": "RouteStop",
                 "plural": false,
-                "selections": v11
+                "selections": v12
               },
               {
                 "kind": "LinkedField",
@@ -387,7 +398,7 @@ v13 = [
                 "args": null,
                 "concreteType": "RouteStop",
                 "plural": false,
-                "selections": v9
+                "selections": v10
               },
               v2
             ]
@@ -402,7 +413,7 @@ return {
   "operationKind": "query",
   "name": "FlightsQuery",
   "id": null,
-  "text": "query FlightsQuery {\n  future: allBookings(only: FUTURE) {\n    ...FlightListContainer_future\n  }\n  past: allBookings(only: PAST) {\n    ...FlightListContainer_past\n  }\n}\n\nfragment FlightListContainer_future on BookingConnection {\n  ...FlightList\n}\n\nfragment FlightListContainer_past on BookingConnection {\n  ...FlightList\n}\n\nfragment FlightList on BookingConnection {\n  edges {\n    node {\n      id\n      type\n      oneWay {\n        ...OneWayFlight_booking\n        id\n      }\n      return {\n        ...ReturnFlight_booking\n        id\n      }\n      multicity {\n        ...MulticityFlight_booking\n        id\n      }\n    }\n  }\n}\n\nfragment OneWayFlight_booking on BookingOneWay {\n  ...CityImage_image\n  trip {\n    departure {\n      ...CityImage_departure\n    }\n    arrival {\n      ...CityImage_arrival\n    }\n  }\n}\n\nfragment ReturnFlight_booking on BookingReturn {\n  ...CityImage_image\n  outbound {\n    arrival {\n      ...CityImage_arrival\n    }\n    departure {\n      ...CityImage_departure\n    }\n  }\n}\n\nfragment MulticityFlight_booking on BookingMulticity {\n  ...CityImage_image\n  end {\n    ...CityImage_arrival\n  }\n  start {\n    ...CityImage_departure\n  }\n}\n\nfragment CityImage_image on BookingInterface {\n  databaseId\n  passengerCount\n  isPastBooking\n  destinationImageUrl(dimensions: _375x165)\n  ...ImageBadges\n}\n\nfragment CityImage_arrival on RouteStop {\n  ...FromToRow_arrival\n}\n\nfragment CityImage_departure on RouteStop {\n  ...DateAndPassengerCount_departure\n  ...FromToRow_departure\n}\n\nfragment DateAndPassengerCount_departure on RouteStop {\n  time\n}\n\nfragment FromToRow_departure on RouteStop {\n  airport {\n    city {\n      name\n    }\n  }\n}\n\nfragment FromToRow_arrival on RouteStop {\n  airport {\n    city {\n      name\n    }\n  }\n}\n\nfragment ImageBadges on BookingInterface {\n  status\n  databaseId\n  isPastBooking\n}\n",
+  "text": "query FlightsQuery {\n  future: allBookings(only: FUTURE) {\n    ...FlightListContainer_future\n  }\n  past: allBookings(only: PAST) {\n    ...FlightListContainer_past\n  }\n}\n\nfragment FlightListContainer_future on BookingConnection {\n  ...FlightList\n}\n\nfragment FlightListContainer_past on BookingConnection {\n  ...FlightList\n}\n\nfragment FlightList on BookingConnection {\n  edges {\n    node {\n      id\n      type\n      oneWay {\n        ...OneWayFlight_booking\n        id\n      }\n      return {\n        ...ReturnFlight_booking\n        id\n      }\n      multicity {\n        ...MulticityFlight_booking\n        id\n      }\n    }\n  }\n}\n\nfragment OneWayFlight_booking on BookingOneWay {\n  ...CityImage_image\n  trip {\n    departure {\n      ...CityImage_departure\n    }\n    arrival {\n      ...CityImage_arrival\n    }\n  }\n}\n\nfragment ReturnFlight_booking on BookingReturn {\n  ...CityImage_image\n  outbound {\n    arrival {\n      ...CityImage_arrival\n    }\n    departure {\n      ...CityImage_departure\n    }\n  }\n}\n\nfragment MulticityFlight_booking on BookingMulticity {\n  ...CityImage_image\n  end {\n    ...CityImage_arrival\n  }\n  start {\n    ...CityImage_departure\n  }\n}\n\nfragment CityImage_image on BookingInterface {\n  databaseId\n  passengerCount\n  isPastBooking\n  destinationImageUrl(dimensions: _375x165)\n  ...ImageBadges\n}\n\nfragment CityImage_arrival on RouteStop {\n  ...FromToRow_arrival\n  cityId\n  time\n}\n\nfragment CityImage_departure on RouteStop {\n  ...DateAndPassengerCount_departure\n  ...FromToRow_departure\n}\n\nfragment DateAndPassengerCount_departure on RouteStop {\n  time\n}\n\nfragment FromToRow_departure on RouteStop {\n  airport {\n    city {\n      name\n    }\n  }\n}\n\nfragment FromToRow_arrival on RouteStop {\n  airport {\n    city {\n      name\n    }\n  }\n}\n\nfragment ImageBadges on BookingInterface {\n  status\n  databaseId\n  isPastBooking\n}\n",
   "metadata": {},
   "fragment": {
     "kind": "Fragment",
@@ -458,7 +469,7 @@ return {
         "args": v0,
         "concreteType": "BookingConnection",
         "plural": false,
-        "selections": v13
+        "selections": v14
       },
       {
         "kind": "LinkedField",
@@ -468,7 +479,7 @@ return {
         "args": v1,
         "concreteType": "BookingConnection",
         "plural": false,
-        "selections": v13
+        "selections": v14
       }
     ]
   }
diff --git a/app/MMB/src/scenes/list/cityImage/CityImage.js b/app/MMB/src/scenes/list/cityImage/CityImage.js
index 86e6d16f..c6d254e3 100644
--- a/app/MMB/src/scenes/list/cityImage/CityImage.js
+++ b/app/MMB/src/scenes/list/cityImage/CityImage.js
@@ -27,6 +27,8 @@ type PropsWithContext = {|
   +setBookingDetail: (booking: {|
     isPastBooking: boolean,
     bookingId: string,
+    arrivalCityId: string,
+    arrivalTime: Date,
   |}) => void,
 |};
 
@@ -34,9 +36,14 @@ class CityImage extends React.Component<PropsWithContext> {
   goToDetail = () => {
     const bookingId = idx(this.props.image, _ => _.databaseId) || '';
     const isPastBooking = Boolean(idx(this.props.image, _ => _.isPastBooking));
+    const arrivalCityId = idx(this.props.arrival, _ => _.cityId) || '';
+    const arrivalTime = idx(this.props.arrival, _ => _.time) || '';
+
     this.props.setBookingDetail({
       bookingId: bookingId.toString(),
       isPastBooking,
+      arrivalCityId,
+      arrivalTime: new Date(arrivalTime),
     });
 
     this.props.navigation.navigate({
@@ -104,6 +111,8 @@ export default createFragmentContainer(
 
     fragment CityImage_arrival on RouteStop {
       ...FromToRow_arrival
+      cityId
+      time
     }
 
     fragment CityImage_departure on RouteStop {
diff --git a/app/MMB/src/scenes/list/cityImage/__generated__/CityImage_arrival.graphql.js b/app/MMB/src/scenes/list/cityImage/__generated__/CityImage_arrival.graphql.js
index 2a706ed4..2c74d824 100644
--- a/app/MMB/src/scenes/list/cityImage/__generated__/CityImage_arrival.graphql.js
+++ b/app/MMB/src/scenes/list/cityImage/__generated__/CityImage_arrival.graphql.js
@@ -12,6 +12,8 @@ type FromToRow_arrival$ref = any;
 import type { FragmentReference } from "relay-runtime";
 declare export opaque type CityImage_arrival$ref: FragmentReference;
 export type CityImage_arrival = {|
+  +cityId: ?string,
+  +time: ?any,
   +$fragmentRefs: FromToRow_arrival$ref,
   +$refType: CityImage_arrival$ref,
 |};
@@ -29,9 +31,23 @@ const node/*: ConcreteFragment*/ = {
       "kind": "FragmentSpread",
       "name": "FromToRow_arrival",
       "args": null
+    },
+    {
+      "kind": "ScalarField",
+      "alias": null,
+      "name": "cityId",
+      "args": null,
+      "storageKey": null
+    },
+    {
+      "kind": "ScalarField",
+      "alias": null,
+      "name": "time",
+      "args": null,
+      "storageKey": null
     }
   ]
 };
 // prettier-ignore
-(node/*: any*/).hash = '83aa66339e287f7815c8ab1825e69a46';
+(node/*: any*/).hash = 'b0ac23d857e7bda1db54b32ddc8d19ee';
 module.exports = node;
diff --git a/app/hotels/src/navigation/allHotels/MapHeaderButton.android.js b/app/hotels/src/navigation/allHotels/MapHeaderButton.android.js
index 786222ac..e1fa022f 100644
--- a/app/hotels/src/navigation/allHotels/MapHeaderButton.android.js
+++ b/app/hotels/src/navigation/allHotels/MapHeaderButton.android.js
@@ -1,11 +1,11 @@
 // @flow
 
 import * as React from 'react';
-import { HeaderRightButton } from '@kiwicom/mobile-shared';
+import { HeaderRightButton, Color, Icon } from '@kiwicom/mobile-shared';
 import RNTooltips from 'react-native-tooltips';
 
 type Props = {|
-  onPress: () => void,
+  +onPress: () => void,
 |};
 
 type State = {|
@@ -38,23 +38,22 @@ export default class MapHeaderButton extends React.Component<Props, State> {
     });
   };
 
-  render = () => [
-    <HeaderRightButton
-      key="header-right-button"
-      onPress={this.onPress}
-      onLongPress={this.onLongPress}
-    />,
-    <RNTooltips
-      key="header-right-button-tooltip"
-      text="Open map"
-      visible={this.state.isTooltipVisible}
-      reference={this.state.buttonReference}
-      corner={100}
-      tintColor="#505c5e"
-      arrow={false}
-      textSize={16}
-      shadow={true}
-      onHide={this.onTooltipClose}
-    />,
-  ];
+  render = () => (
+    <React.Fragment>
+      <HeaderRightButton onPress={this.onPress} onLongPress={this.onLongPress}>
+        <Icon name="map" size={24} color={Color.brand} />
+      </HeaderRightButton>
+      <RNTooltips
+        text="Open map"
+        visible={this.state.isTooltipVisible}
+        reference={this.state.buttonReference}
+        corner={100}
+        tintColor="#505c5e"
+        arrow={false}
+        textSize={16}
+        shadow={true}
+        onHide={this.onTooltipClose}
+      />
+    </React.Fragment>
+  );
 }
diff --git a/app/hotels/src/navigation/allHotels/MapHeaderButton.ios.js b/app/hotels/src/navigation/allHotels/MapHeaderButton.ios.js
index 9f5ab1b0..7c2c913c 100644
--- a/app/hotels/src/navigation/allHotels/MapHeaderButton.ios.js
+++ b/app/hotels/src/navigation/allHotels/MapHeaderButton.ios.js
@@ -1,12 +1,16 @@
 // @flow
 
 import * as React from 'react';
-import { HeaderRightButton } from '@kiwicom/mobile-shared';
+import { HeaderRightButton, Icon, Color } from '@kiwicom/mobile-shared';
 
 type Props = {|
-  onPress: () => void,
+  +onPress: () => void,
 |};
 
 export default function MapHeaderButton(props: Props) {
-  return <HeaderRightButton onPress={props.onPress} />;
+  return (
+    <HeaderRightButton onPress={props.onPress}>
+      <Icon name="map" size={24} color={Color.brand} />
+    </HeaderRightButton>
+  );
 }
diff --git a/packages/shared/src/HeaderRightButton.js b/packages/shared/src/HeaderRightButton.js
index 89e9ec98..d85537e0 100644
--- a/packages/shared/src/HeaderRightButton.js
+++ b/packages/shared/src/HeaderRightButton.js
@@ -3,15 +3,13 @@
 import * as React from 'react';
 import { View } from 'react-native';
 
-import Color from './Color';
 import StyleSheet from './PlatformStyleSheet';
 import Touchable from './Touchable';
-import Icon from './icons/Icon';
 
 type Props = {|
-  onPress: () => void,
-  tintColor?: string,
-  onLongPress?: (React.ElementRef<typeof Touchable>) => void,
+  +onPress: () => void,
+  +onLongPress?: (React.ElementRef<typeof Touchable>) => void,
+  +children?: React.Node,
 |};
 
 type State = {|
@@ -26,10 +24,6 @@ export default class HeaderRightButton extends React.PureComponent<
     reference: null,
   };
 
-  static defaultProps = {
-    tintColor: Color.brand,
-  };
-
   storeReference = (reference: React.ElementRef<typeof Touchable> | null) => {
     this.setState({ reference });
   };
@@ -41,7 +35,7 @@ export default class HeaderRightButton extends React.PureComponent<
   };
 
   render = () => {
-    const { onPress, tintColor } = this.props;
+    const { onPress } = this.props;
 
     return (
       <Touchable
@@ -55,7 +49,7 @@ export default class HeaderRightButton extends React.PureComponent<
         ref={this.storeReference}
       >
         <View style={styles.container}>
-          <Icon style={styles.icon} name="map" size={24} color={tintColor} />
+          <View style={styles.innerContainer}>{this.props.children}</View>
         </View>
       </Touchable>
     );
@@ -68,7 +62,7 @@ const styles = StyleSheet.create({
     flexDirection: 'row',
     backgroundColor: 'transparent',
   },
-  icon: {
+  innerContainer: {
     ios: {
       marginStart: 22,
       marginEnd: 10,


Test patch:
diff --git a/app/MMB/src/context/__tests__/BookingDetailContext.test.js b/app/MMB/src/context/__tests__/BookingDetailContext.test.js
index e28f8711..cb8d960e 100644
--- a/app/MMB/src/context/__tests__/BookingDetailContext.test.js
+++ b/app/MMB/src/context/__tests__/BookingDetailContext.test.js
@@ -2,6 +2,7 @@
 
 import * as React from 'react';
 import renderer from 'react-test-renderer';
+import { DateFormatter } from '@kiwicom/mobile-localization';
 
 import BookingDetailContext from '../BookingDetailContext';
 
@@ -13,12 +14,8 @@ const getWrapper = () =>
   renderer.create(
     <BookingDetailContext.Provider>
       <BookingDetailContext.Consumer>
-        {({ isPastBooking, bookingId, actions: { setBookingDetail } }) => (
-          <ContextConsumer
-            isPastBooking={isPastBooking}
-            bookingId={bookingId}
-            setBookingDetail={setBookingDetail}
-          />
+        {({ actions: { setBookingDetail }, ...rest }) => (
+          <ContextConsumer {...rest} setBookingDetail={setBookingDetail} />
         )}
       </BookingDetailContext.Consumer>
     </BookingDetailContext.Provider>,
@@ -31,6 +28,10 @@ describe('BookingDetailContext', () => {
     const instance = wrapper.root.findByType(ContextConsumer);
     expect(instance.props.isPastBooking).toBe(false);
     expect(instance.props.bookingId).toBe('');
+    expect(
+      DateFormatter(instance.props.arrivalTime).formatForMachine(),
+    ).toEqual(DateFormatter(new Date()).formatForMachine());
+    expect(instance.props.arrivalCityId).toBe('');
     expect(typeof instance.props.setBookingDetail).toBe('function');
   });
 
@@ -38,8 +39,16 @@ describe('BookingDetailContext', () => {
     const wrapper = getWrapper();
     const instance = wrapper.root.findByType(ContextConsumer);
 
-    instance.props.setBookingDetail({ isPastBooking: true, bookingId: '123' });
+    instance.props.setBookingDetail({
+      isPastBooking: true,
+      bookingId: '123',
+      arrivalCityId: 'oslo_no',
+      arrivalTime: new Date(1),
+    });
+
     expect(instance.props.isPastBooking).toBe(true);
     expect(instance.props.bookingId).toBe('123');
+    expect(instance.props.arrivalCityId).toBe('oslo_no');
+    expect(instance.props.arrivalTime).toEqual(new Date(1));
   });
 });