Skip to main content

Social Bet Sharing

Social bet sharing enables users to share pending and resulted bets through their device's native sharing functionality with other apps including messaging and social media apps.

Product Overview

When a bet is shared, an image representing that bet is generated and, if the bet would still be bettable by others at the time it is shared, a unique link is also generated. If the link is opened by another user, the bet details are automatically loaded into the Betslip and opened for the user to enter the amount they wish to bet and submit it.

Designs

Dependencies

react-native-share

react-native-share improves the default sharing capability of the react-native. In particular it enabled us to share both an image and the shared bet url at the same time, across both platforms in a consistent API.

react-native-view-shot

react-native-view-shot is the library that allows us to generate an image from standard react-native components. Once we have rendered the SharePreview for the selected bet, we can turn it into an image that matches exactly what the user sees on their screen, which keeps it dynamic and configurable before they press the share button.

Component Model

When looking at the designs, there were many UI elements that were shared in different areas of the bet image but used different data sources (e.g. a selection instead of a leg) or in a different location (e.g. a single sports bet looks very similar to a sports bet leg of a multi bet).

To make the most of the similarities in the designs we designed the component architecture to follow a container/presentational component model (often called "smart" and "dumb" components. In this arrangement, it's common to have the leaves of the component tree with very little logic in them, simply accepting props of primitive data and laying out and styling the component. These are the presentational components. Wrapping these presentational components are the container components that are responsible for collecting the data and choosing which more primitive values to pass into the presentational components.

The reuse is enabled by having different container components for different variations of bets that use the same underlying presentational components.

Styling

A theme object called betSharing was introduced to handle the styling variables of the social bet sharing module. Generally, this object is limited to colours and font variables, while layout and spacing is handled by inline BoxProps throughout the component structure as there is no variance in how the preview lay out between the different brands.

Testing

Components and functions are tested can be tested with Jest. Snapshot testing is minimally used with the team deciding to prefer explicit assertions on the data appearing in the output instead, leading to fewer breaking tests as the designs evolved during development.

Implementation

The shared bet link has the following structure:

https://{BRAND_WEBSITE}/share-bet/{SHARED_BET_ID}

The BRAND_WEBSITE is configured in the app config while the SHARED_BET_ID is generated from the transaction_id of the selected pending bet using the CreateSharedBet handler of the bet-share api.

There has been some discussion around shortening the url, either through smarter SHARED_BET_ID generation or through the use of an external URL shortener, but this does not form part of the initial release at this time. You can follow the discussion here.

When the link is opened, we extract the SHARED_BET_ID from the URL passed to the app and forward it onto the betslip-utils to collect and generate the relevant bet slip data before opening the Betslip drawer for the user.

Client side generation

When planning the delivery of this feature, a technical decision was made to generate the images on the user's device rather than generating them in the backend and just serving them through the app. There were multiple factors that went into this decision, but the main deciding factors were:

  1. The existing availability of required data
  2. The performance characteristics and "smoothness" of having everything local to the device
  3. The ability to add extra UX "flair", such as animating transitions when inputs were changed.

You can see the full table used in the decision making process here.

Sharing an image

We did investigate using social previews instead of sharing images directly. This option was not pursued as the social previews are often quite restrictive on size and the dynamic nature of the bet structures does not lend itself well to this type of constraint. It's also entirely up to the app the bet is shared with as to how and whether it even uses the social previews. The final consideration was that in the case of a resulted bet, there isn't a relevant URL that can be generated in order to see the social preview.

Overall, it was decided that we would rather have the control on our end and generate and share the image directly from the app.

File Structure

  • Components: app/components/bet-sharing/
  • Hooks: app/hooks/bet-sharing/
  • Utils: app/utils/bet-sharing/