Skip to content

Commit 83e8145

Browse files
committed
Implement simple share function of detail screens
- https://docs.expo.io/versions/v32.0.0/react-native/share - created share helper function - added params for shareContent to navigation params, that will be used for share dialog opened from DetailScreen - created `shareMessage()` helper to build the message to share - refactored `getQuery` to `/queries/index.js` to use everywhere from one place - added missing line trimming of HtmlView in DetailScreen
1 parent 29531bf commit 83e8145

6 files changed

Lines changed: 130 additions & 47 deletions

File tree

src/helpers/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './htmlViewHelper';
22
export * from './linkHelper';
33
export * from './momentHelper';
4+
export * from './shareHelper';

src/helpers/shareHelper.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { Share } from 'react-native';
2+
3+
import appJson from '../../app.json';
4+
import { momentFormat } from './momentHelper';
5+
6+
// https://facebook.github.io/react-native/docs/share
7+
export const openShare = async ({ message, title, url }) => {
8+
try {
9+
const result = await Share.share(
10+
{
11+
message,
12+
title,
13+
url // iOS only
14+
},
15+
{
16+
dialogTitle: 'Teilen', // Android only
17+
subject: title // iOS only - a subject to share via email
18+
}
19+
);
20+
21+
if (result.action === Share.sharedAction) {
22+
if (result.activityType) {
23+
// shared with activity type of result.activityType
24+
} else {
25+
// shared
26+
}
27+
} else if (result.action === Share.dismissedAction) {
28+
// dismissed
29+
}
30+
} catch (error) {
31+
alert(error.message);
32+
}
33+
};
34+
35+
export const shareMessage = (data, query) => {
36+
const buildMessage = (query) => {
37+
switch (query) {
38+
case 'eventRecord':
39+
return `${momentFormat(data.createdAt)} | ${data.dataProvider && data.dataProvider.name}: ${
40+
data.title
41+
}`;
42+
case 'newsItem':
43+
return `${momentFormat(data.publishedAt)} | ${data.dataProvider &&
44+
data.dataProvider.name}: ${data.contentBlocks[0].title}`;
45+
case 'pointsOfInterest':
46+
return data.name;
47+
}
48+
};
49+
50+
// TODO: real deep link instead of test
51+
return `[${appJson.expo.name}] ${buildMessage(query)}\n\n${appJson.expo.slug}://test`;
52+
};

src/queries/index.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,32 @@
1+
import {
2+
GET_EVENT_RECORD,
3+
GET_EVENT_RECORDS,
4+
GET_NEWS_ITEM,
5+
GET_NEWS_ITEMS,
6+
GET_POINT_OF_INTEREST,
7+
GET_POINTS_OF_INTEREST,
8+
GET_PUBLIC_JSON_FILE
9+
} from '../queries';
10+
11+
export const getQuery = (query) => {
12+
switch (query) {
13+
case 'eventRecord':
14+
return GET_EVENT_RECORD;
15+
case 'eventRecords':
16+
return GET_EVENT_RECORDS;
17+
case 'newsItems':
18+
return GET_NEWS_ITEMS;
19+
case 'newsItem':
20+
return GET_NEWS_ITEM;
21+
case 'pointOfInterest':
22+
return GET_POINT_OF_INTEREST;
23+
case 'pointsOfInterest':
24+
return GET_POINTS_OF_INTEREST;
25+
case 'publicJsonFile':
26+
return GET_PUBLIC_JSON_FILE;
27+
}
28+
};
29+
130
export * from './eventRecords';
231
export * from './newsItems';
332
export * from './pointsOfInterest';

src/screens/DetailScreen.js

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ import {
1515
Wrapper,
1616
WrapperRow
1717
} from '../components';
18-
import { GET_EVENT_RECORD, GET_NEWS_ITEM, GET_POINT_OF_INTEREST } from '../queries';
18+
import { getQuery } from '../queries';
1919
import { arrowLeft, drawerMenu, share } from '../icons';
20-
import { momentFormat } from '../helpers';
20+
import { momentFormat, openShare, trimNewLines } from '../helpers';
2121

2222
export class DetailScreen extends React.Component {
2323
static navigationOptions = ({ navigation }) => {
24+
const shareContent = navigation.getParam('shareContent', '');
25+
2426
return {
2527
headerLeft: (
2628
<View>
@@ -31,7 +33,7 @@ export class DetailScreen extends React.Component {
3133
),
3234
headerRight: (
3335
<WrapperRow>
34-
<TouchableOpacity onPress={() => alert('Share')}>
36+
<TouchableOpacity onPress={() => shareContent && openShare(shareContent)}>
3537
<Icon icon={share(colors.lightestText)} style={styles.iconLeft} />
3638
</TouchableOpacity>
3739
<TouchableOpacity onPress={() => navigation.openDrawer()}>
@@ -49,17 +51,6 @@ export class DetailScreen extends React.Component {
4951

5052
if (!query) return null;
5153

52-
const getQuery = (query) => {
53-
switch (query) {
54-
case 'eventRecord':
55-
return GET_EVENT_RECORD;
56-
case 'newsItem':
57-
return GET_NEWS_ITEM;
58-
case 'pointOfInterest':
59-
return GET_POINT_OF_INTEREST;
60-
}
61-
};
62-
6354
/* eslint-disable complexity */
6455
/* TODO: refactoring to single components */
6556
const getPage = (query, data) => {
@@ -135,8 +126,8 @@ export class DetailScreen extends React.Component {
135126
{!!subtitle && <ListSubtitle>{subtitle}</ListSubtitle>}
136127
{/*TODO: map multiple contentBlocks */}
137128
{!!title && <ListTitle noSubtitle>{title}</ListTitle>}
138-
{!!body && <HtmlView html={body} />}
139-
{!!link && <Link url={link} title={'Weiterlesen'} />}
129+
{!!body && <HtmlView html={trimNewLines(body)} />}
130+
{!!link && <Link url={link} title={'Im Browser öffnen'} />}
140131
</Wrapper>
141132
</ScrollView>
142133
);

src/screens/HomeScreen.js

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,8 @@ import { Query } from 'react-apollo';
55

66
import { device, normalize } from '../config';
77
import { CardList, Image, TextList, Title, TitleContainer, TitleShadow } from '../components';
8-
import {
9-
GET_EVENT_RECORDS,
10-
GET_NEWS_ITEMS,
11-
GET_POINTS_OF_INTEREST,
12-
GET_PUBLIC_JSON_FILE
13-
} from '../queries';
14-
import { momentFormat } from '../helpers';
8+
import { getQuery } from '../queries';
9+
import { momentFormat, shareMessage } from '../helpers';
1510

1611
export const HomeScreen = ({ navigation }) => (
1712
<ScrollView>
@@ -20,7 +15,7 @@ export const HomeScreen = ({ navigation }) => (
2015
<Title>{'Nachrichten'.toUpperCase()}</Title>
2116
</TitleContainer>
2217
{device.platform === 'ios' && <TitleShadow />}
23-
<Query query={GET_NEWS_ITEMS} variables={{ limit: 3 }} fetchPolicy="cache-and-network">
18+
<Query query={getQuery('newsItems')} variables={{ limit: 3 }} fetchPolicy="cache-and-network">
2419
{({ data, loading }) => {
2520
if (loading) {
2621
return (
@@ -43,7 +38,10 @@ export const HomeScreen = ({ navigation }) => (
4338
title: 'Nachricht',
4439
query: 'newsItem',
4540
queryVariables: { id: `${newsItem.id}` },
46-
rootRouteName: 'NewsItems'
41+
rootRouteName: 'NewsItems',
42+
shareContent: {
43+
message: shareMessage(newsItem, 'newsItem')
44+
}
4745
},
4846
__typename: newsItem.__typename
4947
}));
@@ -72,7 +70,11 @@ export const HomeScreen = ({ navigation }) => (
7270
<Title>{'Orte & Routen'.toUpperCase()}</Title>
7371
</TitleContainer>
7472
{device.platform === 'ios' && <TitleShadow />}
75-
<Query query={GET_POINTS_OF_INTEREST} variables={{ limit: 3 }} fetchPolicy="cache-and-network">
73+
<Query
74+
query={getQuery('pointsOfInterest')}
75+
variables={{ limit: 3 }}
76+
fetchPolicy="cache-and-network"
77+
>
7678
{({ data, loading }) => {
7779
if (loading) {
7880
return (
@@ -95,12 +97,15 @@ export const HomeScreen = ({ navigation }) => (
9597
title: 'Ort',
9698
query: 'pointOfInterest',
9799
queryVariables: { id: `${pointOfInterest.id}` },
98-
rootRouteName: 'PointsOfInterest'
100+
rootRouteName: 'PointsOfInterest',
101+
shareContent: {
102+
message: shareMessage(pointOfInterest, 'pointOfInterest')
103+
}
99104
},
100105
__typename: pointOfInterest.__typename
101106
}));
102107

103-
if (!pointsOfInterest.length) return null;
108+
if (!pointsOfInterest || !pointsOfInterest.length) return null;
104109

105110
return (
106111
<View>
@@ -131,7 +136,11 @@ export const HomeScreen = ({ navigation }) => (
131136
<Title>{'Veranstaltungen'.toUpperCase()}</Title>
132137
</TitleContainer>
133138
{device.platform === 'ios' && <TitleShadow />}
134-
<Query query={GET_EVENT_RECORDS} variables={{ limit: 3 }} fetchPolicy="cache-and-network">
139+
<Query
140+
query={getQuery('eventRecords')}
141+
variables={{ limit: 3 }}
142+
fetchPolicy="cache-and-network"
143+
>
135144
{({ data, loading }) => {
136145
if (loading) {
137146
return (
@@ -154,7 +163,10 @@ export const HomeScreen = ({ navigation }) => (
154163
title: 'Veranstaltung',
155164
query: 'eventRecord',
156165
queryVariables: { id: `${eventRecord.id}` },
157-
rootRouteName: 'EventRecords'
166+
rootRouteName: 'EventRecords',
167+
shareContent: {
168+
message: shareMessage(eventRecord, 'eventRecord')
169+
}
158170
},
159171
__typename: eventRecord.__typename
160172
}));
@@ -184,7 +196,7 @@ export const HomeScreen = ({ navigation }) => (
184196
</TitleContainer>
185197
{device.platform === 'ios' && <TitleShadow />}
186198
<Query
187-
query={GET_PUBLIC_JSON_FILE}
199+
query={getQuery('publicJsonFile')}
188200
variables={{ name: 'homeRoutes' }}
189201
fetchPolicy="cache-and-network"
190202
>

src/screens/IndexScreen.js

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import { Query } from 'react-apollo';
55

66
import { colors, normalize } from '../config';
77
import { CardList, Icon, TextList } from '../components';
8-
import { GET_EVENT_RECORDS, GET_NEWS_ITEMS, GET_POINTS_OF_INTEREST } from '../queries';
8+
import { getQuery } from '../queries';
99
import { arrowLeft } from '../icons';
10-
import { momentFormat } from '../helpers';
10+
import { momentFormat, shareMessage } from '../helpers';
1111

1212
export class IndexScreen extends React.Component {
1313
static navigationOptions = ({ navigation }) => {
@@ -29,17 +29,6 @@ export class IndexScreen extends React.Component {
2929

3030
if (!query) return null;
3131

32-
const getQuery = (query) => {
33-
switch (query) {
34-
case 'eventRecords':
35-
return GET_EVENT_RECORDS;
36-
case 'newsItems':
37-
return GET_NEWS_ITEMS;
38-
case 'pointsOfInterest':
39-
return GET_POINTS_OF_INTEREST;
40-
}
41-
};
42-
4332
const getListItems = (query, data) => {
4433
switch (query) {
4534
case 'eventRecords':
@@ -54,7 +43,10 @@ export class IndexScreen extends React.Component {
5443
title: 'Veranstaltung',
5544
query: 'eventRecord',
5645
queryVariables: { id: `${eventRecord.id}` },
57-
rootRouteName: 'EventRecords'
46+
rootRouteName: 'EventRecords',
47+
shareContent: {
48+
message: shareMessage(eventRecord, query)
49+
}
5850
}
5951
}))
6052
);
@@ -72,7 +64,10 @@ export class IndexScreen extends React.Component {
7264
title: 'Nachricht',
7365
query: 'newsItem',
7466
queryVariables: { id: `${newsItem.id}` },
75-
rootRouteName: 'NewsItems'
67+
rootRouteName: 'NewsItems',
68+
shareContent: {
69+
message: shareMessage(newsItem, query)
70+
}
7671
}
7772
}))
7873
);
@@ -90,7 +85,10 @@ export class IndexScreen extends React.Component {
9085
title: 'Ort',
9186
query: 'pointOfInterest',
9287
queryVariables: { id: `${pointOfInterest.id}` },
93-
rootRouteName: 'PointsOfInterest'
88+
rootRouteName: 'PointsOfInterest',
89+
shareContent: {
90+
message: shareMessage(pointOfInterest, query)
91+
}
9492
}
9593
}))
9694
);

0 commit comments

Comments
 (0)