Repository: kiwicom/mobile
Pull request #1296 (2018-11-07 09:59:10)

[IOS] Patch ios playground


Patch:
diff --git a/.flowconfig b/.flowconfig
index abb93bee..3aaeccc6 100644
--- a/.flowconfig
+++ b/.flowconfig
@@ -90,6 +90,9 @@ suppress_comment=\\(.\\|\n\\)*\\$FlowIssue: https://github.com/facebook/flow/iss
 suppress_comment=\\(.\\|\n\\)*\\$FlowRelayIssue: https://github.com/facebook/relay/issues/[0-9]+
 suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError: .+
 
+[lints]
+unnecessary-optional-chain=error
+
 [strict]
 ;nonstrict-import
 unclear-type
diff --git a/android/app/build.gradle b/android/app/build.gradle
index b47191b8..a5180036 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -155,6 +155,7 @@ android {
 }
 
 dependencies {
+    compile project(':react-native-code-push')
     implementation project(':react-native-zip-archive')
     implementation project(':react-native-share')
     implementation project(':react-native-pdf')
diff --git a/android/settings.gradle b/android/settings.gradle
index 3545f78b..1d981e90 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -1,4 +1,6 @@
 apply from: "dependencies.gradle"
+include ':react-native-code-push'
+project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')
 include ':react-native-zip-archive'
 project(':react-native-zip-archive').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-zip-archive/android')
 include ':react-native-share'
diff --git a/app/MMB/src/components/Deeplink.js b/app/MMB/src/components/Deeplink.js
index 06884e66..7545ac40 100644
--- a/app/MMB/src/components/Deeplink.js
+++ b/app/MMB/src/components/Deeplink.js
@@ -1,9 +1,8 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { WebView } from '@kiwicom/mobile-shared';
 import { graphql, PublicApiRenderer } from '@kiwicom/mobile-relay';
-import idx from 'idx';
 
 import BookingDetailContext, {
   type State as BookingDetailState,
@@ -20,8 +19,7 @@ type Props = {|
 export default class Deeplink extends React.Component<Props> {
   renderInnerComponent = (renderProps: DeeplinkQueryResponse) => {
     const uri =
-      idx(renderProps, _ => _.singleBooking.directAccessURL) ||
-      'https://www.kiwi.com/';
+      renderProps.singleBooking?.directAccessURL ?? 'https://www.kiwi.com/';
 
     return <WebView source={{ uri }} />;
   };
@@ -50,9 +48,11 @@ export default class Deeplink extends React.Component<Props> {
     />
   );
 
-  render = () => (
-    <BookingDetailContext.Consumer>
-      {this.renderInner}
-    </BookingDetailContext.Consumer>
-  );
+  render() {
+    return (
+      <BookingDetailContext.Consumer>
+        {this.renderInner}
+      </BookingDetailContext.Consumer>
+    );
+  }
 }
diff --git a/app/MMB/src/components/Invoice.js b/app/MMB/src/components/Invoice.js
index 3c3d2bb0..119ae3b9 100644
--- a/app/MMB/src/components/Invoice.js
+++ b/app/MMB/src/components/Invoice.js
@@ -1,20 +1,21 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { graphql, PublicApiRenderer } from '@kiwicom/mobile-relay';
 import { GeneralError } from '@kiwicom/mobile-shared';
 import { Translation } from '@kiwicom/mobile-localization';
 import PdfViewer from '@kiwicom/mobile-pdf';
-import idx from 'idx';
 
-import BookingDetailContext from '../context/BookingDetailContext';
+import BookingDetailContext, {
+  type State as BoookingDetailState,
+} from '../context/BookingDetailContext';
 import type { InvoiceQueryResponse } from './__generated__/InvoiceQuery.graphql';
 
 export default class Invoice extends React.Component<{||}> {
   renderInnerComponent = (renderProps: InvoiceQueryResponse) => {
-    const uri = idx(renderProps, _ => _.singleBooking.assets.invoiceUrl);
+    const uri = renderProps.singleBooking?.assets?.invoiceUrl;
 
-    if (!uri) {
+    if (uri == null) {
       return (
         <GeneralError
           errorMessage={<Translation id="mmb.invoices.not_available" />}
@@ -25,28 +26,32 @@ export default class Invoice extends React.Component<{||}> {
     return <PdfViewer uri={uri} />;
   };
 
-  render = () => (
-    <BookingDetailContext.Consumer>
-      {({ bookingId, authToken }) => (
-        <PublicApiRenderer
-          render={this.renderInnerComponent}
-          query={graphql`
-            query InvoiceQuery($bookingId: Int!, $authToken: String!) {
-              singleBooking(id: $bookingId, authToken: $authToken) {
-                ... on BookingInterface {
-                  assets {
-                    invoiceUrl
-                  }
-                }
+  renderContext = ({ bookingId, authToken }: BoookingDetailState) => (
+    <PublicApiRenderer
+      render={this.renderInnerComponent}
+      query={graphql`
+        query InvoiceQuery($bookingId: Int!, $authToken: String!) {
+          singleBooking(id: $bookingId, authToken: $authToken) {
+            ... on BookingInterface {
+              assets {
+                invoiceUrl
               }
             }
-          `}
-          variables={{
-            bookingId,
-            authToken,
-          }}
-        />
-      )}
-    </BookingDetailContext.Consumer>
+          }
+        }
+      `}
+      variables={{
+        bookingId,
+        authToken,
+      }}
+    />
   );
+
+  render() {
+    return (
+      <BookingDetailContext.Consumer>
+        {this.renderContext}
+      </BookingDetailContext.Consumer>
+    );
+  }
 }
diff --git a/app/MMB/src/components/MissingInformation.js b/app/MMB/src/components/MissingInformation.js
index 8e95eff9..85355cd2 100644
--- a/app/MMB/src/components/MissingInformation.js
+++ b/app/MMB/src/components/MissingInformation.js
@@ -8,7 +8,6 @@ import {
   type NavigationType,
   withNavigation,
 } from '@kiwicom/mobile-navigation';
-import idx from 'idx';
 import { StyleSheet, SimpleCard, Text, Button } from '@kiwicom/mobile-shared';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 
@@ -27,9 +26,9 @@ export class MissingInformation extends React.Component<PropsWithContext> {
   };
 
   isSomePassengerMissingId = () => {
-    const passengers = idx(this.props.data, _ => _.passengers) || [];
+    const passengers = this.props.data.passengers ?? [];
     return passengers.some(
-      passenger => idx(passenger, _ => _.travelDocument.idNumber) == null,
+      passenger => passenger?.travelDocument?.idNumber == null,
     );
   };
 
diff --git a/app/MMB/src/components/header/Header.js b/app/MMB/src/components/header/Header.js
index 380dfe96..f492067b 100644
--- a/app/MMB/src/components/header/Header.js
+++ b/app/MMB/src/components/header/Header.js
@@ -1,4 +1,4 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { View } from 'react-native';
@@ -15,7 +15,6 @@ import {
   MenuItem,
 } from '@kiwicom/mobile-navigation';
 import { Translation } from '@kiwicom/mobile-localization';
-import idx from 'idx';
 
 import ColorStrip from './ColorStrip';
 import StatusBar from './StatusBar';
@@ -30,7 +29,7 @@ type HeaderSharedProps = {|
 |};
 
 function HeaderShared(props: HeaderSharedProps) {
-  const booking = idx(props, _ => _.data);
+  const booking = props.data;
 
   return (
     <React.Fragment>
@@ -71,8 +70,8 @@ class Header extends React.Component<HeaderProps, HeaderState> {
     this.props.openSubmenu('mmb.main_menu.trip_overview', 'mmb.trip_overview');
   };
 
-  render = () => {
-    const booking = idx(this.props, _ => _.data);
+  render() {
+    const booking = this.props.data;
 
     return (
       <AdaptableLayout
@@ -104,7 +103,7 @@ class Header extends React.Component<HeaderProps, HeaderState> {
         }
       />
     );
-  };
+  }
 }
 
 export default createFragmentContainer(
diff --git a/app/MMB/src/components/header/Location.js b/app/MMB/src/components/header/Location.js
index 31bd8c60..e1b610a6 100644
--- a/app/MMB/src/components/header/Location.js
+++ b/app/MMB/src/components/header/Location.js
@@ -1,11 +1,10 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { View } from 'react-native';
 import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
 import { Translation } from '@kiwicom/mobile-localization';
 import { Text, StyleSheet } from '@kiwicom/mobile-shared';
-import idx from 'idx';
 
 import CountryFlag from '../CountryFlag';
 import type { Location as LocationDataType } from './__generated__/Location.graphql';
@@ -15,8 +14,8 @@ type Props = {|
 |};
 
 function Location(props: Props) {
-  const airport = idx(props, _ => _.data.airport);
-  const cityName = idx(airport, _ => _.city.name);
+  const airport = props.data.airport;
+  const cityName = airport?.city?.name;
 
   return (
     <View style={styleSheet.wrapper}>
diff --git a/app/MMB/src/components/header/StatusBar.js b/app/MMB/src/components/header/StatusBar.js
index 4cbc0f86..174b72b1 100644
--- a/app/MMB/src/components/header/StatusBar.js
+++ b/app/MMB/src/components/header/StatusBar.js
@@ -1,11 +1,10 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { View } from 'react-native';
 import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
 import { StyleSheet, Text } from '@kiwicom/mobile-shared';
 import { Translation } from '@kiwicom/mobile-localization';
-import idx from 'idx';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 
 import ColorStrip from './ColorStrip';
@@ -17,7 +16,7 @@ type Props = {|
 |};
 
 function StatusBar(props: Props) {
-  const id = idx(props, _ => _.data.databaseId);
+  const id = props.data.databaseId ?? '';
 
   return (
     <View style={styleSheet.row}>
@@ -27,7 +26,7 @@ function StatusBar(props: Props) {
           <StatusBarIcon data={props.data} />
         </View>
         <Text style={styleSheet.bid}>
-          <Translation passThrough={`#${id || ''}`} />
+          <Translation passThrough={`#${id}`} />
         </Text>
       </View>
     </View>
diff --git a/app/MMB/src/components/header/TripInfo.js b/app/MMB/src/components/header/TripInfo.js
index c6926367..de4eaf26 100644
--- a/app/MMB/src/components/header/TripInfo.js
+++ b/app/MMB/src/components/header/TripInfo.js
@@ -1,10 +1,9 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { View } from 'react-native';
 import { StyleSheet } from '@kiwicom/mobile-shared';
 import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
-import idx from 'idx';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 
 import TripInfoOneWay from './TripInfoOneWay';
@@ -17,8 +16,8 @@ type Props = {|
 |};
 
 function TripInfo(props: Props) {
-  const data = idx(props, _ => _.data);
-  const type = idx(data, _ => _.__typename);
+  const data = props.data;
+  const type = data.__typename;
 
   return (
     <View style={styleSheet.wrapper}>
diff --git a/app/MMB/src/components/header/TripInfoMulticity.js b/app/MMB/src/components/header/TripInfoMulticity.js
index 8fdb9110..292a3c45 100644
--- a/app/MMB/src/components/header/TripInfoMulticity.js
+++ b/app/MMB/src/components/header/TripInfoMulticity.js
@@ -1,11 +1,10 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { View } from 'react-native';
 import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
 import { StyleSheet, Color } from '@kiwicom/mobile-shared';
 import { SeparatorFullWidth } from '@kiwicom/mobile-navigation';
-import idx from 'idx';
 import last from 'lodash/last';
 
 import ColorStrip from './ColorStrip';
@@ -18,10 +17,10 @@ type Props = {|
 |};
 
 function TripInfoMulticity(props: Props) {
-  const trips = idx(props, _ => _.data.trips) || [];
+  const trips = props.data.trips ?? [];
 
   return trips.map((trip, index) => {
-    const color = Color.tripColorCodes[index] || last(Color.tripColorCodes);
+    const color = Color.tripColorCodes[index] ?? last(Color.tripColorCodes);
     const row = (
       <View style={styleSheet.row} key={index}>
         <ColorStrip color={color} />
diff --git a/app/MMB/src/components/header/TripInfoOneWay.js b/app/MMB/src/components/header/TripInfoOneWay.js
index 4262ef7b..4d8732f4 100644
--- a/app/MMB/src/components/header/TripInfoOneWay.js
+++ b/app/MMB/src/components/header/TripInfoOneWay.js
@@ -1,10 +1,9 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { View } from 'react-native';
 import { StyleSheet } from '@kiwicom/mobile-shared';
 import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
-import idx from 'idx';
 
 import TripCities from './TripCities';
 import TripTimes from './TripTimes';
@@ -16,7 +15,7 @@ type Props = {|
 |};
 
 function TripInfoOneWay(props: Props) {
-  const trip = idx(props, _ => _.data.trip);
+  const trip = props.data.trip;
 
   return (
     <View style={styles.row}>
diff --git a/app/MMB/src/components/header/TripInfoReturn.js b/app/MMB/src/components/header/TripInfoReturn.js
index 9db6135a..f5bbd9a8 100644
--- a/app/MMB/src/components/header/TripInfoReturn.js
+++ b/app/MMB/src/components/header/TripInfoReturn.js
@@ -1,11 +1,10 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { View } from 'react-native';
 import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
 import { Translation } from '@kiwicom/mobile-localization';
 import { Text, StyleSheet } from '@kiwicom/mobile-shared';
-import idx from 'idx';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 
 import ColorStrip from './ColorStrip';
@@ -17,10 +16,9 @@ type Props = {|
   +data: TripInfoReturnType,
 |};
 
-function TripInfoReturn(props: Props) {
-  const data = idx(props, _ => _.data);
-  const outbound = idx(data, _ => _.outbound);
-  const inbound = idx(data, _ => _.inbound);
+function TripInfoReturn({ data }: Props) {
+  const outbound = data.outbound;
+  const inbound = data.inbound;
 
   return (
     <View style={styleSheet.row}>
diff --git a/app/MMB/src/components/header/TripTimes.js b/app/MMB/src/components/header/TripTimes.js
index 44b133a1..d447df69 100644
--- a/app/MMB/src/components/header/TripTimes.js
+++ b/app/MMB/src/components/header/TripTimes.js
@@ -1,10 +1,9 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { View } from 'react-native';
 import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
 import { StyleSheet, Duration } from '@kiwicom/mobile-shared';
-import idx from 'idx';
 
 import DateTime from './DateTime';
 import type { TripTimes as TripTimesType } from './__generated__/TripTimes.graphql';
@@ -24,7 +23,7 @@ function TripTimes({ data }: Props) {
       </View>
 
       <View style={styleSheet.duration}>
-        <Duration duration={idx(data, _ => _.duration)} />
+        <Duration duration={data.duration} />
       </View>
 
       <View style={styleSheet.arrival}>
diff --git a/app/MMB/src/components/passengerMenuItem/PassengerMenuItem.js b/app/MMB/src/components/passengerMenuItem/PassengerMenuItem.js
index 5a1c4b00..9b6ba19c 100644
--- a/app/MMB/src/components/passengerMenuItem/PassengerMenuItem.js
+++ b/app/MMB/src/components/passengerMenuItem/PassengerMenuItem.js
@@ -1,7 +1,6 @@
 // @flow strict
 
 import * as React from 'react';
-import idx from 'idx';
 import { View, Platform } from 'react-native';
 import { Translation } from '@kiwicom/mobile-localization';
 import { StyleSheet, TextIcon, Touchable } from '@kiwicom/mobile-shared';
@@ -16,21 +15,23 @@ type Props = {|
 |};
 
 const PassengerMenuItem = (props: Props) => {
-  const disabled = idx(props, _ => _.disabled) || false;
-  const passengerSubtitle = idx(props, _ => _.passengerSubtitle) || null;
-  const menuRightContent = idx(props, _ => _.menuRightContent) || null;
+  const disabled = props.disabled ?? false;
+  const passengerSubtitle = props.passengerSubtitle ?? null;
+  const menuRightContent = props.menuRightContent ?? null;
   return (
     <Touchable onPress={props.onPress} disabled={disabled}>
       <View style={styles.container}>
         <View>
           <Translation passThrough={props.passengerFullName} />
-          {passengerSubtitle || null}
+          {passengerSubtitle}
         </View>
         <View style={styles.rightContent}>
           {menuRightContent}
           {Platform.select({
             android: null,
-            ios: !disabled && <TextIcon code="&#xe01F;" style={styles.icon} />,
+            ios: disabled === false && (
+              <TextIcon code="&#xe01F;" style={styles.icon} />
+            ),
           })}
         </View>
       </View>
diff --git a/app/MMB/src/menuGroups/passengerMenuGroup/Passenger.js b/app/MMB/src/menuGroups/passengerMenuGroup/Passenger.js
index 9285826c..fe1eb664 100644
--- a/app/MMB/src/menuGroups/passengerMenuGroup/Passenger.js
+++ b/app/MMB/src/menuGroups/passengerMenuGroup/Passenger.js
@@ -5,7 +5,6 @@ import { View } from 'react-native';
 import { StyleSheet, Text } from '@kiwicom/mobile-shared';
 import { Translation, DateFormatter } from '@kiwicom/mobile-localization';
 import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
-import idx from 'idx';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 
 import TitleTranslation from '../../components/TitleTranslation';
@@ -16,18 +15,22 @@ type Props = {|
 |};
 
 const Passenger = ({ data }: Props) => {
-  const title = idx(data, _ => _.title) || '';
-  const fullName = idx(data, _ => _.fullName) || '';
-  const birthday = new Date(idx(data, _ => _.birthday) || '');
+  const title = data.title ?? '';
+  const fullName = data.fullName ?? '';
+  const birthday = data.birthday == null ? null : new Date(data.birthday);
 
   return (
     <View style={styles.passenger}>
       <Text style={styles.passengerText}>
         <TitleTranslation title={title} name={fullName} />
       </Text>
-      <Text style={[styles.passengerText, styles.passengerBirthday]}>
-        <Translation passThrough={DateFormatter(birthday).formatToBirthday()} />
-      </Text>
+      {birthday !== null && (
+        <Text style={[styles.passengerText, styles.passengerBirthday]}>
+          <Translation
+            passThrough={DateFormatter(birthday).formatToBirthday()}
+          />
+        </Text>
+      )}
     </View>
   );
 };
diff --git a/app/MMB/src/menuGroups/passengerMenuGroup/PassengerMenuDetail.js b/app/MMB/src/menuGroups/passengerMenuGroup/PassengerMenuDetail.js
index eecca96a..9eb428fd 100644
--- a/app/MMB/src/menuGroups/passengerMenuGroup/PassengerMenuDetail.js
+++ b/app/MMB/src/menuGroups/passengerMenuGroup/PassengerMenuDetail.js
@@ -1,10 +1,9 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { View } from 'react-native';
 import { StyleSheet } from '@kiwicom/mobile-shared';
 import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
-import idx from 'idx';
 
 import Passenger from './Passenger';
 import Visa from './Visa';
@@ -15,13 +14,13 @@ type Props = {|
 |};
 
 const PassengerMenuDetail = (props: Props) => {
-  const passengers = idx(props.data, _ => _.passengers) || [];
+  const passengers = props.data.passengers ?? [];
 
   return (
     <React.Fragment>
       <View style={styles.container}>
         {passengers.map(passenger => (
-          <Passenger data={passenger} key={idx(passenger, _ => _.databaseId)} />
+          <Passenger data={passenger} key={passenger?.databaseId} />
         ))}
       </View>
       <Visa data={props.data} />
diff --git a/app/MMB/src/menuGroups/passengerMenuGroup/Visa.js b/app/MMB/src/menuGroups/passengerMenuGroup/Visa.js
index 98fb9d14..651c82f1 100644
--- a/app/MMB/src/menuGroups/passengerMenuGroup/Visa.js
+++ b/app/MMB/src/menuGroups/passengerMenuGroup/Visa.js
@@ -1,8 +1,7 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
-import idx from 'idx';
 import { Translation } from '@kiwicom/mobile-localization';
 
 import Alert from '../../components/alert/Alert';
@@ -14,19 +13,19 @@ type Props = {|
 |};
 
 const Visa = ({ data }: Props) => {
-  const passengers = idx(data, _ => _.passengers) || [];
+  const passengers = data.passengers ?? [];
   const { requiredIn, warningIn } = passengers.reduce(
     (acc, curr) => {
-      const requiredIn = idx(curr, _ => _.visaInformation.requiredIn) || [];
-      const warningIn = idx(curr, _ => _.visaInformation.warningIn) || [];
+      const requiredIn = curr?.visaInformation?.requiredIn ?? [];
+      const warningIn = curr?.visaInformation?.warningIn ?? [];
       return {
         requiredIn: [
           ...acc.requiredIn,
-          ...requiredIn.map(item => idx(item, _ => _.name) || ''),
+          ...requiredIn.map(item => item?.name ?? ''),
         ],
         warningIn: [
           ...acc.warningIn,
-          ...warningIn.map(item => idx(item, _ => _.name) || ''),
+          ...warningIn.map(item => item?.name ?? ''),
         ],
       };
     },
diff --git a/app/MMB/src/menuGroups/servicesMenuGroup/FlightServices.js b/app/MMB/src/menuGroups/servicesMenuGroup/FlightServices.js
index b36f0c86..e49ef256 100644
--- a/app/MMB/src/menuGroups/servicesMenuGroup/FlightServices.js
+++ b/app/MMB/src/menuGroups/servicesMenuGroup/FlightServices.js
@@ -2,7 +2,6 @@
 
 import * as React from 'react';
 import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
-import idx from 'idx';
 
 import FlightServicesOneWay from './FlightServicesOneWay';
 import FlightServicesReturn from './FlightServicesReturn';
@@ -16,10 +15,10 @@ type Props = {|
 |};
 
 export const FlightServices = (props: Props) => {
-  if (idx(props, _ => _.data.isPastBooking)) {
+  if (props.data.isPastBooking === true) {
     return null;
   }
-  const type = idx(props, _ => _.data.__typename);
+  const type = props.data.__typename;
   return (
     <React.Fragment>
       {type === 'BookingOneWay' && <FlightServicesOneWay {...props} />}
diff --git a/app/MMB/src/menuGroups/servicesMenuGroup/FlightServicesMenuItem.js b/app/MMB/src/menuGroups/servicesMenuGroup/FlightServicesMenuItem.js
index 5f91c9a9..d39da173 100644
--- a/app/MMB/src/menuGroups/servicesMenuGroup/FlightServicesMenuItem.js
+++ b/app/MMB/src/menuGroups/servicesMenuGroup/FlightServicesMenuItem.js
@@ -5,7 +5,6 @@ import { MenuItem } from '@kiwicom/mobile-navigation';
 import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
 import { TextIcon } from '@kiwicom/mobile-shared';
 import { Translation } from '@kiwicom/mobile-localization';
-import idx from 'idx';
 
 import type { FlightServicesMenuItem as BookingType } from './__generated__/FlightServicesMenuItem.graphql';
 
@@ -17,8 +16,8 @@ type Props = {|
 
 export const FlightServicesMenuItem = (props: Props) => {
   const hasFlights = props.data.some(trip => {
-    const legs = idx(trip, _ => _.legs) || [];
-    return legs.some(leg => idx(leg, _ => _.type) === 'AIRCRAFT');
+    const legs = trip.legs ?? [];
+    return legs.some(leg => leg?.type === 'AIRCRAFT');
   });
   if (hasFlights === false) {
     return null;
diff --git a/app/MMB/src/navigation/AddressPickerScreen.js b/app/MMB/src/navigation/AddressPickerScreen.js
index 708797c7..2c235357 100644
--- a/app/MMB/src/navigation/AddressPickerScreen.js
+++ b/app/MMB/src/navigation/AddressPickerScreen.js
@@ -1,7 +1,6 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
-import idx from 'idx';
 import { View, ScrollView } from 'react-native';
 import { Translation } from '@kiwicom/mobile-localization';
 import { HeaderButton, type NavigationType } from '@kiwicom/mobile-navigation';
@@ -78,10 +77,10 @@ export class AddressPickerScreen extends React.Component<Props, State> {
     this.updateFormattedAddress(coordinate);
   }
 
-  componentDidUpdate = () => {
+  componentDidUpdate() {
     const coordinate = this.getCoordinate();
     this.updateFormattedAddress(coordinate);
-  };
+  }
 
   getCoordinate = () =>
     this.props.lat != null && this.props.lng != null
@@ -109,9 +108,8 @@ export class AddressPickerScreen extends React.Component<Props, State> {
   };
 
   render() {
-    const searchText =
-      idx(this.props.navigation, _ => _.state.params.searchText) || '';
-    const region = idx(this.props.navigation, _ => _.state.params.region);
+    const searchText = this.props.navigation.state.params.searchText ?? '';
+    const region = this.props.navigation.state.params.region;
     return (
       <ScrollView
         keyboardDismissMode="on-drag"
diff --git a/app/hotels/src/HotelsContext.js b/app/hotels/src/HotelsContext.js
index 4383b1b8..89dad40f 100644
--- a/app/hotels/src/HotelsContext.js
+++ b/app/hotels/src/HotelsContext.js
@@ -30,7 +30,7 @@ const { Consumer, Provider: ContextProvider } = React.createContext({
 
 export type RoomConfigurationType = $ReadOnlyArray<{|
   +adultsCount: number,
-  +children: $ReadOnlyArray<{|
+  +children?: $ReadOnlyArray<{|
     +age: number,
   |}>,
 |}>;
@@ -118,7 +118,7 @@ class Provider extends React.Component<Props, State> {
     }
     return this.state.roomsConfiguration.reduce((sum, current) => {
       const adults = current.adultsCount;
-      const children = current?.children?.length ?? 0;
+      const children = current.children?.length ?? 0;
       return sum + adults + children;
     }, 0);
   };
diff --git a/app/hotels/src/allHotels/AllHotelsSearchList.js b/app/hotels/src/allHotels/AllHotelsSearchList.js
index e56208a2..547001aa 100644
--- a/app/hotels/src/allHotels/AllHotelsSearchList.js
+++ b/app/hotels/src/allHotels/AllHotelsSearchList.js
@@ -4,7 +4,6 @@ import * as React from 'react';
 import { GeneralError } from '@kiwicom/mobile-shared';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
 import { Translation } from '@kiwicom/mobile-localization';
-import idx from 'idx';
 
 import AllHotelsSearchRow from './AllHotelsSearchRow';
 import type { AllHotelsSearchList as AllHotelsSearchListProps } from './__generated__/AllHotelsSearchList.graphql';
@@ -16,13 +15,15 @@ type PropsWithContext = {|
 |};
 
 export class AllHotelsSearchList extends React.Component<PropsWithContext> {
-  componentDidMount = () => {
-    const hotelId = idx(this.props.data, _ => _[0].hotelId);
+  componentDidMount() {
+    const hotelId = this.props.data[0].hotelId;
+
     if (hotelId != null) {
       this.props.setHotelId(hotelId);
     }
-  };
-  render = () => {
+  }
+
+  render() {
     const hotels = this.props.data || [];
 
     if (hotels.length === 0) {
@@ -39,14 +40,14 @@ export class AllHotelsSearchList extends React.Component<PropsWithContext> {
       <React.Fragment>
         {hotels.map((hotel, index) => (
           <AllHotelsSearchRow
-            key={idx(hotel, _ => _.id)}
+            key={hotel.id}
             data={hotel}
             testID={index === 0 ? 'firstHotelResult' : ''}
           />
         ))}
       </React.Fragment>
     );
-  };
+  }
 }
 
 type Props = {|
diff --git a/app/hotels/src/allHotels/AllHotelsSearchRow.js b/app/hotels/src/allHotels/AllHotelsSearchRow.js
index 042af9fa..a3457978 100644
--- a/app/hotels/src/allHotels/AllHotelsSearchRow.js
+++ b/app/hotels/src/allHotels/AllHotelsSearchRow.js
@@ -1,7 +1,6 @@
 // @flow strict
 
 import * as React from 'react';
-import idx from 'idx';
 import { View } from 'react-native';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
 import {
@@ -36,10 +35,10 @@ type PropsWithContext = {|
 
 class AllHotelsSearchRow extends React.Component<PropsWithContext> {
   onGoToSingleHotel = () => {
-    const hotelId = idx(this.props, _ => _.data.hotelId);
+    const hotelId = this.props.data.hotelId;
     if (hotelId != null) {
+      this.props.setHotelId(hotelId);
       this.props.navigation.navigate('SingleHotel', {
-        hotelId,
         checkin: this.props.checkin,
         checkout: this.props.checkout,
         roomsConfiguration: this.props.roomsConfiguration,
@@ -49,12 +48,12 @@ class AllHotelsSearchRow extends React.Component<PropsWithContext> {
   };
 
   setActiveHotelId = () => {
-    const hotelId = idx(this.props, _ => _.data.hotelId) || '';
+    const hotelId = this.props.data.hotelId ?? '';
     this.props.setHotelId(hotelId);
   };
 
   render = () => {
-    const highResUrl = idx(this.props.data, _ => _.mainPhoto.highResUrl);
+    const highResUrl = this.props.data.mainPhoto?.highResUrl;
     const children = (
       <View style={style.row}>
         <View style={style.imageContainer}>
@@ -70,9 +69,7 @@ class AllHotelsSearchRow extends React.Component<PropsWithContext> {
               <HotelTitle data={this.props.data} />
             </View>
             <View style={style.hotelReviewScore}>
-              <HotelReviewScore
-                score={idx(this.props.data, _ => _.review.score)}
-              />
+              <HotelReviewScore score={this.props.data.review?.score} />
             </View>
           </View>
         </View>
diff --git a/app/hotels/src/allHotels/HotelDistance.js b/app/hotels/src/allHotels/HotelDistance.js
index e80e9027..5b6ec3b8 100644
--- a/app/hotels/src/allHotels/HotelDistance.js
+++ b/app/hotels/src/allHotels/HotelDistance.js
@@ -1,10 +1,9 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
 import { StyleSheet, Text } from '@kiwicom/mobile-shared';
 import { Translation } from '@kiwicom/mobile-localization';
-import idx from 'idx';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 
 import type { HotelDistance_hotel } from './__generated__/HotelDistance_hotel.graphql';
@@ -17,51 +16,62 @@ type Props = {|
 const CITY_CENTER_RADIUS = 1.5;
 
 function HotelDistance({ hotel }: Props) {
-  const distance = idx(hotel, _ => _.distanceFromCenter) || null;
+  const distance = hotel.distanceFromCenter ?? null;
+
   if (distance === null) {
     return null;
   }
 
   return (
     <Text style={style.text}>
-      <Translation
-        passThrough={getDistanceText(distance, CITY_CENTER_RADIUS)}
-      />
+      {getDistanceText(distance, CITY_CENTER_RADIUS)}
     </Text>
   );
 }
 
-const style = StyleSheet.create({
-  text: {
-    letterSpacing: 0.2,
-    color: defaultTokens.colorTextSecondary,
-    fontSize: 12,
-    lineHeight: 15,
-  },
-});
-
 export function getDistanceText(
   distanceFromCenter: number,
   cityCenterRadius: number,
 ) {
   const distanceFromCityCenter = distanceFromCenter - cityCenterRadius;
-  let distanceText = '';
+  let distanceText = <Translation passThrough="" />;
 
   if (distanceFromCenter <= cityCenterRadius) {
-    distanceText = 'In the city center';
+    distanceText = (
+      <Translation id="hotels_search.hotel_distance.in_city_center" />
+    );
   } else if (distanceFromCityCenter < 1) {
     // 1 km from city center radius shows in meters
     // Round up to 100 m
     const distanceInMeters = distanceFromCityCenter * 1000;
     const roundedDistanceInMeters = 100 * Math.ceil(distanceInMeters / 100);
-    distanceText = `${roundedDistanceInMeters}m from center`;
+    distanceText = (
+      <Translation
+        id="hotels_search.hotel_distance.meters_from_center"
+        values={{ distance: roundedDistanceInMeters }}
+      />
+    );
   } else {
-    distanceText = `${distanceFromCityCenter.toFixed(1)}km from center`;
+    distanceText = (
+      <Translation
+        id="hotels_search.hotel_distance.kilo_meters_from_center"
+        values={{ distance: distanceFromCityCenter.toFixed(1) }}
+      />
+    );
   }
 
   return distanceText;
 }
 
+const style = StyleSheet.create({
+  text: {
+    letterSpacing: 0.2,
+    color: defaultTokens.colorTextSecondary,
+    fontSize: 12,
+    lineHeight: 15,
+  },
+});
+
 export default createFragmentContainer(
   HotelDistance,
   graphql`
diff --git a/app/hotels/src/allHotels/HotelTitle.js b/app/hotels/src/allHotels/HotelTitle.js
index 8825ddc3..57b5147c 100644
--- a/app/hotels/src/allHotels/HotelTitle.js
+++ b/app/hotels/src/allHotels/HotelTitle.js
@@ -1,7 +1,6 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
-import idx from 'idx';
 import { View } from 'react-native';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
 import { Price, Stars, Text, StyleSheet } from '@kiwicom/mobile-shared';
@@ -16,15 +15,13 @@ type Props = {|
 |};
 
 function HotelTitle({ data }: Props) {
-  const hotelName = idx(data, _ => _.name);
-  const hotelStars = idx(data, _ => _.rating.stars);
-
-  const price = data.price || null;
+  const hotelName = data.name ?? '';
+  const hotelStars = data.rating?.stars;
 
   return (
     <React.Fragment>
       <Text style={style.title}>
-        <Translation passThrough={`${hotelName || ''} `} />
+        <Translation passThrough={`${hotelName} `} />
         <Text style={style.rating}>
           <Stars rating={hotelStars} />
         </Text>
@@ -33,7 +30,7 @@ function HotelTitle({ data }: Props) {
       <View style={style.distance}>
         <Distance hotel={data} />
       </View>
-      <Price price={price} style={style.price} />
+      <Price price={data.price} style={style.price} />
     </React.Fragment>
   );
 }
diff --git a/app/hotels/src/allHotels/HotelsPaginationContainer.js b/app/hotels/src/allHotels/HotelsPaginationContainer.js
index 0799b0e2..219d545a 100644
--- a/app/hotels/src/allHotels/HotelsPaginationContainer.js
+++ b/app/hotels/src/allHotels/HotelsPaginationContainer.js
@@ -7,7 +7,6 @@ import {
   type RelayPaginationProp,
 } from '@kiwicom/mobile-relay';
 import { Logger } from '@kiwicom/mobile-shared';
-import idx from 'idx';
 
 import type { HotelsPaginationContainer as HotelsPaginationContainerType } from './__generated__/HotelsPaginationContainer.graphql';
 import HotelsContext from '../HotelsContext';
@@ -35,20 +34,16 @@ export class HotelsPaginationContainer extends React.Component<
     };
   }
 
-  componentDidMount = () => {
+  componentDidMount() {
     Logger.ancillaryDisplayed(
       Logger.Type.ANCILLARY_STEP_RESULTS,
       Logger.Provider.ANCILLARY_PROVIDER_BOOKINGCOM,
     );
 
-    const priceMax = idx(
-      this.props,
-      _ => _.data.allAvailableBookingComHotels.stats.maxPrice,
-    );
-    const priceMin = idx(
-      this.props,
-      _ => _.data.allAvailableBookingComHotels.stats.minPrice,
-    );
+    const priceMax = this.props.data.allAvailableBookingComHotels?.stats
+      ?.maxPrice;
+    const priceMin = this.props.data.allAvailableBookingComHotels?.stats
+      ?.minPrice;
 
     if (priceMax != null && priceMin != null) {
       this.props.setCurrentSearchStats({
@@ -56,7 +51,7 @@ export class HotelsPaginationContainer extends React.Component<
         priceMin,
       });
     }
-  };
+  }
 
   loadMore = () => {
     if (this.props.relay.hasMore() && !this.props.relay.isLoading()) {
@@ -68,10 +63,9 @@ export class HotelsPaginationContainer extends React.Component<
     }
   };
 
-  render = () => {
-    const edges =
-      idx(this.props.data, _ => _.allAvailableBookingComHotels.edges) || [];
-    const data = edges.map(hotel => idx(hotel, _ => _.node));
+  render() {
+    const edges = this.props.data.allAvailableBookingComHotels?.edges ?? [];
+    const data = edges.map(hotel => hotel?.node);
 
     return (
       <RenderSearchResults
@@ -82,7 +76,7 @@ export class HotelsPaginationContainer extends React.Component<
         top={56}
       />
     );
-  };
+  }
 }
 
 type Props = {|
diff --git a/app/hotels/src/allHotels/LoadMoreButton.js b/app/hotels/src/allHotels/LoadMoreButton.js
index af475e99..a12013a8 100644
--- a/app/hotels/src/allHotels/LoadMoreButton.js
+++ b/app/hotels/src/allHotels/LoadMoreButton.js
@@ -1,4 +1,4 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { View } from 'react-native';
diff --git a/app/hotels/src/allHotels/NewAllHotelsSearch.js b/app/hotels/src/allHotels/NewAllHotelsSearch.js
index c5bf6f03..8177b67b 100644
--- a/app/hotels/src/allHotels/NewAllHotelsSearch.js
+++ b/app/hotels/src/allHotels/NewAllHotelsSearch.js
@@ -1,4 +1,4 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { graphql, PublicApiRenderer } from '@kiwicom/mobile-relay';
diff --git a/app/hotels/src/allHotels/Stay22HotelsSearch.js b/app/hotels/src/allHotels/Stay22HotelsSearch.js
index 0c9dcdb3..7694b55c 100644
--- a/app/hotels/src/allHotels/Stay22HotelsSearch.js
+++ b/app/hotels/src/allHotels/Stay22HotelsSearch.js
@@ -1,4 +1,4 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { graphql, PublicApiRenderer } from '@kiwicom/mobile-relay';
diff --git a/app/hotels/src/allHotels/Stay22PaginationContainer.js b/app/hotels/src/allHotels/Stay22PaginationContainer.js
index 96fb93e5..4c7fe564 100644
--- a/app/hotels/src/allHotels/Stay22PaginationContainer.js
+++ b/app/hotels/src/allHotels/Stay22PaginationContainer.js
@@ -8,7 +8,6 @@ import {
   type RelayPaginationProp,
 } from '@kiwicom/mobile-relay';
 import { Logger } from '@kiwicom/mobile-shared';
-import idx from 'idx';
 
 import type { Stay22PaginationContainer as Stay22PaginationContainerType } from './__generated__/Stay22PaginationContainer.graphql';
 import HotelsContext from '../HotelsContext';
@@ -39,13 +38,13 @@ export class Stay22PaginationContainer extends React.Component<
     };
   }
 
-  componentDidMount = () => {
+  componentDidMount() {
     Logger.ancillaryDisplayed(
       Logger.Type.ANCILLARY_STEP_RESULTS,
       Logger.Provider.ANCILLARY_PROVIDER_STAY22,
     );
     // TODO: Set min max price here when supported by API
-  };
+  }
 
   loadMore = () => {
     if (this.props.relay.hasMore() && !this.props.relay.isLoading()) {
@@ -57,10 +56,9 @@ export class Stay22PaginationContainer extends React.Component<
     }
   };
 
-  render = () => {
-    const edges =
-      idx(this.props.data, _ => _.allAvailableStay22Hotels.edges) || [];
-    const data = edges.map(hotel => idx(hotel, _ => _.node));
+  render() {
+    const edges = this.props.data.allAvailableStay22Hotels?.edges ?? [];
+    const data = edges.map(hotel => hotel?.node);
 
     return (
       <RenderSearchResults
@@ -71,7 +69,7 @@ export class Stay22PaginationContainer extends React.Component<
         top={0}
       />
     );
-  };
+  }
 }
 
 type Props = {|
diff --git a/app/hotels/src/appRegistry/NewHotelsStandalonePackage.js b/app/hotels/src/appRegistry/NewHotelsStandalonePackage.js
index b6dc3ef0..62fb14e9 100644
--- a/app/hotels/src/appRegistry/NewHotelsStandalonePackage.js
+++ b/app/hotels/src/appRegistry/NewHotelsStandalonePackage.js
@@ -4,10 +4,12 @@ import * as React from 'react';
 import {
   WithNativeNavigation,
   type DimensionType,
+  AdaptableLayout,
 } from '@kiwicom/mobile-shared';
 
 import RootComponent from './RootComponent';
 import HotelsStack from '../navigation/HotelsNavigationStack';
+import HotelsTabletStack from '../navigation/HotelsTabletStack';
 import type { Coordinates } from '../CoordinatesType';
 import type { RoomConfigurationType } from '../HotelsContext';
 
@@ -33,29 +35,35 @@ class NewHotelsStandalonePackage extends React.Component<Props> {
   static navigationOptions = {
     tabBarVisible: false,
   };
-  render = () => (
-    <RootComponent
-      dimensions={this.props.dimensions}
-      dataSaverEnabled={this.props.dataSaverEnabled}
-      version={this.props.version}
-      cityId={this.props.cityId}
-      checkin={this.props.checkin}
-      checkout={this.props.checkout}
-      currency={this.props.currency}
-      roomsConfiguration={this.props.roomsConfiguration}
-      cityName={this.props.cityName}
-      coordinates={this.props.coordinates}
-      // Stay 22 only supports searching with gps coordinates, if we get passed a cityId from native
-      // we are using booking.com, if we don't get cityId, we should have coordinates, and we are using stay22 provider
-      apiProvider={this.props.cityId == null ? 'stay22' : 'booking'}
-    >
-      <HotelsStack
-        screenProps={this.props}
-        onBackClicked={this.props.onBackClicked}
-        onNavigationStateChange={this.props.onNavigationStateChange}
-      />
-    </RootComponent>
-  );
+  render() {
+    const props = {
+      screenProps: this.props,
+      onBackClicked: this.props.onBackClicked,
+      onNavigationStateChange: this.props.onNavigationStateChange,
+    };
+    return (
+      <RootComponent
+        dimensions={this.props.dimensions}
+        dataSaverEnabled={this.props.dataSaverEnabled}
+        version={this.props.version}
+        cityId={this.props.cityId}
+        checkin={this.props.checkin}
+        checkout={this.props.checkout}
+        currency={this.props.currency}
+        roomsConfiguration={this.props.roomsConfiguration}
+        cityName={this.props.cityName}
+        coordinates={this.props.coordinates}
+        // Stay 22 only supports searching with gps coordinates, if we get passed a cityId from native
+        // we are using booking.com, if we don't get cityId, we should have coordinates, and we are using stay22 provider
+        apiProvider={this.props.cityId == null ? 'stay22' : 'booking'}
+      >
+        <AdaptableLayout
+          renderOnNarrow={<HotelsStack {...props} />}
+          renderOnWide={<HotelsTabletStack {...props} />}
+        />
+      </RootComponent>
+    );
+  }
 }
 
 export default WithNativeNavigation(
diff --git a/app/hotels/src/map/Address.js b/app/hotels/src/map/Address.js
index 9795d6fd..ec5e2da7 100644
--- a/app/hotels/src/map/Address.js
+++ b/app/hotels/src/map/Address.js
@@ -1,7 +1,6 @@
 // @flow strict
 
 import * as React from 'react';
-import idx from 'idx';
 import { View } from 'react-native';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
 import { TextIcon, StyleSheet, Text } from '@kiwicom/mobile-shared';
@@ -20,10 +19,10 @@ type Props = {
 };
 
 class Address extends React.Component<Props> {
-  render = () => {
-    const street = idx(this.props, _ => _.address.street) || '';
-    const city = idx(this.props, _ => _.address.city) || '';
-    const zip = idx(this.props, _ => _.address.zip) || '';
+  render() {
+    const street = this.props.address?.street ?? '';
+    const city = this.props.address?.city ?? '';
+    const zip = this.props.address?.zip ?? '';
 
     return (
       <View style={styles.container}>
@@ -40,7 +39,7 @@ class Address extends React.Component<Props> {
         </View>
       </View>
     );
-  };
+  }
 }
 
 export default (createFragmentContainer(
diff --git a/app/hotels/src/map/allHotels/HotelSwipeItem.js b/app/hotels/src/map/allHotels/HotelSwipeItem.js
index eadc900b..74cb7628 100644
--- a/app/hotels/src/map/allHotels/HotelSwipeItem.js
+++ b/app/hotels/src/map/allHotels/HotelSwipeItem.js
@@ -3,7 +3,6 @@
 import * as React from 'react';
 import { View } from 'react-native';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
-import idx from 'idx';
 import {
   withNavigation,
   type NavigationType,
@@ -33,6 +32,7 @@ export class HotelSwipeItemWithContext extends React.Component<
   PropsWithContext,
 > {
   openSingleHotel = (hotelId: string) => {
+    this.props.setHotelId(hotelId);
     this.props.navigation.navigate('SingleHotel', {
       hotelId,
       checkin: this.props.checkin,
@@ -47,7 +47,7 @@ export class HotelSwipeItemWithContext extends React.Component<
 
   handlePress = () => {
     const { data } = this.props;
-    const id = idx(data, _ => _.hotelId);
+    const id = data?.hotelId;
 
     if (id != null) {
       this.isNarrowLayout()
@@ -58,11 +58,11 @@ export class HotelSwipeItemWithContext extends React.Component<
 
   render = () => {
     const { width, data } = this.props;
-    const name = idx(data, _ => _.name);
-    const price = idx(data, _ => _.price);
-    const thumbnailUrl = idx(data, _ => _.mainPhoto.thumbnailUrl);
-    const stars = idx(data, _ => _.rating.stars);
-    const score = idx(data, _ => _.review.score);
+    const name = data?.name;
+    const price = data?.price;
+    const thumbnailUrl = data?.mainPhoto?.thumbnailUrl;
+    const stars = data?.rating?.stars;
+    const score = data?.review?.score;
     return (
       <TouchableWithoutFeedback onPress={this.handlePress}>
         <View style={{ width }}>
diff --git a/app/hotels/src/map/allHotels/HotelSwipeList.js b/app/hotels/src/map/allHotels/HotelSwipeList.js
index 41c6c348..e393ab7e 100644
--- a/app/hotels/src/map/allHotels/HotelSwipeList.js
+++ b/app/hotels/src/map/allHotels/HotelSwipeList.js
@@ -11,7 +11,6 @@ import {
   type OnLayout,
 } from '@kiwicom/mobile-shared';
 import { Translation } from '@kiwicom/mobile-localization';
-import idx from 'idx';
 
 import HotelSwipeItem from './HotelSwipeItem';
 import Address from '../Address';
@@ -40,16 +39,16 @@ class HotelSwipeList extends React.Component<Props, State> {
     containerWidth: 0,
   };
 
-  componentDidUpdate = () => {
+  componentDidUpdate() {
     if (this.carouselRef) {
       this.carouselRef.snapToItem(this.props.selectedIndex, false);
     }
-  };
+  }
 
   getSelectedAddress = () => {
     const { selectedIndex, data } = this.props;
 
-    return idx(data, _ => _[selectedIndex].address) || {};
+    return data[selectedIndex].address ?? {};
   };
 
   renderItem = ({ item }: { item: Object, index: number }) => {
@@ -67,7 +66,7 @@ class HotelSwipeList extends React.Component<Props, State> {
     });
   };
 
-  render = () => {
+  render() {
     const { data, onSnapToItem } = this.props;
 
     return (
@@ -105,7 +104,7 @@ class HotelSwipeList extends React.Component<Props, State> {
         </HotelPreviewProvider>
       </View>
     );
-  };
+  }
 }
 
 const styles = StyleSheet.create({
diff --git a/app/hotels/src/map/allHotels/MapScreen.js b/app/hotels/src/map/allHotels/MapScreen.js
index 08e7c2a5..5a9aac77 100644
--- a/app/hotels/src/map/allHotels/MapScreen.js
+++ b/app/hotels/src/map/allHotels/MapScreen.js
@@ -1,4 +1,4 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { View } from 'react-native';
@@ -9,7 +9,6 @@ import {
   Dimensions,
   Device,
 } from '@kiwicom/mobile-shared';
-import idx from 'idx';
 
 import SingleHotelContext from '../../navigation/singleHotel/SingleHotelContext';
 import MapView from './MapView';
@@ -51,7 +50,7 @@ class MapScreenWithContext extends React.Component<PropsWithContext, State> {
 
   onSelectMarker = (hotelId: string) => {
     const hotels = this.getHotels();
-    const index = hotels.findIndex(hotel => idx(hotel, _ => _.id) === hotelId);
+    const index = hotels.findIndex(hotel => hotel.id === hotelId);
 
     if (index !== -1) {
       this.handleActiveIndex(index, hotels);
@@ -60,7 +59,7 @@ class MapScreenWithContext extends React.Component<PropsWithContext, State> {
 
   handleActiveIndex = (index: number, hotels: MapScreenData) => {
     if (!this.isNarrowLayout()) {
-      const hotelHotelId = idx(hotels[index], _ => _.hotelId);
+      const hotelHotelId = hotels[index].hotelId;
       hotelHotelId != null && this.props.setHotelId(hotelHotelId);
     }
     this.selectMarker(index);
diff --git a/app/hotels/src/map/allHotels/MapView.js b/app/hotels/src/map/allHotels/MapView.js
index fc9d884f..2f5a8fbb 100644
--- a/app/hotels/src/map/allHotels/MapView.js
+++ b/app/hotels/src/map/allHotels/MapView.js
@@ -1,6 +1,5 @@
 // @flow
 
-import idx from 'idx';
 import * as React from 'react';
 import MapView from 'react-native-maps';
 import { orderByDistance, getBounds } from 'geolib';
@@ -61,20 +60,20 @@ export class Map extends React.Component<Props, State> {
     };
   }
 
-  componentDidMount = () => {
+  componentDidMount() {
     const { selectedIndex } = this.props;
     // it's necessary to call showCallout to bring selected marker to foreground
     this.markers[selectedIndex] && this.markers[selectedIndex].showCallout();
-  };
+  }
 
-  componentDidUpdate = () => {
+  componentDidUpdate() {
     this.animateToCoordinate(this.props.selectedIndex);
     this.markers[this.props.selectedIndex] &&
       this.markers[this.props.selectedIndex].showCallout();
-  };
+  }
 
   getCoordinate = (hotel: Object): LatLng | null => {
-    const coordinate = idx(hotel, _ => _.coordinates);
+    const coordinate = hotel?.coordinates;
 
     if (coordinate) {
       return {
@@ -182,8 +181,8 @@ export class Map extends React.Component<Props, State> {
 
   renderHotelMarker = (hotel: Object, index: number) => {
     const { selectedIndex } = this.props;
-    const price = idx(hotel, _ => _.price);
-    const id = idx(hotel, _ => _.id);
+    const price = hotel?.price;
+    const id = hotel?.id;
     const coordinate = this.getCoordinate(hotel);
 
     return (
diff --git a/app/hotels/src/map/hotelDetailPreview/HotelDetailPreview.js b/app/hotels/src/map/hotelDetailPreview/HotelDetailPreview.js
index 87b0915c..acfe35f7 100644
--- a/app/hotels/src/map/hotelDetailPreview/HotelDetailPreview.js
+++ b/app/hotels/src/map/hotelDetailPreview/HotelDetailPreview.js
@@ -10,7 +10,6 @@ import {
   Stars,
 } from '@kiwicom/mobile-shared';
 import { Translation } from '@kiwicom/mobile-localization';
-import idx from 'idx';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 
 import {
@@ -32,11 +31,11 @@ type Props = {|
 
 export default class HotelDetailPreview extends React.Component<Props> {
   renderInner = ({ containerWidth }: HotelDetailState) => {
-    const name = idx(this.props, _ => _.name);
-    const price = idx(this.props, _ => _.price) || {};
-    const image = idx(this.props, _ => _.thumbnailUrl);
-    const stars = idx(this.props, _ => _.stars) || 0;
-    const score = idx(this.props, _ => _.score);
+    const name = this.props.name;
+    const price = this.props.price;
+    const image = this.props.thumbnailUrl;
+    const stars = this.props.stars ?? 0;
+    const score = this.props.score;
     return (
       <View style={[styles.container, { width: containerWidth }]}>
         <View>
@@ -55,7 +54,7 @@ export default class HotelDetailPreview extends React.Component<Props> {
           <View style={styles.row}>
             <View>
               {stars > 0 && <Stars rating={stars} style={styles.stars} />}
-              {price != null && <Price price={price} style={styles.price} />}
+              <Price price={price} style={styles.price} />
             </View>
             <HotelReviewScore score={score} />
           </View>
diff --git a/app/hotels/src/map/singleHotel/AdditionalInfo.js b/app/hotels/src/map/singleHotel/AdditionalInfo.js
index 9100680d..0eb2c69f 100644
--- a/app/hotels/src/map/singleHotel/AdditionalInfo.js
+++ b/app/hotels/src/map/singleHotel/AdditionalInfo.js
@@ -1,7 +1,6 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
-import idx from 'idx';
 import { View } from 'react-native';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
 import { StyleSheet, type OnLayout, Device } from '@kiwicom/mobile-shared';
@@ -34,11 +33,11 @@ export class AdditionalInfo extends React.Component<Props, State> {
 
   render() {
     const { data } = this.props;
-    const name = idx(data, _ => _.hotel.name);
-    const price = idx(data, _ => _.price);
-    const thumbnailUrl = idx(data, _ => _.hotel.mainPhoto.thumbnailUrl);
-    const stars = idx(data, _ => _.hotel.rating.stars);
-    const score = idx(data, _ => _.hotel.review.score);
+    const name = data?.hotel?.name;
+    const price = data?.price;
+    const thumbnailUrl = data?.hotel?.mainPhoto?.thumbnailUrl;
+    const stars = data?.hotel?.rating?.stars;
+    const score = data?.hotel?.review?.score;
     return (
       <View style={styles.container} onLayout={this.onLayout}>
         <HotelPreviewProvider value={this.state}>
@@ -53,7 +52,7 @@ export class AdditionalInfo extends React.Component<Props, State> {
                 score={score}
               />
               <View style={styles.addressContainer}>
-                <Address address={idx(data, _ => _.hotel.address)} />
+                <Address address={data?.hotel?.address} />
               </View>
             </View>
           </BottomSheet>
@@ -85,7 +84,7 @@ const styles = StyleSheet.create({
 export default createFragmentContainer(
   AdditionalInfo,
   graphql`
-    fragment AdditionalInfo on HotelAvailability {
+    fragment AdditionalInfo on HotelAvailabilityInterface {
       price {
         amount
         currency
diff --git a/app/hotels/src/map/singleHotel/MapView.js b/app/hotels/src/map/singleHotel/MapView.js
index e6aac895..5a32a2fb 100644
--- a/app/hotels/src/map/singleHotel/MapView.js
+++ b/app/hotels/src/map/singleHotel/MapView.js
@@ -1,7 +1,6 @@
 // @flow
 
 import * as React from 'react';
-import idx from 'idx';
 import NativeMapView from 'react-native-maps';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
 import { DropMarker, StyleSheet } from '@kiwicom/mobile-shared';
@@ -20,8 +19,8 @@ type Props = {
 export class MapView extends React.Component<Props> {
   render() {
     const { hotel } = this.props;
-    const latitude = idx(hotel, _ => _.coordinates.lat);
-    const longitude = idx(hotel, _ => _.coordinates.lng);
+    const latitude = hotel?.coordinates?.lat;
+    const longitude = hotel?.coordinates?.lng;
 
     return (
       <NativeMapView
@@ -44,7 +43,7 @@ export class MapView extends React.Component<Props> {
 export default (createFragmentContainer(
   MapView,
   graphql`
-    fragment MapView_hotel on Hotel {
+    fragment MapView_hotel on HotelInterface {
       coordinates {
         lat
         lng
diff --git a/app/hotels/src/map/singleHotel/SingleHotelMapScreen.js b/app/hotels/src/map/singleHotel/SingleHotelMapScreen.js
index 3dda870b..cf58ed28 100644
--- a/app/hotels/src/map/singleHotel/SingleHotelMapScreen.js
+++ b/app/hotels/src/map/singleHotel/SingleHotelMapScreen.js
@@ -1,27 +1,18 @@
 // @flow
 
 import * as React from 'react';
-import idx from 'idx';
-import { View } from 'react-native';
 import { graphql, PublicApiRenderer } from '@kiwicom/mobile-relay';
-import {
-  StyleSheet,
-  CloseButton,
-  Device,
-  StretchedImage,
-} from '@kiwicom/mobile-shared';
 import {
   withNavigation,
   type NavigationType,
 } from '@kiwicom/mobile-navigation';
-import { defaultTokens } from '@kiwicom/mobile-orbit';
 
 import type { AvailableHotelSearchInput } from '../../singleHotel/AvailableHotelSearchInput';
-import MapView from './MapView';
 import type { SingleHotelMapScreenQueryResponse } from './__generated__/SingleHotelMapScreenQuery.graphql';
 import { sanitizeDate } from '../../GraphQLSanitizers';
-import AdditionalInfo from './AdditionalInfo';
-import gradient from '../gradient.png';
+import SingleMap from './SingleMap';
+import SingleHotelContext from '../../navigation/singleHotel/SingleHotelContext';
+import HotelsContext from '../../HotelsContext';
 
 type Props = {|
   +currency: string,
@@ -36,22 +27,14 @@ class SingleHotelMapScreen extends React.Component<Props> {
   renderInnerComponent = ({
     availableHotel,
   }: SingleHotelMapScreenQueryResponse) => (
-    <View style={styles.container}>
-      <MapView hotel={idx(availableHotel, _ => _.hotel)} />
-      <View style={styles.underlay}>
-        <StretchedImage source={gradient} />
-      </View>
-      <View style={styles.dropShadow}>
-        <AdditionalInfo data={availableHotel} />
-      </View>
-      <View style={styles.button}>
-        <CloseButton onPress={this.goBack} />
-      </View>
-    </View>
+    <SingleMap goBack={this.goBack} data={availableHotel} />
   );
 
-  render() {
-    const { search, currency } = this.props;
+  renderQuery = (currency, roomsConfiguration) => ({
+    checkin,
+    checkout,
+    hotelId,
+  }) => {
     return (
       <PublicApiRenderer
         query={graphql`
@@ -60,48 +43,37 @@ class SingleHotelMapScreen extends React.Component<Props> {
             $options: AvailableHotelOptionsInput
           ) {
             availableHotel(search: $search, options: $options) {
-              hotel {
-                ...MapView_hotel
-              }
-              ...AdditionalInfo
+              ...SingleMap
             }
           }
         `}
         variables={{
           search: {
-            ...search,
-            checkin: sanitizeDate(search.checkin),
-            checkout: sanitizeDate(search.checkout),
+            hotelId,
+            roomsConfiguration,
+            checkin: sanitizeDate(checkin),
+            checkout: sanitizeDate(checkout),
           },
           options: { currency },
         }}
         render={this.renderInnerComponent}
       />
     );
+  };
+
+  renderHotelsContext = ({ currency, roomsConfiguration }) => (
+    <SingleHotelContext.Consumer>
+      {this.renderQuery(currency, roomsConfiguration)}
+    </SingleHotelContext.Consumer>
+  );
+
+  render() {
+    return (
+      <HotelsContext.Consumer>
+        {this.renderHotelsContext}
+      </HotelsContext.Consumer>
+    );
   }
 }
 
-const styles = StyleSheet.create({
-  container: {
-    flex: 1,
-    justifyContent: 'flex-end',
-  },
-  button: {
-    position: 'absolute',
-    bottom: Device.isIPhoneX ? 36 : 8,
-    start: 8,
-    end: 8,
-  },
-  underlay: { height: 132 },
-  dropShadow: {
-    shadowColor: defaultTokens.paletteInkDark,
-    shadowOpacity: 0.2,
-    shadowOffset: { width: 0, height: 2 },
-    shadowRadius: 4,
-    android: {
-      elevation: 1,
-    },
-  },
-});
-
 export default withNavigation(SingleHotelMapScreen);
diff --git a/app/hotels/src/map/singleHotel/SingleMap.js b/app/hotels/src/map/singleHotel/SingleMap.js
new file mode 100644
index 00000000..46bb07c1
--- /dev/null
+++ b/app/hotels/src/map/singleHotel/SingleMap.js
@@ -0,0 +1,74 @@
+// @flow strict
+
+import * as React from 'react';
+import { View } from 'react-native';
+import { graphql, createFragmentContainer } from '@kiwicom/mobile-relay';
+import {
+  StyleSheet,
+  CloseButton,
+  Device,
+  StretchedImage,
+} from '@kiwicom/mobile-shared';
+import { defaultTokens } from '@kiwicom/mobile-orbit';
+
+import MapView from './MapView';
+import AdditionalInfo from './AdditionalInfo';
+import gradient from '../gradient.png';
+import type { SingleMap as HotelType } from './__generated__/SingleMap.graphql';
+
+type Props = {|
+  +goBack: () => void,
+  +data: HotelType,
+|};
+
+const SingleMap = (props: Props) => {
+  return (
+    <View style={styles.container}>
+      <MapView hotel={props.data.hotel} />
+      <View style={styles.underlay}>
+        <StretchedImage source={gradient} />
+      </View>
+      <View style={styles.dropShadow}>
+        <AdditionalInfo data={props.data} />
+      </View>
+      <View style={styles.button}>
+        <CloseButton onPress={props.goBack} />
+      </View>
+    </View>
+  );
+};
+
+const styles = StyleSheet.create({
+  container: {
+    flex: 1,
+    justifyContent: 'flex-end',
+  },
+  button: {
+    position: 'absolute',
+    bottom: Device.isIPhoneX ? 36 : 8,
+    start: 8,
+    end: 8,
+  },
+  underlay: { height: 132 },
+  dropShadow: {
+    shadowColor: defaultTokens.paletteInkDark,
+    shadowOpacity: 0.2,
+    shadowOffset: { width: 0, height: 2 },
+    shadowRadius: 4,
+    android: {
+      elevation: 1,
+    },
+  },
+});
+
+export default createFragmentContainer(
+  SingleMap,
+  graphql`
+    fragment SingleMap on HotelAvailabilityInterface {
+      hotel {
+        ...MapView_hotel
+      }
+      ...AdditionalInfo
+    }
+  `,
+);
diff --git a/app/hotels/src/map/singleHotel/Stay22SingleHotelMapScreen.js b/app/hotels/src/map/singleHotel/Stay22SingleHotelMapScreen.js
new file mode 100644
index 00000000..68019cef
--- /dev/null
+++ b/app/hotels/src/map/singleHotel/Stay22SingleHotelMapScreen.js
@@ -0,0 +1,78 @@
+// @flow
+
+import * as React from 'react';
+import { graphql, PublicApiRenderer } from '@kiwicom/mobile-relay';
+import {
+  withNavigation,
+  type NavigationType,
+} from '@kiwicom/mobile-navigation';
+
+import { sanitizeDate } from '../../GraphQLSanitizers';
+import SingleHotelContext from '../../navigation/singleHotel/SingleHotelContext';
+import HotelsContext from '../../HotelsContext';
+import type { Stay22SingleHotelMapScreenQueryResponse } from './__generated__/Stay22SingleHotelMapScreenQuery.graphql';
+import SingleMap from './SingleMap';
+
+type Props = {|
+  +navigation: NavigationType,
+|};
+
+class Stay22SingleHotelMapScreen extends React.Component<Props> {
+  goBack = () => {
+    this.props.navigation.goBack(null);
+  };
+
+  renderHotelContext = ({ getGuestCount, currency }) => (
+    <SingleHotelContext.Consumer>
+      {this.renderSingleHotelContext(getGuestCount, currency)}
+    </SingleHotelContext.Consumer>
+  );
+
+  renderSingleHotelContext = (getGuestCount, currency) => ({
+    hotelId,
+    checkin,
+    checkout,
+  }) => (
+    <PublicApiRenderer
+      query={graphql`
+        query Stay22SingleHotelMapScreenQuery(
+          $id: ID!
+          $guests: Int!
+          $currency: Currency
+          $checkin: Date!
+          $checkout: Date!
+        ) {
+          stay22HotelDetail(
+            id: $id
+            guests: $guests
+            currency: $currency
+            checkin: $checkin
+            checkout: $checkout
+          ) {
+            ...SingleMap
+          }
+        }
+      `}
+      variables={{
+        checkin: sanitizeDate(checkin),
+        checkout: sanitizeDate(checkout),
+        id: hotelId,
+        guests: getGuestCount(),
+        currency,
+      }}
+      render={this.renderInner}
+    />
+  );
+
+  renderInner = (props: Stay22SingleHotelMapScreenQueryResponse) => (
+    <SingleMap data={props.stay22HotelDetail} goBack={this.goBack} />
+  );
+
+  render() {
+    return (
+      <HotelsContext.Consumer>{this.renderHotelContext}</HotelsContext.Consumer>
+    );
+  }
+}
+
+export default withNavigation(Stay22SingleHotelMapScreen);
diff --git a/app/hotels/src/map/singleHotel/__generated__/AdditionalInfo.graphql.js b/app/hotels/src/map/singleHotel/__generated__/AdditionalInfo.graphql.js
index 7b2cdf4f..218049f1 100644
--- a/app/hotels/src/map/singleHotel/__generated__/AdditionalInfo.graphql.js
+++ b/app/hotels/src/map/singleHotel/__generated__/AdditionalInfo.graphql.js
@@ -40,7 +40,7 @@ export type AdditionalInfo = {|
 const node/*: ConcreteFragment*/ = {
   "kind": "Fragment",
   "name": "AdditionalInfo",
-  "type": "HotelAvailability",
+  "type": "HotelAvailabilityInterface",
   "metadata": null,
   "argumentDefinitions": [],
   "selections": [
@@ -75,7 +75,7 @@ const node/*: ConcreteFragment*/ = {
       "name": "hotel",
       "storageKey": null,
       "args": null,
-      "concreteType": "Hotel",
+      "concreteType": null,
       "plural": false,
       "selections": [
         {
@@ -167,5 +167,5 @@ const node/*: ConcreteFragment*/ = {
   ]
 };
 // prettier-ignore
-(node/*: any*/).hash = 'fb58f5cd722f8df8339c3034d88558a6';
+(node/*: any*/).hash = 'f96f53c45e6c3ee4ad30f1d0ae3a3527';
 module.exports = node;
diff --git a/app/hotels/src/map/singleHotel/__generated__/MapView_hotel.graphql.js b/app/hotels/src/map/singleHotel/__generated__/MapView_hotel.graphql.js
index d432f45f..252dd910 100644
--- a/app/hotels/src/map/singleHotel/__generated__/MapView_hotel.graphql.js
+++ b/app/hotels/src/map/singleHotel/__generated__/MapView_hotel.graphql.js
@@ -23,7 +23,7 @@ export type MapView_hotel = {|
 const node/*: ConcreteFragment*/ = {
   "kind": "Fragment",
   "name": "MapView_hotel",
-  "type": "Hotel",
+  "type": "HotelInterface",
   "metadata": null,
   "argumentDefinitions": [],
   "selections": [
@@ -55,5 +55,5 @@ const node/*: ConcreteFragment*/ = {
   ]
 };
 // prettier-ignore
-(node/*: any*/).hash = 'e27f572a2b782be72991ae55531f6c5f';
+(node/*: any*/).hash = '54d5eb1a9e793be8bced0c546d27f87b';
 module.exports = node;
diff --git a/app/hotels/src/map/singleHotel/__generated__/SingleHotelMapScreenQuery.graphql.js b/app/hotels/src/map/singleHotel/__generated__/SingleHotelMapScreenQuery.graphql.js
index 435d9a24..13da7dcf 100644
--- a/app/hotels/src/map/singleHotel/__generated__/SingleHotelMapScreenQuery.graphql.js
+++ b/app/hotels/src/map/singleHotel/__generated__/SingleHotelMapScreenQuery.graphql.js
@@ -1,6 +1,6 @@
 /**
  * @flow
- * @relayHash 9e60687c947b774bf8b57af9375193d6
+ * @relayHash b5ce6ca3f1712f723032f8b5d1eab09e
  */
 
 /* eslint-disable */
@@ -9,8 +9,7 @@
 
 /*::
 import type { ConcreteRequest } from 'relay-runtime';
-type AdditionalInfo$ref = any;
-type MapView_hotel$ref = any;
+type SingleMap$ref = any;
 export type Currency = "AED" | "AFN" | "ALL" | "AMD" | "ANG" | "AOA" | "ARS" | "AUD" | "AWG" | "AZN" | "BAM" | "BBD" | "BDT" | "BGN" | "BHD" | "BIF" | "BMD" | "BND" | "BOB" | "BOV" | "BRL" | "BSD" | "BTN" | "BWP" | "BYN" | "BZD" | "CAD" | "CDF" | "CHE" | "CHF" | "CHW" | "CLF" | "CLP" | "CNY" | "COP" | "COU" | "CRC" | "CUC" | "CUP" | "CVE" | "CZK" | "DJF" | "DKK" | "DOP" | "DZD" | "EGP" | "ERN" | "ETB" | "EUR" | "FJD" | "FKP" | "GBP" | "GEL" | "GHS" | "GIP" | "GMD" | "GNF" | "GTQ" | "GYD" | "HKD" | "HNL" | "HRK" | "HTG" | "HUF" | "IDR" | "ILS" | "INR" | "IQD" | "IRR" | "ISK" | "JMD" | "JOD" | "JPY" | "KES" | "KGS" | "KHR" | "KMF" | "KPW" | "KRW" | "KWD" | "KYD" | "KZT" | "LAK" | "LBP" | "LKR" | "LRD" | "LSL" | "LYD" | "MAD" | "MDL" | "MGA" | "MKD" | "MMK" | "MNT" | "MOP" | "MRU" | "MUR" | "MVR" | "MWK" | "MXN" | "MXV" | "MYR" | "MZN" | "NAD" | "NGN" | "NIO" | "NOK" | "NPR" | "NZD" | "OMR" | "PAB" | "PEN" | "PGK" | "PHP" | "PKR" | "PLN" | "PYG" | "QAR" | "RON" | "RSD" | "RUB" | "RWF" | "SAR" | "SBD" | "SCR" | "SDG" | "SEK" | "SGD" | "SHP" | "SLL" | "SOS" | "SRD" | "SSP" | "STN" | "SVC" | "SYP" | "SZL" | "THB" | "TJS" | "TMT" | "TND" | "TOP" | "TRY" | "TTD" | "TWD" | "TZS" | "UAH" | "UGX" | "USD" | "USN" | "UYI" | "UYU" | "UZS" | "VEF" | "VND" | "VUV" | "WST" | "XAF" | "XAG" | "XAU" | "XBA" | "XBB" | "XBC" | "XBD" | "XCD" | "XDR" | "XOF" | "XPD" | "XPF" | "XPT" | "XSU" | "XTS" | "XUA" | "XXX" | "YER" | "ZAR" | "ZMW" | "ZWL" | "%future added value";
 export type Language = "ar" | "bg" | "ca" | "cs" | "da" | "de" | "el" | "en" | "engb" | "enus" | "es" | "esar" | "et" | "fi" | "fr" | "he" | "hr" | "hu" | "id" | "is" | "it" | "ja" | "ko" | "lt" | "lv" | "ms" | "nl" | "no" | "pl" | "pt" | "ptbr" | "ptpt" | "ro" | "ru" | "sk" | "sl" | "sr" | "sv" | "th" | "tl" | "tr" | "uk" | "vi" | "zh" | "zhcn" | "zhtw" | "%future added value";
 export type OrderBy = "DISTANCE" | "POPULARITY" | "PRICE" | "RANKING" | "REVIEW_SCORE" | "STARS" | "%future added value";
@@ -38,10 +37,7 @@ export type SingleHotelMapScreenQueryVariables = {|
 |};
 export type SingleHotelMapScreenQueryResponse = {|
   +availableHotel: ?{|
-    +hotel: ?{|
-      +$fragmentRefs: MapView_hotel$ref
-    |},
-    +$fragmentRefs: AdditionalInfo$ref,
+    +$fragmentRefs: SingleMap$ref
   |}
 |};
 export type SingleHotelMapScreenQuery = {|
@@ -57,28 +53,34 @@ query SingleHotelMapScreenQuery(
   $options: AvailableHotelOptionsInput
 ) {
   availableHotel(search: $search, options: $options) {
-    hotel {
-      ...MapView_hotel
-      id
-    }
-    ...AdditionalInfo
+    ...SingleMap
+    id
+  }
+}
+
+fragment SingleMap on HotelAvailabilityInterface {
+  hotel {
+    __typename
+    ...MapView_hotel
     id
   }
+  ...AdditionalInfo
 }
 
-fragment MapView_hotel on Hotel {
+fragment MapView_hotel on HotelInterface {
   coordinates {
     lat
     lng
   }
 }
 
-fragment AdditionalInfo on HotelAvailability {
+fragment AdditionalInfo on HotelAvailabilityInterface {
   price {
     amount
     currency
   }
   hotel {
+    __typename
     address {
       ...Address_address
     }
@@ -145,7 +147,7 @@ return {
   "operationKind": "query",
   "name": "SingleHotelMapScreenQuery",
   "id": null,
-  "text": "query SingleHotelMapScreenQuery(\n  $search: AvailableHotelSearchInput!\n  $options: AvailableHotelOptionsInput\n) {\n  availableHotel(search: $search, options: $options) {\n    hotel {\n      ...MapView_hotel\n      id\n    }\n    ...AdditionalInfo\n    id\n  }\n}\n\nfragment MapView_hotel on Hotel {\n  coordinates {\n    lat\n    lng\n  }\n}\n\nfragment AdditionalInfo on HotelAvailability {\n  price {\n    amount\n    currency\n  }\n  hotel {\n    address {\n      ...Address_address\n    }\n    review {\n      score\n    }\n    id\n    name\n    mainPhoto {\n      thumbnailUrl\n      id\n    }\n    rating {\n      stars\n    }\n  }\n}\n\nfragment Address_address on Address {\n  street\n  city\n  zip\n}\n",
+  "text": "query SingleHotelMapScreenQuery(\n  $search: AvailableHotelSearchInput!\n  $options: AvailableHotelOptionsInput\n) {\n  availableHotel(search: $search, options: $options) {\n    ...SingleMap\n    id\n  }\n}\n\nfragment SingleMap on HotelAvailabilityInterface {\n  hotel {\n    __typename\n    ...MapView_hotel\n    id\n  }\n  ...AdditionalInfo\n}\n\nfragment MapView_hotel on HotelInterface {\n  coordinates {\n    lat\n    lng\n  }\n}\n\nfragment AdditionalInfo on HotelAvailabilityInterface {\n  price {\n    amount\n    currency\n  }\n  hotel {\n    __typename\n    address {\n      ...Address_address\n    }\n    review {\n      score\n    }\n    id\n    name\n    mainPhoto {\n      thumbnailUrl\n      id\n    }\n    rating {\n      stars\n    }\n  }\n}\n\nfragment Address_address on Address {\n  street\n  city\n  zip\n}\n",
   "metadata": {},
   "fragment": {
     "kind": "Fragment",
@@ -163,25 +165,9 @@ return {
         "concreteType": "HotelAvailability",
         "plural": false,
         "selections": [
-          {
-            "kind": "LinkedField",
-            "alias": null,
-            "name": "hotel",
-            "storageKey": null,
-            "args": null,
-            "concreteType": "Hotel",
-            "plural": false,
-            "selections": [
-              {
-                "kind": "FragmentSpread",
-                "name": "MapView_hotel",
-                "args": null
-              }
-            ]
-          },
           {
             "kind": "FragmentSpread",
-            "name": "AdditionalInfo",
+            "name": "SingleMap",
             "args": null
           }
         ]
@@ -208,9 +194,16 @@ return {
             "name": "hotel",
             "storageKey": null,
             "args": null,
-            "concreteType": "Hotel",
+            "concreteType": null,
             "plural": false,
             "selections": [
+              {
+                "kind": "ScalarField",
+                "alias": null,
+                "name": "__typename",
+                "args": null,
+                "storageKey": null
+              },
               {
                 "kind": "LinkedField",
                 "alias": null,
@@ -366,5 +359,5 @@ return {
 };
 })();
 // prettier-ignore
-(node/*: any*/).hash = '98d1dc98cd2b3fa571422d30bdde8086';
+(node/*: any*/).hash = 'ebdd43ba89c69e2d571a7e4a852b3f1c';
 module.exports = node;
diff --git a/app/hotels/src/map/singleHotel/__generated__/SingleMap.graphql.js b/app/hotels/src/map/singleHotel/__generated__/SingleMap.graphql.js
new file mode 100644
index 00000000..bcbc57d4
--- /dev/null
+++ b/app/hotels/src/map/singleHotel/__generated__/SingleMap.graphql.js
@@ -0,0 +1,57 @@
+/**
+ * @flow
+ */
+
+/* eslint-disable */
+
+'use strict';
+
+/*::
+import type { ConcreteFragment } from 'relay-runtime';
+type AdditionalInfo$ref = any;
+type MapView_hotel$ref = any;
+import type { FragmentReference } from "relay-runtime";
+declare export opaque type SingleMap$ref: FragmentReference;
+export type SingleMap = {|
+  +hotel: ?{|
+    +$fragmentRefs: MapView_hotel$ref
+  |},
+  +$fragmentRefs: AdditionalInfo$ref,
+  +$refType: SingleMap$ref,
+|};
+*/
+
+
+const node/*: ConcreteFragment*/ = {
+  "kind": "Fragment",
+  "name": "SingleMap",
+  "type": "HotelAvailabilityInterface",
+  "metadata": null,
+  "argumentDefinitions": [],
+  "selections": [
+    {
+      "kind": "LinkedField",
+      "alias": null,
+      "name": "hotel",
+      "storageKey": null,
+      "args": null,
+      "concreteType": null,
+      "plural": false,
+      "selections": [
+        {
+          "kind": "FragmentSpread",
+          "name": "MapView_hotel",
+          "args": null
+        }
+      ]
+    },
+    {
+      "kind": "FragmentSpread",
+      "name": "AdditionalInfo",
+      "args": null
+    }
+  ]
+};
+// prettier-ignore
+(node/*: any*/).hash = 'ef00405f0bd4f6acb78f36eaa583ea9b';
+module.exports = node;
diff --git a/app/hotels/src/map/singleHotel/__generated__/Stay22SingleHotelMapScreenQuery.graphql.js b/app/hotels/src/map/singleHotel/__generated__/Stay22SingleHotelMapScreenQuery.graphql.js
new file mode 100644
index 00000000..62783241
--- /dev/null
+++ b/app/hotels/src/map/singleHotel/__generated__/Stay22SingleHotelMapScreenQuery.graphql.js
@@ -0,0 +1,385 @@
+/**
+ * @flow
+ * @relayHash 036a915c3f5ac54d68f08d8feaf950f2
+ */
+
+/* eslint-disable */
+
+'use strict';
+
+/*::
+import type { ConcreteRequest } from 'relay-runtime';
+type SingleMap$ref = any;
+export type Currency = "AED" | "AFN" | "ALL" | "AMD" | "ANG" | "AOA" | "ARS" | "AUD" | "AWG" | "AZN" | "BAM" | "BBD" | "BDT" | "BGN" | "BHD" | "BIF" | "BMD" | "BND" | "BOB" | "BOV" | "BRL" | "BSD" | "BTN" | "BWP" | "BYN" | "BZD" | "CAD" | "CDF" | "CHE" | "CHF" | "CHW" | "CLF" | "CLP" | "CNY" | "COP" | "COU" | "CRC" | "CUC" | "CUP" | "CVE" | "CZK" | "DJF" | "DKK" | "DOP" | "DZD" | "EGP" | "ERN" | "ETB" | "EUR" | "FJD" | "FKP" | "GBP" | "GEL" | "GHS" | "GIP" | "GMD" | "GNF" | "GTQ" | "GYD" | "HKD" | "HNL" | "HRK" | "HTG" | "HUF" | "IDR" | "ILS" | "INR" | "IQD" | "IRR" | "ISK" | "JMD" | "JOD" | "JPY" | "KES" | "KGS" | "KHR" | "KMF" | "KPW" | "KRW" | "KWD" | "KYD" | "KZT" | "LAK" | "LBP" | "LKR" | "LRD" | "LSL" | "LYD" | "MAD" | "MDL" | "MGA" | "MKD" | "MMK" | "MNT" | "MOP" | "MRU" | "MUR" | "MVR" | "MWK" | "MXN" | "MXV" | "MYR" | "MZN" | "NAD" | "NGN" | "NIO" | "NOK" | "NPR" | "NZD" | "OMR" | "PAB" | "PEN" | "PGK" | "PHP" | "PKR" | "PLN" | "PYG" | "QAR" | "RON" | "RSD" | "RUB" | "RWF" | "SAR" | "SBD" | "SCR" | "SDG" | "SEK" | "SGD" | "SHP" | "SLL" | "SOS" | "SRD" | "SSP" | "STN" | "SVC" | "SYP" | "SZL" | "THB" | "TJS" | "TMT" | "TND" | "TOP" | "TRY" | "TTD" | "TWD" | "TZS" | "UAH" | "UGX" | "USD" | "USN" | "UYI" | "UYU" | "UZS" | "VEF" | "VND" | "VUV" | "WST" | "XAF" | "XAG" | "XAU" | "XBA" | "XBB" | "XBC" | "XBD" | "XCD" | "XDR" | "XOF" | "XPD" | "XPF" | "XPT" | "XSU" | "XTS" | "XUA" | "XXX" | "YER" | "ZAR" | "ZMW" | "ZWL" | "%future added value";
+export type Stay22SingleHotelMapScreenQueryVariables = {|
+  id: string,
+  guests: number,
+  currency?: ?Currency,
+  checkin: any,
+  checkout: any,
+|};
+export type Stay22SingleHotelMapScreenQueryResponse = {|
+  +stay22HotelDetail: ?{|
+    +$fragmentRefs: SingleMap$ref
+  |}
+|};
+export type Stay22SingleHotelMapScreenQuery = {|
+  variables: Stay22SingleHotelMapScreenQueryVariables,
+  response: Stay22SingleHotelMapScreenQueryResponse,
+|};
+*/
+
+
+/*
+query Stay22SingleHotelMapScreenQuery(
+  $id: ID!
+  $guests: Int!
+  $currency: Currency
+  $checkin: Date!
+  $checkout: Date!
+) {
+  stay22HotelDetail(id: $id, guests: $guests, currency: $currency, checkin: $checkin, checkout: $checkout) {
+    ...SingleMap
+    id
+  }
+}
+
+fragment SingleMap on HotelAvailabilityInterface {
+  hotel {
+    __typename
+    ...MapView_hotel
+    id
+  }
+  ...AdditionalInfo
+}
+
+fragment MapView_hotel on HotelInterface {
+  coordinates {
+    lat
+    lng
+  }
+}
+
+fragment AdditionalInfo on HotelAvailabilityInterface {
+  price {
+    amount
+    currency
+  }
+  hotel {
+    __typename
+    address {
+      ...Address_address
+    }
+    review {
+      score
+    }
+    id
+    name
+    mainPhoto {
+      thumbnailUrl
+      id
+    }
+    rating {
+      stars
+    }
+  }
+}
+
+fragment Address_address on Address {
+  street
+  city
+  zip
+}
+*/
+
+const node/*: ConcreteRequest*/ = (function(){
+var v0 = [
+  {
+    "kind": "LocalArgument",
+    "name": "id",
+    "type": "ID!",
+    "defaultValue": null
+  },
+  {
+    "kind": "LocalArgument",
+    "name": "guests",
+    "type": "Int!",
+    "defaultValue": null
+  },
+  {
+    "kind": "LocalArgument",
+    "name": "currency",
+    "type": "Currency",
+    "defaultValue": null
+  },
+  {
+    "kind": "LocalArgument",
+    "name": "checkin",
+    "type": "Date!",
+    "defaultValue": null
+  },
+  {
+    "kind": "LocalArgument",
+    "name": "checkout",
+    "type": "Date!",
+    "defaultValue": null
+  }
+],
+v1 = [
+  {
+    "kind": "Variable",
+    "name": "checkin",
+    "variableName": "checkin",
+    "type": "Date!"
+  },
+  {
+    "kind": "Variable",
+    "name": "checkout",
+    "variableName": "checkout",
+    "type": "Date!"
+  },
+  {
+    "kind": "Variable",
+    "name": "currency",
+    "variableName": "currency",
+    "type": "Currency"
+  },
+  {
+    "kind": "Variable",
+    "name": "guests",
+    "variableName": "guests",
+    "type": "Int!"
+  },
+  {
+    "kind": "Variable",
+    "name": "id",
+    "variableName": "id",
+    "type": "ID!"
+  }
+],
+v2 = {
+  "kind": "ScalarField",
+  "alias": null,
+  "name": "id",
+  "args": null,
+  "storageKey": null
+};
+return {
+  "kind": "Request",
+  "operationKind": "query",
+  "name": "Stay22SingleHotelMapScreenQuery",
+  "id": null,
+  "text": "query Stay22SingleHotelMapScreenQuery(\n  $id: ID!\n  $guests: Int!\n  $currency: Currency\n  $checkin: Date!\n  $checkout: Date!\n) {\n  stay22HotelDetail(id: $id, guests: $guests, currency: $currency, checkin: $checkin, checkout: $checkout) {\n    ...SingleMap\n    id\n  }\n}\n\nfragment SingleMap on HotelAvailabilityInterface {\n  hotel {\n    __typename\n    ...MapView_hotel\n    id\n  }\n  ...AdditionalInfo\n}\n\nfragment MapView_hotel on HotelInterface {\n  coordinates {\n    lat\n    lng\n  }\n}\n\nfragment AdditionalInfo on HotelAvailabilityInterface {\n  price {\n    amount\n    currency\n  }\n  hotel {\n    __typename\n    address {\n      ...Address_address\n    }\n    review {\n      score\n    }\n    id\n    name\n    mainPhoto {\n      thumbnailUrl\n      id\n    }\n    rating {\n      stars\n    }\n  }\n}\n\nfragment Address_address on Address {\n  street\n  city\n  zip\n}\n",
+  "metadata": {},
+  "fragment": {
+    "kind": "Fragment",
+    "name": "Stay22SingleHotelMapScreenQuery",
+    "type": "RootQuery",
+    "metadata": null,
+    "argumentDefinitions": v0,
+    "selections": [
+      {
+        "kind": "LinkedField",
+        "alias": null,
+        "name": "stay22HotelDetail",
+        "storageKey": null,
+        "args": v1,
+        "concreteType": "Stay22HotelDetail",
+        "plural": false,
+        "selections": [
+          {
+            "kind": "FragmentSpread",
+            "name": "SingleMap",
+            "args": null
+          }
+        ]
+      }
+    ]
+  },
+  "operation": {
+    "kind": "Operation",
+    "name": "Stay22SingleHotelMapScreenQuery",
+    "argumentDefinitions": v0,
+    "selections": [
+      {
+        "kind": "LinkedField",
+        "alias": null,
+        "name": "stay22HotelDetail",
+        "storageKey": null,
+        "args": v1,
+        "concreteType": "Stay22HotelDetail",
+        "plural": false,
+        "selections": [
+          {
+            "kind": "LinkedField",
+            "alias": null,
+            "name": "hotel",
+            "storageKey": null,
+            "args": null,
+            "concreteType": null,
+            "plural": false,
+            "selections": [
+              {
+                "kind": "ScalarField",
+                "alias": null,
+                "name": "__typename",
+                "args": null,
+                "storageKey": null
+              },
+              {
+                "kind": "LinkedField",
+                "alias": null,
+                "name": "coordinates",
+                "storageKey": null,
+                "args": null,
+                "concreteType": "Coordinates",
+                "plural": false,
+                "selections": [
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "lat",
+                    "args": null,
+                    "storageKey": null
+                  },
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "lng",
+                    "args": null,
+                    "storageKey": null
+                  }
+                ]
+              },
+              v2,
+              {
+                "kind": "LinkedField",
+                "alias": null,
+                "name": "address",
+                "storageKey": null,
+                "args": null,
+                "concreteType": "Address",
+                "plural": false,
+                "selections": [
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "street",
+                    "args": null,
+                    "storageKey": null
+                  },
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "city",
+                    "args": null,
+                    "storageKey": null
+                  },
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "zip",
+                    "args": null,
+                    "storageKey": null
+                  }
+                ]
+              },
+              {
+                "kind": "LinkedField",
+                "alias": null,
+                "name": "review",
+                "storageKey": null,
+                "args": null,
+                "concreteType": "HotelReview",
+                "plural": false,
+                "selections": [
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "score",
+                    "args": null,
+                    "storageKey": null
+                  }
+                ]
+              },
+              {
+                "kind": "ScalarField",
+                "alias": null,
+                "name": "name",
+                "args": null,
+                "storageKey": null
+              },
+              {
+                "kind": "LinkedField",
+                "alias": null,
+                "name": "mainPhoto",
+                "storageKey": null,
+                "args": null,
+                "concreteType": "HotelPhoto",
+                "plural": false,
+                "selections": [
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "thumbnailUrl",
+                    "args": null,
+                    "storageKey": null
+                  },
+                  v2
+                ]
+              },
+              {
+                "kind": "LinkedField",
+                "alias": null,
+                "name": "rating",
+                "storageKey": null,
+                "args": null,
+                "concreteType": "HotelRating",
+                "plural": false,
+                "selections": [
+                  {
+                    "kind": "ScalarField",
+                    "alias": null,
+                    "name": "stars",
+                    "args": null,
+                    "storageKey": null
+                  }
+                ]
+              }
+            ]
+          },
+          {
+            "kind": "LinkedField",
+            "alias": null,
+            "name": "price",
+            "storageKey": null,
+            "args": null,
+            "concreteType": "Price",
+            "plural": false,
+            "selections": [
+              {
+                "kind": "ScalarField",
+                "alias": null,
+                "name": "amount",
+                "args": null,
+                "storageKey": null
+              },
+              {
+                "kind": "ScalarField",
+                "alias": null,
+                "name": "currency",
+                "args": null,
+                "storageKey": null
+              }
+            ]
+          },
+          v2
+        ]
+      }
+    ]
+  }
+};
+})();
+// prettier-ignore
+(node/*: any*/).hash = 'e4a0010566422a86f8163845af1815cc';
+module.exports = node;
diff --git a/app/hotels/src/navigation/HotelsNavigationStack.js b/app/hotels/src/navigation/HotelsNavigationStack.js
index 8dc40382..9ee039a0 100644
--- a/app/hotels/src/navigation/HotelsNavigationStack.js
+++ b/app/hotels/src/navigation/HotelsNavigationStack.js
@@ -31,34 +31,16 @@ const DetailStack = StackNavigator(
         ...createTransparentHeaderStyle(RNDimensions.get('screen')),
       },
     },
-  },
-  {
-    ...StackNavigatorOptions,
-    initialRouteName: 'SingleHotel',
-  },
-);
-
-const GalleryStack = StackNavigator(
-  {
     GalleryGrid: {
       screen: withMappedProps(GalleryGrid, AdditionalPropsInjector),
     },
-  },
-  {
-    ...StackNavigatorOptions,
-    initialRouteName: 'GalleryGrid',
-  },
-);
-
-const PaymentStack = StackNavigator(
-  {
     Payment: {
       screen: withMappedProps(Payment),
     },
   },
   {
     ...StackNavigatorOptions,
-    initialRouteName: 'Payment',
+    initialRouteName: 'SingleHotel',
   },
 );
 
@@ -73,18 +55,6 @@ export default StackNavigator(
         header: null,
       },
     },
-    GalleryStack: {
-      screen: GalleryStack,
-      navigationOptions: {
-        header: null,
-      },
-    },
-    PaymentStack: {
-      screen: PaymentStack,
-      navigationOptions: {
-        header: null,
-      },
-    },
     SingleHotelMap: {
       screen: SingleHotelMapNavigationScreen,
       navigationOptions: {
diff --git a/app/hotels/src/navigation/HotelsTabletStack.js b/app/hotels/src/navigation/HotelsTabletStack.js
new file mode 100644
index 00000000..a6ed5700
--- /dev/null
+++ b/app/hotels/src/navigation/HotelsTabletStack.js
@@ -0,0 +1,63 @@
+// @flow strict
+
+import {
+  StackNavigator,
+  StackNavigatorOptions,
+  type NavigationType,
+  createTransparentHeaderStyle,
+} from '@kiwicom/mobile-navigation';
+import { Dimensions as RNDimensions } from 'react-native';
+import { withMappedNavigationAndConfigProps as withMappedProps } from 'react-navigation-props-mapper';
+
+import SearchResults from './allHotels/SearchResultsScreen';
+import AdditionalPropsInjector from './singleHotel/AdditionalPropsInjector';
+import SingleHotelMapNavigationScreen from './singleHotel/SingleHotelMapNavigationScreen';
+import Payment from '../singleHotel/PaymentScreen';
+import GalleryGrid from '../gallery/GalleryGrid';
+
+export type NavigationProps = {|
+  navigation: NavigationType,
+  language: string,
+  currency: string,
+|};
+
+const TabletStack = StackNavigator(
+  {
+    SearchResults: {
+      screen: withMappedProps(SearchResults),
+    },
+    GalleryGrid: {
+      screen: withMappedProps(GalleryGrid, AdditionalPropsInjector),
+    },
+    Payment: {
+      screen: withMappedProps(Payment),
+    },
+  },
+  {
+    ...StackNavigatorOptions,
+    initialRouteName: 'SearchResults',
+  },
+);
+
+export default StackNavigator(
+  {
+    TabletStack: {
+      screen: TabletStack,
+      navigationOptions: {
+        header: null,
+      },
+    },
+    SingleHotelMap: {
+      screen: SingleHotelMapNavigationScreen,
+      navigationOptions: {
+        headerLeft: null,
+        ...createTransparentHeaderStyle(RNDimensions.get('screen')),
+      },
+    },
+  },
+  {
+    ...StackNavigatorOptions,
+    initialRouteName: 'TabletStack',
+    mode: 'modal',
+  },
+);
diff --git a/app/hotels/src/navigation/singleHotel/SingleHotelMapNavigationScreen.js b/app/hotels/src/navigation/singleHotel/SingleHotelMapNavigationScreen.js
index d739295b..22d337de 100644
--- a/app/hotels/src/navigation/singleHotel/SingleHotelMapNavigationScreen.js
+++ b/app/hotels/src/navigation/singleHotel/SingleHotelMapNavigationScreen.js
@@ -4,30 +4,32 @@ import * as React from 'react';
 import { StatusBar } from 'react-native';
 import { withMappedNavigationAndConfigProps } from 'react-navigation-props-mapper';
 
-import type { AvailableHotelSearchInput } from '../../singleHotel/AvailableHotelSearchInput';
-import SingleHotelMap from '../../map/singleHotel/SingleHotelMapScreen';
+import SingleHotelMapScreen from '../../map/singleHotel/SingleHotelMapScreen';
+import SingleHotelContext from './SingleHotelContext';
+import Stay22SingleHotelMapScreen from '../../map/singleHotel/Stay22SingleHotelMapScreen';
 
-type Props = {
-  ...AvailableHotelSearchInput,
-  currency: string,
-};
+type Props = {||};
 
 class SingleHotelMapNavigationScreen extends React.Component<Props> {
-  render() {
+  renderInner = ({ apiProvider }) => {
     return (
       <React.Fragment>
-        <SingleHotelMap
-          search={{
-            hotelId: this.props.hotelId,
-            checkin: this.props.checkin,
-            checkout: this.props.checkout,
-            roomsConfiguration: this.props.roomsConfiguration,
-          }}
-          currency={this.props.currency}
-        />
         <StatusBar barStyle="dark-content" />
+        {apiProvider === 'booking' ? (
+          <SingleHotelMapScreen />
+        ) : (
+          <Stay22SingleHotelMapScreen />
+        )}
       </React.Fragment>
     );
+  };
+
+  render() {
+    return (
+      <SingleHotelContext.Consumer>
+        {this.renderInner}
+      </SingleHotelContext.Consumer>
+    );
   }
 }
 
diff --git a/app/hotels/src/singleHotel/HotelDetailScreen.js b/app/hotels/src/singleHotel/HotelDetailScreen.js
index 0d0f308f..b342c0dd 100644
--- a/app/hotels/src/singleHotel/HotelDetailScreen.js
+++ b/app/hotels/src/singleHotel/HotelDetailScreen.js
@@ -15,7 +15,6 @@ import {
 } from '@kiwicom/mobile-shared';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
 import { Translation } from '@kiwicom/mobile-localization';
-import idx from 'idx';
 import isEqual from 'react-fast-compare';
 import { SafeAreaView } from 'react-navigation';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
@@ -29,10 +28,12 @@ import BrandLabel from './brandLabel/BrandLabel';
 import type { RoomsConfiguration } from '../singleHotel/AvailableHotelSearchInput';
 import type { HotelDetailScreen_availableHotel } from './__generated__/HotelDetailScreen_availableHotel.graphql';
 import countBookingPrice from './bookNow/countBookingPrice';
+import HotelsContext from '../HotelsContext';
 
 type PropsWithContext = {|
   ...Props,
   +width: number,
+  +getGuestCount: () => number,
 |};
 
 type State = {|
@@ -114,8 +115,7 @@ export class HotelDetailScreen extends React.Component<
     maxPersons: number,
   ) => {
     this.setState(state => {
-      const previousCount =
-        idx(state, _ => _.selected[availabilityOriginalId]) || 0;
+      const previousCount = state.selected[availabilityOriginalId] ?? 0;
 
       return {
         ...state,
@@ -140,16 +140,8 @@ export class HotelDetailScreen extends React.Component<
       return this.state.selected[currentItem] + sum;
     }, 0);
 
-  getNumberOfGuests = () => {
-    const roomsConfiguration = idx(
-      this.props,
-      _ => _.roomsConfiguration[0],
-    ) || { adultsCount: 0, children: [] };
-    return roomsConfiguration.adultsCount + roomsConfiguration.children.length;
-  };
-
   getPersonCount = () => {
-    const guestTotal = this.getNumberOfGuests();
+    const guestTotal = this.props.getGuestCount();
 
     return this.state.maxPersons > guestTotal
       ? guestTotal
@@ -160,9 +152,9 @@ export class HotelDetailScreen extends React.Component<
     const { availableHotel } = this.props;
     const { selected } = this.state;
 
-    const disabled = this.getNumberOfGuests() <= this.getNumberOfRooms();
+    const disabled = this.props.getGuestCount() <= this.getNumberOfRooms();
     const price = countBookingPrice(
-      idx(this.props, _ => _.availableHotel.availableRooms),
+      this.props.availableHotel.availableRooms,
       selected,
     );
     if (!availableHotel) {
@@ -231,12 +223,22 @@ type Props = {|
 |};
 
 class HotelDetailScreenWithContext extends React.Component<Props> {
-  renderInner = ({ width }) => (
-    <HotelDetailScreen {...this.props} width={width} />
+  renderDimensions = ({ width }) => (
+    <HotelsContext.Consumer>
+      {this.renderHotelsContext(width)}
+    </HotelsContext.Consumer>
+  );
+
+  renderHotelsContext = width => ({ getGuestCount }) => (
+    <HotelDetailScreen
+      {...this.props}
+      width={width}
+      getGuestCount={getGuestCount}
+    />
   );
 
   render() {
-    return <Dimensions.Consumer>{this.renderInner}</Dimensions.Consumer>;
+    return <Dimensions.Consumer>{this.renderDimensions}</Dimensions.Consumer>;
   }
 }
 
diff --git a/app/hotels/src/singleHotel/PaymentScreen.js b/app/hotels/src/singleHotel/PaymentScreen.js
index dc4cadbe..f00027bc 100644
--- a/app/hotels/src/singleHotel/PaymentScreen.js
+++ b/app/hotels/src/singleHotel/PaymentScreen.js
@@ -12,7 +12,6 @@ import { DateUtils, Translation } from '@kiwicom/mobile-localization';
 import querystring from 'querystring';
 import { HeaderTitle, type NavigationType } from '@kiwicom/mobile-navigation';
 import { graphql, PublicApiRenderer } from '@kiwicom/mobile-relay';
-import idx from 'idx';
 import { HeaderBackButton } from 'react-navigation';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 
@@ -79,7 +78,7 @@ export class PaymentScreen extends React.Component<PaymentParameters> {
     }));
 
   renderInner = (props: PaymentScreenQueryResponse) => {
-    const url = idx(props, _ => _.hotelPaymentUrls.bookingComPaymentUrl);
+    const url = props.hotelPaymentUrls?.bookingComPaymentUrl;
     if (url == null) {
       return (
         <GeneralError
diff --git a/app/hotels/src/singleHotel/bookNow/BookNow.js b/app/hotels/src/singleHotel/bookNow/BookNow.js
index 0c1f4cd4..58a43b06 100644
--- a/app/hotels/src/singleHotel/bookNow/BookNow.js
+++ b/app/hotels/src/singleHotel/bookNow/BookNow.js
@@ -1,9 +1,8 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
 import { StyleSheet, Button, Text } from '@kiwicom/mobile-shared';
-import idx from 'idx';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 import {
   withNavigation,
@@ -13,24 +12,19 @@ import { DeviceInfo, Translation } from '@kiwicom/mobile-localization';
 
 import convertRooms from './convertRooms';
 import type { BookNow_hotel } from './__generated__/BookNow_hotel.graphql';
-import SingleHotelContext, {
-  type State as SingleHotelState,
-} from '../../navigation/singleHotel/SingleHotelContext';
 import HotelsContext, {
   type State as HotelsContextState,
 } from '../../HotelsContext';
 
 type PropsWithContext = {
   ...Props,
-  +checkin: Date,
-  +checkout: Date,
   +currency: string,
 };
 
 export class BookNow extends React.Component<PropsWithContext> {
   handleGoToPayment = () => {
-    const hotelId = idx(this.props.hotel, _ => _.id);
-    if (hotelId) {
+    const hotelId = this.props.hotel?.id;
+    if (hotelId != null) {
       this.props.navigation.navigate('Payment', {
         hotelId,
         rooms: convertRooms(this.props.selected),
@@ -54,31 +48,17 @@ type Props = {|
   +selected: {
     [string]: number,
   },
-  +availableRooms: any,
-  +hotel: any,
   +hotel: ?BookNow_hotel,
   +navigation: NavigationType,
 |};
 
 export class BookNowWithContext extends React.Component<Props> {
-  renderHotelsContext = ({ currency }: HotelsContextState) => (
-    <SingleHotelContext.Consumer>
-      {this.renderSingleHotelContext(currency)}
-    </SingleHotelContext.Consumer>
-  );
-
-  renderSingleHotelContext = (
-    currency: $PropertyType<HotelsContextState, 'currency'>,
-  ) => (state: SingleHotelState) => (
-    <BookNow {...this.props} {...state} currency={currency} />
+  renderInner = ({ currency }: HotelsContextState) => (
+    <BookNow {...this.props} currency={currency} />
   );
 
   render() {
-    return (
-      <HotelsContext.Consumer>
-        {this.renderHotelsContext}
-      </HotelsContext.Consumer>
-    );
+    return <HotelsContext.Consumer>{this.renderInner}</HotelsContext.Consumer>;
   }
 }
 
diff --git a/app/hotels/src/singleHotel/bookNow/countBookingPrice.js b/app/hotels/src/singleHotel/bookNow/countBookingPrice.js
index d60b8590..f164cfce 100644
--- a/app/hotels/src/singleHotel/bookNow/countBookingPrice.js
+++ b/app/hotels/src/singleHotel/bookNow/countBookingPrice.js
@@ -1,7 +1,5 @@
 // @flow
 
-import idx from 'idx';
-
 import type { BookNow_availableRooms } from '../__generated__/HotelDetailScreen_availableHotel.graphql';
 
 type Money = {|
@@ -32,16 +30,14 @@ export default (
 
       if (availableRooms) {
         const room = availableRooms.find(room => room.id === id);
-        return idx(room, _ => _.incrementalPrice[count - 1].amount);
+        return room?.incrementalPrice?.[count - 1]?.amount;
       }
     })
     .reduce((a, b) => a + b, 0);
 
   const currency =
-    idx(
-      availableRooms.find(room => room.id === positiveSelections[0][0]),
-      _ => _.incrementalPrice[0].currency,
-    ) || '';
+    availableRooms.find(room => room.id === positiveSelections[0][0])
+      ?.incrementalPrice?.[0]?.currency ?? '';
 
   return {
     amount,
diff --git a/app/hotels/src/singleHotel/brandLabel/BrandLabel.js b/app/hotels/src/singleHotel/brandLabel/BrandLabel.js
index 1743ea02..58eac38f 100644
--- a/app/hotels/src/singleHotel/brandLabel/BrandLabel.js
+++ b/app/hotels/src/singleHotel/brandLabel/BrandLabel.js
@@ -1,4 +1,4 @@
-// @flow
+// @flow strict
 
 import * as React from 'react';
 import { View, Image } from 'react-native';
diff --git a/app/hotels/src/singleHotel/galleryButton/GalleryButton.js b/app/hotels/src/singleHotel/galleryButton/GalleryButton.js
index 389138da..4ccb6eb2 100644
--- a/app/hotels/src/singleHotel/galleryButton/GalleryButton.js
+++ b/app/hotels/src/singleHotel/galleryButton/GalleryButton.js
@@ -9,7 +9,6 @@ import {
   type StylePropType,
   TextIcon,
 } from '@kiwicom/mobile-shared';
-import idx from 'idx';
 import { Translation } from '@kiwicom/mobile-localization';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 
@@ -23,9 +22,9 @@ type Props = {|
 |};
 
 export default function GalleryButton({ count, style }: Props) {
-  const containerStyle = idx(style, _ => _.container) || null;
-  const iconStyle = idx(style, _ => _.icon) || null;
-  const textStyle = idx(style, _ => _.text) || null;
+  const containerStyle = style?.container ?? null;
+  const iconStyle = style?.icon ?? null;
+  const textStyle = style?.text ?? null;
   return (
     <View style={[styles.container, containerStyle]}>
       <TextIcon code="&#xe064;" style={[styles.icon, iconStyle]} />
diff --git a/app/hotels/src/singleHotel/hotelInformation/HotelReview.js b/app/hotels/src/singleHotel/hotelInformation/HotelReview.js
index 878f59b1..cdc4a2e6 100644
--- a/app/hotels/src/singleHotel/hotelInformation/HotelReview.js
+++ b/app/hotels/src/singleHotel/hotelInformation/HotelReview.js
@@ -6,7 +6,6 @@ import { StyleSheet, Text } from '@kiwicom/mobile-shared';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 import { Translation } from '@kiwicom/mobile-localization';
-import idx from 'idx';
 
 import HotelReviewScore from '../../components/HotelReviewScore';
 import type { HotelReview as HotelReviewType } from './__generated__/HotelReview.graphql';
@@ -35,15 +34,15 @@ const RenderLabel = ({ score }: {| +score: ?number |}) => {
 };
 
 const HotelReview = (props: Props) => {
-  const reviews = idx(props.data, _ => _.review.count);
+  const reviews = props.data.review?.count;
   return (
     <View style={styles.container}>
       <View style={styles.row}>
         <View style={styles.badgeWrapper}>
-          <HotelReviewScore score={idx(props.data, _ => _.review.score)} />
+          <HotelReviewScore score={props.data.review?.score} />
         </View>
         <View>
-          <RenderLabel score={idx(props.data, _ => _.review.score)} />
+          <RenderLabel score={props.data.review?.score} />
           {reviews != null && (
             <Text style={styles.score}>
               <Translation
diff --git a/app/hotels/src/singleHotel/hotelInformation/description/Amenities.js b/app/hotels/src/singleHotel/hotelInformation/description/Amenities.js
index 48194c0c..76fe731c 100644
--- a/app/hotels/src/singleHotel/hotelInformation/description/Amenities.js
+++ b/app/hotels/src/singleHotel/hotelInformation/description/Amenities.js
@@ -11,7 +11,6 @@ import {
 } from '@kiwicom/mobile-shared';
 import { Translation, TranslationFragment } from '@kiwicom/mobile-localization';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
-import idx from 'idx';
 
 import type { Amenities as AmenitiesType } from './__generated__/Amenities.graphql';
 
@@ -36,7 +35,7 @@ export class Amenities extends React.Component<Props, State> {
 
   render() {
     const { collapsed } = this.state;
-    const fullList = idx(this.props.data, _ => _.amenities) || [];
+    const fullList = this.props.data?.amenities ?? [];
 
     const shortlist = fullList.slice(0, 9);
     const listToRender = collapsed ? shortlist : fullList;
diff --git a/app/hotels/src/singleHotel/hotelInformation/description/Description.js b/app/hotels/src/singleHotel/hotelInformation/description/Description.js
index 333519b3..2f15a338 100644
--- a/app/hotels/src/singleHotel/hotelInformation/description/Description.js
+++ b/app/hotels/src/singleHotel/hotelInformation/description/Description.js
@@ -5,7 +5,6 @@ import { View } from 'react-native';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
 import { Text, StyleSheet, ReadMore } from '@kiwicom/mobile-shared';
 import { Translation } from '@kiwicom/mobile-localization';
-import idx from 'idx';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 
 import DescriptionTitle from './DescriptionTitle';
@@ -34,14 +33,14 @@ export const Description = (props: Props) => (
       revealedText={<Translation id="single_hotel.description.show_less" />}
     >
       <Text style={styles.summary}>
-        <Translation passThrough={idx(props, _ => _.hotel.summary)} />
+        <Translation passThrough={props.hotel?.summary} />
       </Text>
     </ReadMore>
     <View style={styles.facilitiesContainer}>
       <DescriptionTitle
         title={<Translation id="single_hotel.description.equipment" />}
       />
-      <Amenities data={idx(props, _ => _.hotel)} />
+      <Amenities data={props.hotel} />
     </View>
   </View>
 );
diff --git a/app/hotels/src/singleHotel/hotelInformation/location/Location.js b/app/hotels/src/singleHotel/hotelInformation/location/Location.js
index 10007fc3..6d5d933e 100644
--- a/app/hotels/src/singleHotel/hotelInformation/location/Location.js
+++ b/app/hotels/src/singleHotel/hotelInformation/location/Location.js
@@ -12,7 +12,6 @@ import {
 } from '@kiwicom/mobile-shared';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
 import { Translation } from '@kiwicom/mobile-localization';
-import idx from 'idx';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 import {
   withNavigation,
@@ -52,20 +51,20 @@ export class Location extends React.Component<PropsWithContext> {
 
   render = () => {
     const { hotel } = this.props;
-    const address = idx(hotel, _ => _.address);
-    const coordinates = idx(hotel, _ => _.coordinates);
-    const latitude = idx(coordinates, _ => _.lat);
-    const longitude = idx(coordinates, _ => _.lng);
+    const address = hotel?.address;
+    const coordinates = hotel?.coordinates;
+    const latitude = coordinates?.lat;
+    const longitude = coordinates?.lng;
     return (
       <View style={styles.background}>
         <TouchableWithoutFeedback onPress={this.goToMap}>
           <View style={styles.container}>
             <View style={styles.leftColumn}>
               <Text style={[styles.addressLine, styles.streetLine]}>
-                <Translation passThrough={idx(address, _ => _.street)} />
+                <Translation passThrough={address?.street} />
               </Text>
               <Text style={[styles.addressLine, styles.cityLine]}>
-                <Translation passThrough={idx(address, _ => _.city)} />
+                <Translation passThrough={address?.city} />
               </Text>
             </View>
             {typeof latitude === 'number' &&
diff --git a/app/hotels/src/singleHotel/roomList/BeddingInfo.js b/app/hotels/src/singleHotel/roomList/BeddingInfo.js
index 3787a372..0709c0b4 100644
--- a/app/hotels/src/singleHotel/roomList/BeddingInfo.js
+++ b/app/hotels/src/singleHotel/roomList/BeddingInfo.js
@@ -5,7 +5,6 @@ import { View } from 'react-native';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
 import { StyleSheet, Text, TextIcon } from '@kiwicom/mobile-shared';
 import { Translation } from '@kiwicom/mobile-localization';
-import idx from 'idx';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 
 import type { BeddingInfo_room } from './__generated__/BeddingInfo_room.graphql';
@@ -24,7 +23,7 @@ export class BeddingInfo extends React.Component<Props> {
   render = () => {
     const { room } = this.props;
     const info = formatBeddingInfo(room);
-    const maxPersons = idx(this.props.room, _ => _.maxPersons);
+    const maxPersons = this.props.room?.maxPersons;
 
     return (
       <View>
diff --git a/app/hotels/src/singleHotel/roomList/RoomBadges.js b/app/hotels/src/singleHotel/roomList/RoomBadges.js
index 82fc18e0..a72c12d1 100644
--- a/app/hotels/src/singleHotel/roomList/RoomBadges.js
+++ b/app/hotels/src/singleHotel/roomList/RoomBadges.js
@@ -4,7 +4,6 @@ import * as React from 'react';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
 import { AdaptableBadge, StyleSheet, TextIcon } from '@kiwicom/mobile-shared';
 import { Translation } from '@kiwicom/mobile-localization';
-import idx from 'idx';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 
 import type { RoomBadges_availableRoom as RoomBadgesTypes } from './__generated__/RoomBadges_availableRoom.graphql';
@@ -19,11 +18,8 @@ type Props = {|
 |};
 
 export const RoomBadges = (props: Props) => {
-  const isBreakfastIncluded = idx(
-    props.availableRoom,
-    _ => _.isBreakfastIncluded,
-  );
-  const isRefundable = idx(props.availableRoom, _ => _.isRefundable);
+  const isBreakfastIncluded = props.availableRoom.isBreakfastIncluded;
+  const isRefundable = props.availableRoom.isRefundable;
 
   return (
     <React.Fragment>
diff --git a/app/hotels/src/singleHotel/roomList/RoomRow.js b/app/hotels/src/singleHotel/roomList/RoomRow.js
index 5fcc9a85..fb20d5c8 100644
--- a/app/hotels/src/singleHotel/roomList/RoomRow.js
+++ b/app/hotels/src/singleHotel/roomList/RoomRow.js
@@ -51,8 +51,8 @@ export class RoomRow extends React.Component<Props> {
   };
 
   getIdAndMaxPersons = () => {
-    const id = this.props?.availableRoom?.id;
-    const maxPersons = this.props?.availableRoom?.room?.maxPersons;
+    const id = this.props.availableRoom?.id;
+    const maxPersons = this.props.availableRoom?.room?.maxPersons;
     return { id, maxPersons };
   };
 
@@ -89,7 +89,7 @@ export class RoomRow extends React.Component<Props> {
     const currency = availableRoom?.minimalPrice?.currency ?? null;
     const selectableCount = availableRoom?.incrementalPrice?.length ?? 0;
     const id = availableRoom?.id ?? '';
-    const selectedCount = this.props.selected?.[id] ?? 0;
+    const selectedCount = this.props.selected[id] ?? 0;
     const room = availableRoom?.room;
 
     return (
diff --git a/app/hotels/src/singleHotel/roomList/RoomRowTitle.js b/app/hotels/src/singleHotel/roomList/RoomRowTitle.js
index 7776e68c..dc0c4db3 100644
--- a/app/hotels/src/singleHotel/roomList/RoomRowTitle.js
+++ b/app/hotels/src/singleHotel/roomList/RoomRowTitle.js
@@ -4,7 +4,6 @@ import * as React from 'react';
 import { Text, StyleSheet } from '@kiwicom/mobile-shared';
 import { createFragmentContainer, graphql } from '@kiwicom/mobile-relay';
 import { Translation } from '@kiwicom/mobile-localization';
-import idx from 'idx';
 import { defaultTokens } from '@kiwicom/mobile-orbit';
 
 import type { RoomRowTitle_room as RoomRowTitleType } from './__generated__/RoomRowTitle_room.graphql';
@@ -19,7 +18,7 @@ type Props = {|
 |};
 
 export function RoomRowTitle(props: Props) {
-  const title = idx(props.room, _ => _.description.title) || '';
+  const title = props.room?.description?.title ?? '';
 
   return (
     <Text style={styles.title}>
diff --git a/app/hotels/src/singleHotel/roomList/formatBeddingInfo.js b/app/hotels/src/singleHotel/roomList/formatBeddingInfo.js
index 70d96a1c..9d927edc 100644
--- a/app/hotels/src/singleHotel/roomList/formatBeddingInfo.js
+++ b/app/hotels/src/singleHotel/roomList/formatBeddingInfo.js
@@ -1,15 +1,13 @@
 // @flow
 
-import idx from 'idx';
-
 import type { BeddingInfo_room } from './__generated__/BeddingInfo_room.graphql';
 
 export default (room: ?BeddingInfo_room): string => {
-  const beddingOptions = idx(room, _ => _.bedding) || [];
+  const beddingOptions = room?.bedding ?? [];
   return beddingOptions
     .map(beddingOption => {
-      const type = idx(beddingOption, _ => _.type);
-      const amount = idx(beddingOption, _ => _.amount);
+      const type = beddingOption?.type;
+      const amount = beddingOption?.amount;
       return [amount, type].filter(value => value != null).join(' ');
     })
     .join(' or '); // TODO: Translate
diff --git a/docs/android/README.md b/docs/android/README.md
index 952a25fb..28f1dfc7 100644
--- a/docs/android/README.md
+++ b/docs/android/README.md
@@ -1,6 +1,7 @@
 # rnkiwimobile - Android distribution
 
-The source code can be found in [rnkiwimobile](../../android/rnkiwimobile). This library contains everything that the Android Kiwi native app needs in order to run React Native including the JavaScript code.
+The source code can be found in [rnkiwimobile](../../android/rnkiwimobile). This library contains everything that the 
+Android Kiwi native app needs in order to run React Native including the JavaScript code.
 
 ## Test playground app
 
@@ -23,9 +24,35 @@ Or if you prefer you can run if from Android Studio:
 **Important**: The packager will only be used if there is no bundle in `.build/android`, if there is,
 you can safely delete the whole directory.
 
-### Release
+### Setting up CodePush keys
 
-In release mode, the `playground` is going to use `rnkiwimobile` from [Trinerdis](http://trinerdis.cz:8000/repository/snapshots/com/trinerdis/skypicker/rnkiwimobile/). The version is defined [here](../../.build/package.json#L3). 
+In order to run the app in `stagingRelease` mode or in `release` mode, we need to set up CodePush keys. If you didn't 
+download the CLI and log in to CodePush and make sure to [set it up](../common/code-push.md). After that, you can get
+the keys by running:
+
+```bash
+appcenter codepush deployment list -a Kiwicom/mobile-android
+```
+
+You need to create a file named `codepush.properties` inside [playground](../../android/playground):
+
+```bash
+STAGING_KEY=""
+PRODUCTION=KEY=""
+```
+
+#### Staging
+
+If you set up the STAGING_KEY from previous step, you can just run:
+
+```bash
+yarn android --appFolder playground --variant stagingRelease
+```
+
+#### Production
+
+In `release` mode, the `playground` is going to use `rnkiwimobile` from [Trinerdis](http://trinerdis.cz:8000/repository/snapshots/com/trinerdis/skypicker/rnkiwimobile/). The version is defined [here](../../.build/package.json#L3).
+It will also you the `Production` version of CodePush. 
 You do not need the packager running. This is the real version that the native app wil be consuming.
 
 You can run it using:
diff --git a/docs/common/code-push.md b/docs/common/code-push.md
new file mode 100644
index 00000000..22136ccf
--- /dev/null
+++ b/docs/common/code-push.md
@@ -0,0 +1,44 @@
+# CodePush
+
+For versioning CodePush we use our own version system following the 
+[target binary version](https://github.com/Microsoft/code-push/tree/master/cli#target-binary-version-parameter) section.
+
+We do specify the version in our [package.json#rnkiwimobile](../../package.json#L91-L93).
+
+## Releasing a new version
+
+The script is located in [scripts/codePush.js](../../scripts/codePush.js). You need to be logged in `appcenter`. 
+If you do not have it yet, you can install the cli:
+
+```bash
+npm install -g appcenter-cli
+``` 
+
+And after that you can log in using:
+
+```bash
+# This will open the browser offering you a code that you need to paste into the terminal
+appcenter login
+```
+
+Finally, we can run the script to release into Staging (this will do it for both Android and iOS):
+
+```bash
+yarn code-push
+```
+
+To release into Production we can simply promote a Staging release to Production in the AppCenter website.
+
+## Bumping a new major version
+
+Just go to the [package.json#rnkiwimobile](../../package.json#L91-L93) and change the version:
+
+```
+"rnkiwimobile": {
+   // Instead of 1.0.0
+  "code-push-target-binary-version": "2.0.0"
+}
+```
+
+This will make that only users with the native app updated (using JS CodePush version 2.x.x) will get it. 
+The users that did not update from 1.0.0 (native side) will not receive it. This allow us not breaking the app for them.
diff --git a/ios/RNKiwiMobile/RNKiwiViewController.h b/ios/RNKiwiMobile/RNKiwiViewController.h
index 201db341..957fd6c9 100644
--- a/ios/RNKiwiMobile/RNKiwiViewController.h
+++ b/ios/RNKiwiMobile/RNKiwiViewController.h
@@ -15,7 +15,7 @@
 @property (nonatomic, weak, nullable) id<RNKiwiViewControllerFlowDelegate> flowDelegate;
 
 // Logging
-@property (nonatomic, copy, nullable) void (^didDisplayAncillary)(NSString * _Nonnull type);
-@property (nonatomic, copy, nullable) void (^didPurchaseAncillary)(NSString * _Nonnull type);
+@property (nonatomic, copy, nullable) void (^didDisplayAncillary)(NSString * _Nonnull type, NSString *provider);
+@property (nonatomic, copy, nullable) void (^didPurchaseAncillary)(NSString * _Nonnull type, NSString *provider);
 
 @end
diff --git a/ios/RNKiwiMobile/RNKiwiViewController.m b/ios/RNKiwiMobile/RNKiwiViewController.m
index 6c411c15..395b98f0 100644
--- a/ios/RNKiwiMobile/RNKiwiViewController.m
+++ b/ios/RNKiwiMobile/RNKiwiViewController.m
@@ -81,15 +81,15 @@
 
 #pragma mark - RNLogger
 
-- (void)ancillaryDisplayed:(NSString *)type {
+- (void)ancillaryDisplayed:(NSString *)type provider:(NSString *)provider {
   if ([self didDisplayAncillary]) {
-    self.didDisplayAncillary(type);
+    self.didDisplayAncillary(type, provider);
   }
 }
 
-- (void)ancillaryPurchased:(NSString *)type {
+- (void)ancillaryPurchased:(NSString *)type provider:(NSString *)provider {
   if ([self didPurchaseAncillary]) {
-    self.didPurchaseAncillary(type);
+    self.didPurchaseAncillary(type, provider);
   }
 }
 
diff --git a/ios/RNModules/RNLogging/RNLogging/RNLoggingModule.m b/ios/RNModules/RNLogging/RNLogging/RNLoggingModule.m
index 5839f9ee..be640d3e 100755
--- a/ios/RNModules/RNLogging/RNLogging/RNLoggingModule.m
+++ b/ios/RNModules/RNLogging/RNLogging/RNLoggingModule.m
@@ -11,7 +11,7 @@
     NSLog(@"ancillaryDisplayed - type: %@, - provider: %@", type, provider);
 }
 
-- (void)ancillaryPurchased:(NSString *)type  provider:(NSString *)provider{
+- (void)ancillaryPurchased:(NSString *)type provider:(NSString *)provider{
     NSLog(@"ancillaryPurchased - type: %@, - provider: %@", type, provider);
 }
 
@@ -52,7 +52,7 @@ RCT_EXPORT_MODULE();
     return _logger;
 }
 
-RCT_EXPORT_METHOD(ancillaryDisplayed:(NSString *)type  provider:(NSString *)provider) {
+RCT_EXPORT_METHOD(ancillaryDisplayed:(NSString *)type provider:(NSString *)provider) {
     [self.logger ancillaryDisplayed:type provider:provider];
 }
 
@@ -62,12 +62,12 @@ RCT_EXPORT_METHOD(ancillaryPurchased:(NSString *)type provider:(NSString *)provi
 
 - (NSDictionary *)constantsToExport
 {
-    return @{ @"ANCILLARY_STEP_SEARCH_FORM" : @"searchForm",
-              @"ANCILLARY_STEP_RESULTS"     : @"results",
-              @"ANCILLARY_STEP_DETAILS"     : @"details",
-              @"ANCILLARY_STEP_PAYMENT"     : @"payment",
-              @"ANCILLARY_PROVIDER_BOOKINGCOM"     : @"booking.com",
-              @"ANCILLARY_PROVIDER_STAY22"     : @"stay22",
+    return @{ @"ANCILLARY_STEP_SEARCH_FORM"     : @"searchForm",
+              @"ANCILLARY_STEP_RESULTS"         : @"results",
+              @"ANCILLARY_STEP_DETAILS"         : @"details",
+              @"ANCILLARY_STEP_PAYMENT"         : @"payment",
+              @"ANCILLARY_PROVIDER_BOOKINGCOM"  : @"booking.com",
+              @"ANCILLARY_PROVIDER_STAY22"      : @"stay22",
     };
 }
 
diff --git a/ios/reactNativeApp.xcodeproj/project.pbxproj b/ios/reactNativeApp.xcodeproj/project.pbxproj
index 537a26c9..6438a2c0 100644
--- a/ios/reactNativeApp.xcodeproj/project.pbxproj
+++ b/ios/reactNativeApp.xcodeproj/project.pbxproj
@@ -5,7 +5,6 @@
 	};
 	objectVersion = 46;
 	objects = {
-
 /* Begin PBXBuildFile section */
 		13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
 		13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
diff --git a/packages/localization/src/vocabularies/Hotels.js b/packages/localization/src/vocabularies/Hotels.js
index d7105a6f..d9691194 100644
--- a/packages/localization/src/vocabularies/Hotels.js
+++ b/packages/localization/src/vocabularies/Hotels.js
@@ -89,6 +89,11 @@ export default {
   'hotels_search.location_picker.header': 'Where',
   'hotels_search.location_picker.recent_search': 'Recent search',
   'hotels_search.header.to': 'to',
+  'hotels_search.hotel_distance.in_city_center': 'In the city center',
+  'hotels_search.hotel_distance.meters_from_center':
+    '__distance__m from center',
+  'hotels_search.hotel_distance.kilo_meters_from_center':
+    '__distance__km from center',
 
   'single_hotel.bedding_info.guests': '__numberOfGuests__ Guests',
   'single_hotel.book_now': 'Book Now',
diff --git a/packages/navigation/src/SplitNavigation.js b/packages/navigation/src/SplitNavigation.js
index bb33735a..fb7a4bac 100644
--- a/packages/navigation/src/SplitNavigation.js
+++ b/packages/navigation/src/SplitNavigation.js
@@ -55,7 +55,7 @@ export default class SplitNavigation extends React.Component<Props, State> {
   };
 
   getContainerComponent = () =>
-    this.props.containerComponents[this.state.activeId]?.screen;
+    this.props.containerComponents[this.state.activeId].screen;
 
   render() {
     const MainMenuContainerWide = React.cloneElement(this.props.menuComponent, {
diff --git a/scripts/configureApplication.js b/scripts/configureApplication.js
index 2757593f..9e9bcf09 100644
--- a/scripts/configureApplication.js
+++ b/scripts/configureApplication.js
@@ -2,6 +2,7 @@
 
 const fs = require('fs');
 const path = require('path');
+const child_process = require('child_process');
 
 const log = message => console.log(`➤ ${message}`); // eslint-disable-line no-console
 
@@ -51,18 +52,50 @@ API_KEY_GOOGLE_MAPS=${vault.API_KEY_GOOGLE_MAPS}
 log('Setting up ENV variables...');
 fs.writeFileSync(path.join(__dirname, '..', '.env'), envTemplate);
 
+// We need to do this patching as react-native-code-push is actually "linked" as part of our native library RNKiwiMobile
+// We might be avoiding this patching when linking is extracted from RN core (with new features)
+// Keep an eye on https://github.com/react-native-community/react-native-cli
+log('Patching react-native-code-push...');
+const rnCodePushPackgeJson = JSON.parse(
+  fs.readFileSync(
+    path.join(
+      __dirname,
+      '..',
+      'node_modules',
+      'react-native-code-push',
+      'package.json',
+    ),
+    'utf-8',
+  ),
+);
+delete rnCodePushPackgeJson.rnpm;
+
+fs.writeFileSync(
+  path.join(
+    __dirname,
+    '..',
+    'node_modules',
+    'react-native-code-push',
+    'package.json',
+  ),
+  JSON.stringify(rnCodePushPackgeJson, null, 2),
+);
+
+log('Linking all native dependencies...');
+child_process.execSync('yarn react-native link');
+
 log('Patching intl package');
-const packageJson = JSON.parse(
+const intlPackageJson = JSON.parse(
   fs.readFileSync(
     path.join(__dirname, '..', 'node_modules', 'intl', 'package.json'),
     'utf-8',
   ),
 );
-delete packageJson.browser;
+delete intlPackageJson.browser;
 
 fs.writeFileSync(
   path.join(__dirname, '..', 'node_modules', 'intl', 'package.json'),
-  JSON.stringify(packageJson, null, 2),
+  JSON.stringify(intlPackageJson, null, 2),
 );
 
 try {


Test patch:
diff --git a/app/hotels/src/allHotels/__tests__/HotelDistance.test.js b/app/hotels/src/allHotels/__tests__/HotelDistance.test.js
index e01be6fb..afd6e7fb 100644
--- a/app/hotels/src/allHotels/__tests__/HotelDistance.test.js
+++ b/app/hotels/src/allHotels/__tests__/HotelDistance.test.js
@@ -5,14 +5,45 @@ import { getDistanceText } from '../HotelDistance';
 const cityCenterRadius = 1.5;
 
 it('Distance should be in the city center', () => {
-  expect(getDistanceText(1.3, cityCenterRadius)).toBe('In the city center');
+  expect(getDistanceText(1.3, cityCenterRadius)).toMatchInlineSnapshot(`
+<Translation
+  id="hotels_search.hotel_distance.in_city_center"
+/>
+`);
 });
 
 it('Distance should be in meters and rounded up to 100', () => {
-  expect(getDistanceText(1.81, cityCenterRadius)).toBe('400m from center');
-  expect(getDistanceText(1.89, cityCenterRadius)).toBe('400m from center');
+  expect(getDistanceText(1.81, cityCenterRadius)).toMatchInlineSnapshot(`
+<Translation
+  id="hotels_search.hotel_distance.meters_from_center"
+  values={
+    Object {
+      "distance": 400,
+    }
+  }
+/>
+`);
+  expect(getDistanceText(1.89, cityCenterRadius)).toMatchInlineSnapshot(`
+<Translation
+  id="hotels_search.hotel_distance.meters_from_center"
+  values={
+    Object {
+      "distance": 400,
+    }
+  }
+/>
+`);
 });
 
 it('Distance should be in km', () => {
-  expect(getDistanceText(4.81, cityCenterRadius)).toBe('3.3km from center');
+  expect(getDistanceText(4.81, cityCenterRadius)).toMatchInlineSnapshot(`
+<Translation
+  id="hotels_search.hotel_distance.kilo_meters_from_center"
+  values={
+    Object {
+      "distance": "3.3",
+    }
+  }
+/>
+`);
 });