@plusscommunities/pluss-core-app 1.6.0 → 1.6.3-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,6 +5,7 @@ export * from './contactActions';
5
5
  export * from './eventActions';
6
6
  export * from './analyticsActions';
7
7
  export * from './notificationActions';
8
+ export * from './stringActions';
8
9
  export * from './typeActions';
9
10
  export { default as userActions } from './userActions';
10
11
  export { default as profileActions } from './profileActions';
@@ -1 +1 @@
1
- {"version":3,"sources":["index.js"],"names":["default","userActions","profileActions"],"mappings":"AAAA,cAAc,mBAAd;AACA,cAAc,eAAd;AACA,cAAc,mBAAd;AACA,cAAc,kBAAd;AACA,cAAc,gBAAd;AACA,cAAc,oBAAd;AACA,cAAc,uBAAd;AACA,cAAc,eAAd;AACA,SAASA,OAAO,IAAIC,WAApB,QAAuC,eAAvC;AACA,SAASD,OAAO,IAAIE,cAApB,QAA0C,kBAA1C","sourcesContent":["export * from './reactionActions';\nexport * from './fileActions';\nexport * from './followerActions';\nexport * from './contactActions';\nexport * from './eventActions';\nexport * from './analyticsActions';\nexport * from './notificationActions';\nexport * from './typeActions';\nexport { default as userActions } from './userActions';\nexport { default as profileActions } from './profileActions';\n"]}
1
+ {"version":3,"sources":["index.js"],"names":["default","userActions","profileActions"],"mappings":"AAAA,cAAc,mBAAd;AACA,cAAc,eAAd;AACA,cAAc,mBAAd;AACA,cAAc,kBAAd;AACA,cAAc,gBAAd;AACA,cAAc,oBAAd;AACA,cAAc,uBAAd;AACA,cAAc,iBAAd;AACA,cAAc,eAAd;AACA,SAASA,OAAO,IAAIC,WAApB,QAAuC,eAAvC;AACA,SAASD,OAAO,IAAIE,cAApB,QAA0C,kBAA1C","sourcesContent":["export * from './reactionActions';\nexport * from './fileActions';\nexport * from './followerActions';\nexport * from './contactActions';\nexport * from './eventActions';\nexport * from './analyticsActions';\nexport * from './notificationActions';\nexport * from './stringActions';\nexport * from './typeActions';\nexport { default as userActions } from './userActions';\nexport { default as profileActions } from './profileActions';\n"]}
@@ -0,0 +1,30 @@
1
+ import axios from 'axios';
2
+ import { authedFunction } from '../session';
3
+ import { getUrl } from '../helper';
4
+ export const stringActions = {
5
+ getString: (site, id, useDefault) => {
6
+ const url = getUrl('strings', `get/${site}_${id}`, useDefault ? {
7
+ useDefault
8
+ } : undefined);
9
+ return axios({
10
+ method: 'GET',
11
+ url
12
+ }).catch(error => {
13
+ console.log('getString error', error);
14
+ throw error;
15
+ });
16
+ },
17
+ setString: (site, key, value) => {
18
+ const url = getUrl('strings', 'set');
19
+ return authedFunction({
20
+ method: 'POST',
21
+ url,
22
+ data: {
23
+ site,
24
+ key,
25
+ value
26
+ }
27
+ });
28
+ }
29
+ };
30
+ //# sourceMappingURL=stringActions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["stringActions.js"],"names":["axios","authedFunction","getUrl","stringActions","getString","site","id","useDefault","url","undefined","method","catch","error","console","log","setString","key","value","data"],"mappings":"AAAA,OAAOA,KAAP,MAAkB,OAAlB;AACA,SAASC,cAAT,QAA+B,YAA/B;AACA,SAASC,MAAT,QAAuB,WAAvB;AAEA,OAAO,MAAMC,aAAa,GAAG;AAC3BC,EAAAA,SAAS,EAAE,CAACC,IAAD,EAAOC,EAAP,EAAWC,UAAX,KAA0B;AACnC,UAAMC,GAAG,GAAGN,MAAM,CAAC,SAAD,EAAa,OAAMG,IAAK,IAAGC,EAAG,EAA9B,EAAiCC,UAAU,GAAG;AAAEA,MAAAA;AAAF,KAAH,GAAoBE,SAA/D,CAAlB;AACA,WAAOT,KAAK,CAAC;AACXU,MAAAA,MAAM,EAAE,KADG;AAEXF,MAAAA;AAFW,KAAD,CAAL,CAGJG,KAHI,CAGEC,KAAK,IAAI;AAChBC,MAAAA,OAAO,CAACC,GAAR,CAAY,iBAAZ,EAA+BF,KAA/B;AACA,YAAMA,KAAN;AACD,KANM,CAAP;AAOD,GAV0B;AAW3BG,EAAAA,SAAS,EAAE,CAACV,IAAD,EAAOW,GAAP,EAAYC,KAAZ,KAAsB;AAC/B,UAAMT,GAAG,GAAGN,MAAM,CAAC,SAAD,EAAY,KAAZ,CAAlB;AACA,WAAOD,cAAc,CAAC;AACpBS,MAAAA,MAAM,EAAE,MADY;AAEpBF,MAAAA,GAFoB;AAGpBU,MAAAA,IAAI,EAAE;AACJb,QAAAA,IADI;AAEJW,QAAAA,GAFI;AAGJC,QAAAA;AAHI;AAHc,KAAD,CAArB;AASD;AAtB0B,CAAtB","sourcesContent":["import axios from 'axios';\nimport { authedFunction } from '../session';\nimport { getUrl } from '../helper';\n\nexport const stringActions = {\n getString: (site, id, useDefault) => {\n const url = getUrl('strings', `get/${site}_${id}`, useDefault ? { useDefault } : undefined);\n return axios({\n method: 'GET',\n url,\n }).catch(error => {\n console.log('getString error', error);\n throw error;\n });\n },\n setString: (site, key, value) => {\n const url = getUrl('strings', 'set');\n return authedFunction({\n method: 'POST',\n url,\n data: {\n site,\n key,\n value,\n },\n });\n },\n};\n"]}
@@ -0,0 +1,137 @@
1
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
+
3
+ import React, { Component } from 'react';
4
+ import { View, Animated, StyleSheet } from 'react-native';
5
+ import moment from 'moment';
6
+ import { findLandmarkRange, getScaledOffset, get300 } from '../helper';
7
+
8
+ class AutoOffsetImage extends Component {
9
+ constructor(props) {
10
+ super(props);
11
+
12
+ _defineProperty(this, "onLoad", event => {
13
+ if (event.nativeEvent.source.uri === this.props.uri && !this.state.imageLoaded) {
14
+ //unblur
15
+ this.setState({
16
+ imageLoaded: true
17
+ });
18
+ Animated.sequence([Animated.delay(200), Animated.timing(this.state.blurRadius, {
19
+ toValue: 0,
20
+ duration: 500,
21
+ useNativeDriver: false
22
+ })]).start();
23
+ }
24
+ });
25
+
26
+ _defineProperty(this, "positionImage", async () => {
27
+ try {
28
+ const startTime = moment().valueOf();
29
+ const image = await findLandmarkRange(this.props.uri, {
30
+ targetWidth: this.props.width,
31
+ targetHeight: this.props.height
32
+ });
33
+ const scaledOffset = getScaledOffset(image.width, image.height, this.props.width, this.props.height);
34
+ const {
35
+ start: landmarkStart,
36
+ end: landmarkEnd
37
+ } = image;
38
+ const {
39
+ bounds: imageBounds,
40
+ offset,
41
+ width,
42
+ height
43
+ } = scaledOffset;
44
+
45
+ if (landmarkStart.y < imageBounds.start.y) {
46
+ // move up
47
+ offset.y = -Math.max(landmarkStart.y - this.props.height * this.paddingFactor, 0); // move top to 5% above start of landmark
48
+ } else if (landmarkEnd.y > imageBounds.end.y) {
49
+ // move down
50
+ offset.y = -Math.max(landmarkEnd.y + this.props.height * this.paddingFactor - this.props.height, 0); // move bottom to 5% below end of landmark
51
+ }
52
+
53
+ if (landmarkStart.x < imageBounds.start.x) {
54
+ // move right
55
+ offset.x = -Math.max(landmarkStart.x - this.props.width * this.paddingFactor, 0); // move left edge to 5% left of start of landmark
56
+ } else if (landmarkEnd.x > imageBounds.end.x) {
57
+ // move left
58
+ offset.x = -Math.max(landmarkEnd.x + this.props.width * this.paddingFactor - this.props.width, 0); // move right edge to 5% left of end of landmark
59
+ }
60
+
61
+ this.setState({
62
+ imageStyle: {
63
+ width,
64
+ height,
65
+ top: offset.y,
66
+ left: offset.x
67
+ },
68
+ imageSource: this.props.uri
69
+ });
70
+ const endTime = moment().valueOf();
71
+
72
+ if (endTime - startTime < 300) {
73
+ Animated.timing(this.state.blurRadius, {
74
+ toValue: 0,
75
+ duration: 0,
76
+ useNativeDriver: false
77
+ }).start();
78
+ }
79
+ } catch (e) {
80
+ this.setState({
81
+ imageSource: this.props.uri
82
+ });
83
+ }
84
+ });
85
+
86
+ this.paddingFactor = this.props.paddingFactor || 0.1;
87
+ this.state = {
88
+ imageStyle: {
89
+ width: this.props.width,
90
+ height: this.props.height
91
+ },
92
+ blurRadius: new Animated.Value(100),
93
+ imageSource: get300(this.props.uri)
94
+ };
95
+ }
96
+
97
+ componentDidMount() {
98
+ this.positionImage();
99
+ }
100
+
101
+ componentDidUpdate(prevProps) {
102
+ if (prevProps.uri !== this.props.uri || prevProps.height !== this.props.height || prevProps.width !== this.props.width) {
103
+ this.positionImage();
104
+ }
105
+ }
106
+
107
+ render() {
108
+ return /*#__PURE__*/React.createElement(View, {
109
+ style: [styles.container, {
110
+ width: this.props.width,
111
+ height: this.props.height
112
+ }, this.props.style]
113
+ }, /*#__PURE__*/React.createElement(Animated.Image, {
114
+ blurRadius: this.state.blurRadius,
115
+ source: {
116
+ uri: this.state.imageSource
117
+ },
118
+ style: [styles.image, this.state.imageStyle],
119
+ onLoad: this.onLoad
120
+ }), this.props.children);
121
+ }
122
+
123
+ }
124
+
125
+ const styles = StyleSheet.create({
126
+ container: {
127
+ overflow: 'hidden'
128
+ },
129
+ image: {
130
+ position: 'absolute',
131
+ top: 0,
132
+ left: 0,
133
+ resizeMode: 'cover'
134
+ }
135
+ });
136
+ export default AutoOffsetImage;
137
+ //# sourceMappingURL=AutoOffsetImage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["AutoOffsetImage.js"],"names":["React","Component","View","Animated","StyleSheet","moment","findLandmarkRange","getScaledOffset","get300","AutoOffsetImage","constructor","props","event","nativeEvent","source","uri","state","imageLoaded","setState","sequence","delay","timing","blurRadius","toValue","duration","useNativeDriver","start","startTime","valueOf","image","targetWidth","width","targetHeight","height","scaledOffset","landmarkStart","end","landmarkEnd","bounds","imageBounds","offset","y","Math","max","paddingFactor","x","imageStyle","top","left","imageSource","endTime","e","Value","componentDidMount","positionImage","componentDidUpdate","prevProps","render","styles","container","style","onLoad","children","create","overflow","position","resizeMode"],"mappings":"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","sourcesContent":["import React, { Component } from 'react';\nimport { View, Animated, StyleSheet } from 'react-native';\nimport moment from 'moment';\nimport { findLandmarkRange, getScaledOffset, get300 } from '../helper';\n\nclass AutoOffsetImage extends Component {\n constructor(props) {\n super(props);\n\n this.paddingFactor = this.props.paddingFactor || 0.1;\n\n this.state = {\n imageStyle: {\n width: this.props.width,\n height: this.props.height,\n },\n blurRadius: new Animated.Value(100),\n imageSource: get300(this.props.uri),\n };\n }\n\n componentDidMount() {\n this.positionImage();\n }\n\n componentDidUpdate(prevProps) {\n if (prevProps.uri !== this.props.uri || prevProps.height !== this.props.height || prevProps.width !== this.props.width) {\n this.positionImage();\n }\n }\n\n onLoad = event => {\n if (event.nativeEvent.source.uri === this.props.uri && !this.state.imageLoaded) {\n //unblur\n this.setState({\n imageLoaded: true,\n });\n Animated.sequence([\n Animated.delay(200),\n Animated.timing(this.state.blurRadius, {\n toValue: 0,\n duration: 500,\n useNativeDriver: false,\n }),\n ]).start();\n }\n };\n\n positionImage = async () => {\n try {\n const startTime = moment().valueOf();\n const image = await findLandmarkRange(this.props.uri, { targetWidth: this.props.width, targetHeight: this.props.height });\n const scaledOffset = getScaledOffset(image.width, image.height, this.props.width, this.props.height);\n\n const { start: landmarkStart, end: landmarkEnd } = image;\n const { bounds: imageBounds, offset, width, height } = scaledOffset;\n\n if (landmarkStart.y < imageBounds.start.y) {\n // move up\n offset.y = -Math.max(landmarkStart.y - this.props.height * this.paddingFactor, 0); // move top to 5% above start of landmark\n } else if (landmarkEnd.y > imageBounds.end.y) {\n // move down\n offset.y = -Math.max(landmarkEnd.y + this.props.height * this.paddingFactor - this.props.height, 0); // move bottom to 5% below end of landmark\n }\n\n if (landmarkStart.x < imageBounds.start.x) {\n // move right\n offset.x = -Math.max(landmarkStart.x - this.props.width * this.paddingFactor, 0); // move left edge to 5% left of start of landmark\n } else if (landmarkEnd.x > imageBounds.end.x) {\n // move left\n offset.x = -Math.max(landmarkEnd.x + this.props.width * this.paddingFactor - this.props.width, 0); // move right edge to 5% left of end of landmark\n }\n\n this.setState({\n imageStyle: {\n width,\n height,\n top: offset.y,\n left: offset.x,\n },\n imageSource: this.props.uri,\n });\n\n const endTime = moment().valueOf();\n if (endTime - startTime < 300) {\n Animated.timing(this.state.blurRadius, {\n toValue: 0,\n duration: 0,\n useNativeDriver: false,\n }).start();\n }\n } catch (e) {\n this.setState({\n imageSource: this.props.uri,\n });\n }\n };\n\n render() {\n return (\n <View\n style={[\n styles.container,\n {\n width: this.props.width,\n height: this.props.height,\n },\n this.props.style,\n ]}\n >\n <Animated.Image\n blurRadius={this.state.blurRadius}\n source={{ uri: this.state.imageSource }}\n style={[styles.image, this.state.imageStyle]}\n onLoad={this.onLoad}\n />\n {this.props.children}\n </View>\n );\n }\n}\n\nconst styles = StyleSheet.create({\n container: {\n overflow: 'hidden',\n },\n image: {\n position: 'absolute',\n top: 0,\n left: 0,\n resizeMode: 'cover',\n },\n});\n\nexport default AutoOffsetImage;\n"]}
@@ -48,6 +48,7 @@ export { default as ImageUploadProgress } from './ImageUploadProgress';
48
48
  export { default as UserListing } from './UserListing';
49
49
  export { default as PlussChat } from './PlussChat';
50
50
  export { default as PositionedImage } from './PositionedImage';
51
+ export { default as AutoOffsetImage } from './AutoOffsetImage';
51
52
  export { default as FormattedText } from './FormattedText';
52
53
  export { default as MediaPlayer } from './MediaPlayer';
53
54
  export { default as AudienceSelectorPage } from './AudienceSelectorPage';
@@ -1 +1 @@
1
- {"version":3,"sources":["index.js"],"names":["default","EmptyStateWidget","EmptyStateMain","LoadingStateWidget","Header","LoadingIndicator","ImageUploader","ImageUploadProgress","UserListing","PlussChat","PositionedImage","FormattedText","MediaPlayer","AudienceSelectorPage"],"mappings":"AAAA,cAAc,gBAAd;AACA,cAAc,uBAAd;AACA,cAAc,YAAd;AACA,cAAc,mBAAd;AACA,cAAc,iCAAd;AACA,cAAc,cAAd;AACA,cAAc,WAAd;AACA,cAAc,kBAAd;AACA,cAAc,SAAd;AACA,cAAc,cAAd;AACA,cAAc,cAAd;AACA,cAAc,gBAAd;AACA,cAAc,eAAd;AACA,cAAc,gBAAd;AACA,cAAc,qBAAd;AACA,cAAc,kBAAd;AACA,cAAc,gBAAd;AACA,cAAc,aAAd;AACA,cAAc,aAAd;AACA,cAAc,cAAd;AACA,cAAc,uBAAd;AACA,cAAc,gBAAd;AACA,cAAc,eAAd;AACA,cAAc,YAAd;AACA,cAAc,aAAd;AACA,cAAc,UAAd;AACA,cAAc,SAAd;AACA,cAAc,gBAAd;AACA,cAAc,gBAAd;AACA,cAAc,gBAAd;AACA,cAAc,gBAAd;AACA,cAAc,cAAd;AACA,cAAc,YAAd;AACA,cAAc,sBAAd;AACA,cAAc,gBAAd;AACA,cAAc,kBAAd;AACA,cAAc,mBAAd;AACA,cAAc,iBAAd;AACA,cAAc,aAAd;AACA,cAAc,4BAAd;AACA,SAASA,OAAO,IAAIC,gBAApB,QAA4C,oBAA5C;AACA,SAASD,OAAO,IAAIE,cAApB,QAA0C,kBAA1C;AACA,SAASF,OAAO,IAAIG,kBAApB,QAA8C,sBAA9C;AACA,SAASH,OAAO,IAAII,MAApB,QAAkC,UAAlC;AACA,SAASJ,OAAO,IAAIK,gBAApB,QAA4C,oBAA5C;AACA,SAASL,OAAO,IAAIM,aAApB,QAAyC,iBAAzC;AACA,SAASN,OAAO,IAAIO,mBAApB,QAA+C,uBAA/C;AACA,SAASP,OAAO,IAAIQ,WAApB,QAAuC,eAAvC;AACA,SAASR,OAAO,IAAIS,SAApB,QAAqC,aAArC;AACA,SAAST,OAAO,IAAIU,eAApB,QAA2C,mBAA3C;AACA,SAASV,OAAO,IAAIW,aAApB,QAAyC,iBAAzC;AACA,SAASX,OAAO,IAAIY,WAApB,QAAuC,eAAvC;AACA,SAASZ,OAAO,IAAIa,oBAApB,QAAgD,wBAAhD","sourcesContent":["export * from './InlineButton';\nexport * from './AddToCalendarButton';\nexport * from './FormCard';\nexport * from './FormCardSection';\nexport * from './FormCardSectionOptionLauncher';\nexport * from './ProfilePic';\nexport * from './Spinner';\nexport * from './LoadingCircles';\nexport * from './Popup';\nexport * from './ImagePopup';\nexport * from './VideoPopup';\nexport * from './SharingTools';\nexport * from './MiddlePopup';\nexport * from './ConfirmPopup';\nexport * from './ConfirmationPopup';\nexport * from './CommentSection';\nexport * from './CommentReply';\nexport * from './PopupMenu';\nexport * from './AddButton';\nexport * from './Attachment';\nexport * from './GenericInputSection';\nexport * from './GenericInput';\nexport * from './RadioButton';\nexport * from './PDFPopup';\nexport * from './TextStyle';\nexport * from './Toggle';\nexport * from './Input';\nexport * from './StickyFooter';\nexport * from './CategoryTabs';\nexport * from './DropDownMenu';\nexport * from './DropDownItem';\nexport * from './BackButton';\nexport * from './Reaction';\nexport * from './TouchableSearchBar';\nexport * from './WarningPopup';\nexport * from './FontScalePopup';\nexport * from './FontScaleButton';\nexport * from './UserListPopup';\nexport * from './Reactions';\nexport * from './AudienceSelectorLauncher';\nexport { default as EmptyStateWidget } from './EmptyStateWidget';\nexport { default as EmptyStateMain } from './EmptyStateMain';\nexport { default as LoadingStateWidget } from './LoadingStateWidget';\nexport { default as Header } from './Header';\nexport { default as LoadingIndicator } from './LoadingIndicator';\nexport { default as ImageUploader } from './ImageUploader';\nexport { default as ImageUploadProgress } from './ImageUploadProgress';\nexport { default as UserListing } from './UserListing';\nexport { default as PlussChat } from './PlussChat';\nexport { default as PositionedImage } from './PositionedImage';\nexport { default as FormattedText } from './FormattedText';\nexport { default as MediaPlayer } from './MediaPlayer';\nexport { default as AudienceSelectorPage } from './AudienceSelectorPage';\n"]}
1
+ {"version":3,"sources":["index.js"],"names":["default","EmptyStateWidget","EmptyStateMain","LoadingStateWidget","Header","LoadingIndicator","ImageUploader","ImageUploadProgress","UserListing","PlussChat","PositionedImage","AutoOffsetImage","FormattedText","MediaPlayer","AudienceSelectorPage"],"mappings":"AAAA,cAAc,gBAAd;AACA,cAAc,uBAAd;AACA,cAAc,YAAd;AACA,cAAc,mBAAd;AACA,cAAc,iCAAd;AACA,cAAc,cAAd;AACA,cAAc,WAAd;AACA,cAAc,kBAAd;AACA,cAAc,SAAd;AACA,cAAc,cAAd;AACA,cAAc,cAAd;AACA,cAAc,gBAAd;AACA,cAAc,eAAd;AACA,cAAc,gBAAd;AACA,cAAc,qBAAd;AACA,cAAc,kBAAd;AACA,cAAc,gBAAd;AACA,cAAc,aAAd;AACA,cAAc,aAAd;AACA,cAAc,cAAd;AACA,cAAc,uBAAd;AACA,cAAc,gBAAd;AACA,cAAc,eAAd;AACA,cAAc,YAAd;AACA,cAAc,aAAd;AACA,cAAc,UAAd;AACA,cAAc,SAAd;AACA,cAAc,gBAAd;AACA,cAAc,gBAAd;AACA,cAAc,gBAAd;AACA,cAAc,gBAAd;AACA,cAAc,cAAd;AACA,cAAc,YAAd;AACA,cAAc,sBAAd;AACA,cAAc,gBAAd;AACA,cAAc,kBAAd;AACA,cAAc,mBAAd;AACA,cAAc,iBAAd;AACA,cAAc,aAAd;AACA,cAAc,4BAAd;AACA,SAASA,OAAO,IAAIC,gBAApB,QAA4C,oBAA5C;AACA,SAASD,OAAO,IAAIE,cAApB,QAA0C,kBAA1C;AACA,SAASF,OAAO,IAAIG,kBAApB,QAA8C,sBAA9C;AACA,SAASH,OAAO,IAAII,MAApB,QAAkC,UAAlC;AACA,SAASJ,OAAO,IAAIK,gBAApB,QAA4C,oBAA5C;AACA,SAASL,OAAO,IAAIM,aAApB,QAAyC,iBAAzC;AACA,SAASN,OAAO,IAAIO,mBAApB,QAA+C,uBAA/C;AACA,SAASP,OAAO,IAAIQ,WAApB,QAAuC,eAAvC;AACA,SAASR,OAAO,IAAIS,SAApB,QAAqC,aAArC;AACA,SAAST,OAAO,IAAIU,eAApB,QAA2C,mBAA3C;AACA,SAASV,OAAO,IAAIW,eAApB,QAA2C,mBAA3C;AACA,SAASX,OAAO,IAAIY,aAApB,QAAyC,iBAAzC;AACA,SAASZ,OAAO,IAAIa,WAApB,QAAuC,eAAvC;AACA,SAASb,OAAO,IAAIc,oBAApB,QAAgD,wBAAhD","sourcesContent":["export * from './InlineButton';\nexport * from './AddToCalendarButton';\nexport * from './FormCard';\nexport * from './FormCardSection';\nexport * from './FormCardSectionOptionLauncher';\nexport * from './ProfilePic';\nexport * from './Spinner';\nexport * from './LoadingCircles';\nexport * from './Popup';\nexport * from './ImagePopup';\nexport * from './VideoPopup';\nexport * from './SharingTools';\nexport * from './MiddlePopup';\nexport * from './ConfirmPopup';\nexport * from './ConfirmationPopup';\nexport * from './CommentSection';\nexport * from './CommentReply';\nexport * from './PopupMenu';\nexport * from './AddButton';\nexport * from './Attachment';\nexport * from './GenericInputSection';\nexport * from './GenericInput';\nexport * from './RadioButton';\nexport * from './PDFPopup';\nexport * from './TextStyle';\nexport * from './Toggle';\nexport * from './Input';\nexport * from './StickyFooter';\nexport * from './CategoryTabs';\nexport * from './DropDownMenu';\nexport * from './DropDownItem';\nexport * from './BackButton';\nexport * from './Reaction';\nexport * from './TouchableSearchBar';\nexport * from './WarningPopup';\nexport * from './FontScalePopup';\nexport * from './FontScaleButton';\nexport * from './UserListPopup';\nexport * from './Reactions';\nexport * from './AudienceSelectorLauncher';\nexport { default as EmptyStateWidget } from './EmptyStateWidget';\nexport { default as EmptyStateMain } from './EmptyStateMain';\nexport { default as LoadingStateWidget } from './LoadingStateWidget';\nexport { default as Header } from './Header';\nexport { default as LoadingIndicator } from './LoadingIndicator';\nexport { default as ImageUploader } from './ImageUploader';\nexport { default as ImageUploadProgress } from './ImageUploadProgress';\nexport { default as UserListing } from './UserListing';\nexport { default as PlussChat } from './PlussChat';\nexport { default as PositionedImage } from './PositionedImage';\nexport { default as AutoOffsetImage } from './AutoOffsetImage';\nexport { default as FormattedText } from './FormattedText';\nexport { default as MediaPlayer } from './MediaPlayer';\nexport { default as AudienceSelectorPage } from './AudienceSelectorPage';\n"]}
@@ -3,7 +3,11 @@ import { Platform, StatusBar, Dimensions } from 'react-native';
3
3
  import Constants from 'expo-constants';
4
4
  import Config from './config';
5
5
  import { LINEGREY } from './colours';
6
- import { getSessionTokenAWS } from './session';
6
+ import { getSessionTokenAWS } from './session'; // seperated files to export
7
+
8
+ import detectFaces from './js/images/detectFaces';
9
+ import findLandmarkRange from './js/images/findLandmarkRange';
10
+ import getScaledOffset from './js/images/getScaledOffset';
7
11
  const TIMESTAMP_FORMAT = 'D MMM • h:mma';
8
12
  const DATE_FORMAT = 'D MMM YYYY';
9
13
 
@@ -177,6 +181,25 @@ const get1400 = url => {
177
181
  return url;
178
182
  };
179
183
 
184
+ const get300 = url => {
185
+ if (!url) {
186
+ return url;
187
+ }
188
+
189
+ if (isStockImage(url) || url.indexOf(Config.env.baseUploadsUrl) !== -1) {
190
+ const extension = getExtension(url);
191
+ let urlToUse = url;
192
+
193
+ if (extension !== 'jpg') {
194
+ urlToUse = `${url.substring(0, url.length - extension.length)}jpg`;
195
+ }
196
+
197
+ return urlToUse.replace('/uploads/', '/300/').replace('/1400/', '/300/');
198
+ }
199
+
200
+ return url;
201
+ };
202
+
180
203
  const getMimeType = url => {
181
204
  const extension = getExtension(url);
182
205
 
@@ -432,5 +455,5 @@ const allowComments = canComment => {
432
455
  return Config.env.defaultAllowComments;
433
456
  };
434
457
 
435
- export { TIMESTAMP_FORMAT, DATE_FORMAT, getUrl, getAuthTokenHeader, getShadowStyle, StatusBarHeight, getStatusBarHeight, getSiteSettingFromState, getValueOrDefault, getExtension, getFileName, isVideo, getThumb300, get1400, getMimeType, getCompressed, imageExists, getPluralS, getPluralOptions, randomString, generateImageName, getSite, getImageSource, getFirstName, usersToSearchResult, searchUsers, getEnabledTabsFromState, getReactions, hasReacted, isTablet, isYoutube, getYoutubeEmbed, getValidUrl, getUserPreview, allowComments, isVideoUrl };
458
+ export { TIMESTAMP_FORMAT, DATE_FORMAT, getUrl, getAuthTokenHeader, getShadowStyle, StatusBarHeight, getStatusBarHeight, getSiteSettingFromState, getValueOrDefault, getExtension, getFileName, isVideo, get300, getThumb300, get1400, getMimeType, getCompressed, imageExists, getPluralS, getPluralOptions, randomString, generateImageName, getSite, getImageSource, getFirstName, usersToSearchResult, searchUsers, getEnabledTabsFromState, getReactions, hasReacted, isTablet, isYoutube, getYoutubeEmbed, getValidUrl, getUserPreview, allowComments, isVideoUrl, detectFaces, findLandmarkRange, getScaledOffset };
436
459
  //# sourceMappingURL=helper.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["helper.js"],"names":["_","Platform","StatusBar","Dimensions","Constants","Config","LINEGREY","getSessionTokenAWS","TIMESTAMP_FORMAT","DATE_FORMAT","getUrl","baseAction","action","query","baseAPIUrl","baseStage","env","queryPart","keys","forEach","key","index","encodeURIComponent","getAuthTokenHeader","Promise","resolve","reject","then","idToken","getShadowStyle","OS","shadowColor","shadowOffset","width","height","shadowOpacity","shadowRadius","backgroundColor","borderColor","elevation","StatusBarHeight","size","getStatusBarHeight","statusBarHeight","currentHeight","getSiteSettingFromState","state","defaultValue","user","siteSettings","isUndefined","getValueOrDefault","value","def","getExtension","url","fileSplit","split","length","toLowerCase","getFileName","noExtension","name","isVideo","extension","includes","isVideoUrl","urlToCheck","getValidUrl","isYoutube","isVimeo","isStockImage","indexOf","getThumb300","replace","baseUploadsUrl","urlToUse","substring","get1400","getMimeType","getCompressed","imageExists","fetch","method","cache","response","status","catch","getPluralS","count","getPluralOptions","singular","plural","randomString","c","r","Math","random","v","toString","generateImageName","source","result","last","getSite","site","preferredSite","getTakeoverThumb","uri","filename","pop","getTakeoverImage","getImageSource","isThumb","getFirstName","isEmpty","usersToSearchResult","contacts","excludedUserIds","push","displayName","id","objectID","ID","userId","Id","profilePic","photoURL","unit","contact","searchUsers","term","filter","some","part","getTabSettingsFromState","tabSettings","interface","getEnabledTabsFromState","tab","isEnabled","getReactions","icon","require","hasReacted","reactions","isTablet","get","getVimeoEmbed","vimeoId","regExp","match","getYoutubeEmbed","newUrl","decodeURIComponent","trim","test","getUserPreview","uid","allowComments","canComment","defaultAllowComments"],"mappings":"AAAA,OAAOA,CAAP,MAAc,QAAd;AACA,SAASC,QAAT,EAAmBC,SAAnB,EAA8BC,UAA9B,QAAgD,cAAhD;AACA,OAAOC,SAAP,MAAsB,gBAAtB;AACA,OAAOC,MAAP,MAAmB,UAAnB;AACA,SAASC,QAAT,QAAyB,WAAzB;AACA,SAASC,kBAAT,QAAmC,WAAnC;AAEA,MAAMC,gBAAgB,GAAG,eAAzB;AACA,MAAMC,WAAW,GAAG,YAApB;;AAEA,MAAMC,MAAM,GAAG,CAACC,UAAD,EAAaC,MAAb,EAAqBC,KAArB,KAA+B;AAC5C,QAAM;AAAEC,IAAAA,UAAF;AAAcC,IAAAA;AAAd,MAA4BV,MAAM,CAACW,GAAzC;AACA,MAAIC,SAAS,GAAG,EAAhB;;AACA,MAAIJ,KAAJ,EAAW;AACTb,IAAAA,CAAC,CAACkB,IAAF,CAAOL,KAAP,EAAcM,OAAd,CAAsB,CAACC,GAAD,EAAMC,KAAN,KAAgB;AACpCJ,MAAAA,SAAS,IAAK,GAAEI,KAAK,KAAK,CAAV,GAAc,GAAd,GAAoB,GAAI,GAAED,GAAI,IAAGE,kBAAkB,CAACT,KAAK,CAACO,GAAD,CAAN,CAAa,EAAhF;AACD,KAFD;AAGD;;AACD,SAAQ,GAAEN,UAAW,IAAGH,UAAW,IAAGI,SAAU,IAAGH,MAAO,GAAEK,SAAU,EAAtE;AACD,CATD;;AAWA,MAAMM,kBAAkB,GAAG,MAAM;AAC/B,SAAO,IAAIC,OAAJ,CAAY,CAACC,OAAD,EAAUC,MAAV,KAAqB;AACtCnB,IAAAA,kBAAkB,GAAGoB,IAArB,CAA0BC,OAAO,IAAI;AACnCH,MAAAA,OAAO,CAAE,UAASG,OAAQ,EAAnB,CAAP;AACD,KAFD;AAGD,GAJM,CAAP;AAKD,CAND;;AAQA,MAAMC,cAAc,GAAG,MAAM;AAC3B,MAAI5B,QAAQ,CAAC6B,EAAT,KAAgB,KAApB,EAA2B;AACzB,WAAO;AACLC,MAAAA,WAAW,EAAE,MADR;AAELC,MAAAA,YAAY,EAAE;AACZC,QAAAA,KAAK,EAAE,CADK;AAEZC,QAAAA,MAAM,EAAE;AAFI,OAFT;AAMLC,MAAAA,aAAa,EAAE,GANV;AAOLC,MAAAA,YAAY,EAAE,CAPT;AAQLC,MAAAA,eAAe,EAAE;AARZ,KAAP;AAUD;;AACD,SAAO;AACLC,IAAAA,WAAW,EAAEhC,QADR;AAEL+B,IAAAA,eAAe,EAAE,MAFZ;AAGLE,IAAAA,SAAS,EAAE;AAHN,GAAP;AAKD,CAlBD;;AAoBA,MAAMC,eAAe,GAAGC,IAAI,IAAI;AAC9B,SAAOC,kBAAkB,KAAKD,IAA9B;AACD,CAFD;;AAIA,MAAMC,kBAAkB,GAAG,MAAM;AAC/B,SAAOzC,QAAQ,CAAC6B,EAAT,KAAgB,KAAhB,GAAwB1B,SAAS,CAACuC,eAAlC,GAAoDzC,SAAS,CAAC0C,aAArE;AACD,CAFD;;AAIA,MAAMC,uBAAuB,GAAG,CAACC,KAAD,EAAQ1B,GAAR,EAAa2B,YAAb,KAA8B;AAC5D,MAAID,KAAK,IAAIA,KAAK,CAACE,IAAf,IAAuBF,KAAK,CAACE,IAAN,CAAWC,YAAlC,IAAkD,CAACjD,CAAC,CAACkD,WAAF,CAAcJ,KAAK,CAACE,IAAN,CAAWC,YAAX,CAAwB7B,GAAxB,CAAd,CAAvD,EAAoG;AAClG,WAAO0B,KAAK,CAACE,IAAN,CAAWC,YAAX,CAAwB7B,GAAxB,CAAP;AACD;;AACD,SAAO2B,YAAY,IAAI,IAAvB;AACD,CALD;;AAOA,MAAMI,iBAAiB,GAAG,CAACC,KAAD,EAAQC,GAAR,KAAgB;AACxC,SAAO,CAACrD,CAAC,CAACkD,WAAF,CAAcE,KAAd,CAAD,GAAwBA,KAAxB,GAAgCC,GAAvC;AACD,CAFD;;AAIA,MAAMC,YAAY,GAAGC,GAAG,IAAI;AAC1B,MAAI,CAACA,GAAL,EAAU;AACR,WAAO,IAAP;AACD;;AACD,QAAMC,SAAS,GAAGD,GAAG,CAACE,KAAJ,CAAU,GAAV,CAAlB;AACA,SAAOD,SAAS,CAACA,SAAS,CAACE,MAAV,GAAmB,CAApB,CAAT,CAAgCC,WAAhC,EAAP;AACD,CAND;;AAQA,MAAMC,WAAW,GAAG,CAACL,GAAD,EAAMM,WAAN,KAAsB;AACxC,MAAI,CAACN,GAAL,EAAU;AACR,WAAO,IAAP;AACD;;AACD,QAAMC,SAAS,GAAGD,GAAG,CAACE,KAAJ,CAAU,GAAV,CAAlB;AACA,QAAMK,IAAI,GAAGN,SAAS,CAACA,SAAS,CAACE,MAAV,GAAmB,CAApB,CAAT,CAAgCC,WAAhC,EAAb;;AACA,MAAI,CAACE,WAAL,EAAkB;AAChB,WAAOC,IAAP;AACD;;AACD,SAAOA,IAAI,CAACL,KAAL,CAAW,GAAX,EAAgB,CAAhB,CAAP;AACD,CAVD;;AAYA,MAAMM,OAAO,GAAGR,GAAG,IAAI;AACrB,QAAMS,SAAS,GAAGV,YAAY,CAACC,GAAD,CAA9B;AACA,SAAO,CAAC,KAAD,EAAQ,KAAR,EAAeU,QAAf,CAAwBD,SAAxB,CAAP;AACD,CAHD;;AAKA,MAAME,UAAU,GAAGX,GAAG,IAAI;AACxB,QAAMY,UAAU,GAAGC,WAAW,CAACb,GAAD,CAA9B;;AACA,MAAIQ,OAAO,CAACI,UAAD,CAAX,EAAyB;AACvB,WAAO,IAAP;AACD;;AACD,MAAIE,SAAS,CAACF,UAAD,CAAb,EAA2B;AACzB,WAAO,IAAP;AACD;;AACD,MAAIG,OAAO,CAACH,UAAD,CAAX,EAAyB;AACvB,WAAO,IAAP;AACD;;AACD,SAAO,KAAP;AACD,CAZD;;AAcA,MAAMI,YAAY,GAAGhB,GAAG,IAAI;AAC1B,SAAOA,GAAG,CAACiB,OAAJ,CAAY,6EAAZ,MAA+F,CAAC,CAAvG;AACD,CAFD;;AAIA,MAAMC,WAAW,GAAGlB,GAAG,IAAI;AACzB,MAAI,CAACA,GAAL,EAAU;AACR,WAAOA,GAAP;AACD;;AACD,MAAIA,GAAG,CAACiB,OAAJ,CAAY,gDAAZ,MAAkE,CAAC,CAAvE,EAA0E;AACxE,WAAOjB,GAAG,CAACmB,OAAJ,CAAY,gDAAZ,EAA8D,iCAA9D,CAAP;AACD;;AACD,MAAInB,GAAG,CAACiB,OAAJ,CAAY,iCAAZ,MAAmD,CAAC,CAAxD,EAA2D;AACzD,WAAOjB,GAAG,CACPmB,OADI,CACI,WADJ,EACiB,iBADjB,EAEJA,OAFI,CAEI,WAFJ,EAEiB,cAFjB,EAGJA,OAHI,CAGI,eAHJ,EAGqB,iBAHrB,EAIJA,OAJI,CAII,eAJJ,EAIqB,cAJrB,CAAP;AAKD;;AACD,MAAIH,YAAY,CAAChB,GAAD,CAAZ,IAAqBA,GAAG,CAACiB,OAAJ,CAAYnE,MAAM,CAACW,GAAP,CAAW2D,cAAvB,MAA2C,CAAC,CAArE,EAAwE;AACtE,UAAMX,SAAS,GAAGV,YAAY,CAACC,GAAD,CAA9B;AACA,QAAIqB,QAAQ,GAAGrB,GAAf;;AACA,QAAIS,SAAS,KAAK,KAAlB,EAAyB;AACvBY,MAAAA,QAAQ,GAAI,GAAErB,GAAG,CAACsB,SAAJ,CAAc,CAAd,EAAiBtB,GAAG,CAACG,MAAJ,GAAaM,SAAS,CAACN,MAAxC,CAAgD,KAA9D;AACD;;AACD,WAAOkB,QAAQ,CAACF,OAAT,CAAiB,QAAjB,EAA2B,YAA3B,EAAyCA,OAAzC,CAAiD,WAAjD,EAA8D,YAA9D,CAAP;AACD;;AACD,SAAOnB,GAAP;AACD,CAvBD;;AAyBA,MAAMuB,OAAO,GAAGvB,GAAG,IAAI;AACrB,MAAI,CAACA,GAAL,EAAU;AACR,WAAOA,GAAP;AACD;;AACD,MAAIA,GAAG,CAACiB,OAAJ,CAAY,gDAAZ,MAAkE,CAAC,CAAvE,EAA0E;AACxE,WAAOjB,GAAG,CAACmB,OAAJ,CAAY,gDAAZ,EAA8D,iCAA9D,CAAP;AACD;;AACD,MAAInB,GAAG,CAACiB,OAAJ,CAAY,iCAAZ,MAAmD,CAAC,CAAxD,EAA2D;AACzD,WAAOjB,GAAG,CAACmB,OAAJ,CAAY,WAAZ,EAAyB,eAAzB,EAA0CA,OAA1C,CAAkD,WAAlD,EAA+D,eAA/D,CAAP;AACD;;AACD,MAAIH,YAAY,CAAChB,GAAD,CAAZ,IAAqBA,GAAG,CAACiB,OAAJ,CAAYnE,MAAM,CAACW,GAAP,CAAW2D,cAAvB,MAA2C,CAAC,CAArE,EAAwE;AACtE,UAAMX,SAAS,GAAGV,YAAY,CAACC,GAAD,CAA9B;AACA,QAAIqB,QAAQ,GAAGrB,GAAf;;AACA,QAAIS,SAAS,KAAK,KAAlB,EAAyB;AACvBY,MAAAA,QAAQ,GAAI,GAAErB,GAAG,CAACsB,SAAJ,CAAc,CAAd,EAAiBtB,GAAG,CAACG,MAAJ,GAAaM,SAAS,CAACN,MAAxC,CAAgD,KAA9D;AACD;;AACD,WAAOkB,QAAQ,CAACF,OAAT,CAAiB,WAAjB,EAA8B,QAA9B,CAAP;AACD;;AACD,SAAOnB,GAAP;AACD,CAnBD;;AAqBA,MAAMwB,WAAW,GAAGxB,GAAG,IAAI;AACzB,QAAMS,SAAS,GAAGV,YAAY,CAACC,GAAD,CAA9B;;AACA,UAAQS,SAAR;AACE,SAAK,KAAL;AACE,aAAO,iBAAP;;AACF,SAAK,KAAL;AACE,aAAO,WAAP;;AACF;AACE,aAAO,YAAP;AANJ;AAQD,CAVD;;AAYA,MAAMgB,aAAa,GAAGzB,GAAG,IAAI;AAC3B,MAAI,CAACA,GAAD,IAAQ,OAAOA,GAAP,KAAe,QAA3B,EAAqC,OAAO,EAAP;AACrC,SAAOA,GAAG,CAACmB,OAAJ,CAAY,WAAZ,EAAyB,cAAzB,CAAP;AACD,CAHD;;AAKA,MAAMO,WAAW,GAAG1B,GAAG,IAAI;AACzB,SAAO,IAAI/B,OAAJ,CAAYC,OAAO,IAAI;AAC5ByD,IAAAA,KAAK,CAAC3B,GAAD,EAAM;AAAE4B,MAAAA,MAAM,EAAE,MAAV;AAAkBC,MAAAA,KAAK,EAAE;AAAzB,KAAN,CAAL,CACGzD,IADH,CACQ0D,QAAQ,IAAI;AAChB5D,MAAAA,OAAO,CAAC4D,QAAQ,CAACC,MAAT,KAAoB,GAArB,CAAP;AACD,KAHH,EAIGC,KAJH,CAIS,MAAM;AACX9D,MAAAA,OAAO,CAAC,KAAD,CAAP;AACD,KANH;AAOD,GARM,CAAP;AASD,CAVD;;AAYA,MAAM+D,UAAU,GAAGC,KAAK,IAAI;AAC1B,SAAOA,KAAK,KAAK,CAAV,GAAc,EAAd,GAAmB,GAA1B;AACD,CAFD;;AAIA,MAAMC,gBAAgB,GAAG,CAACD,KAAD,EAAQE,QAAR,EAAkBC,MAAlB,KAA6B;AACpD,MAAIH,KAAK,KAAK,CAAd,EAAiB;AACf,WAAOE,QAAP;AACD;;AACD,SAAOC,MAAP;AACD,CALD;;AAOA,MAAMC,YAAY,GAAG,YAAe;AAAA,MAAd/B,IAAc,uEAAP,EAAO;AAClC,SAAQ,6BAA4BA,IAAK,EAAlC,CAAoCY,OAApC,CAA4C,OAA5C,EAAqDoB,CAAC,IAAI;AAC/D;AACA,QAAIC,CAAC,GAAIC,IAAI,CAACC,MAAL,KAAgB,EAAjB,GAAuB,CAA/B;AAAA,QACEC,CAAC,GAAGJ,CAAC,KAAK,GAAN,GAAYC,CAAZ,GAAiBA,CAAC,GAAG,GAAL,GAAY,GADlC;AAEA,WAAOG,CAAC,CAACC,QAAF,CAAW,EAAX,CAAP;AACD,GALM,CAAP;AAMD,CAPD;;AASA,MAAMC,iBAAiB,GAAG,CAACtC,IAAD,EAAOuC,MAAP,KAAkB;AAC1C,MAAIC,MAAM,GAAGT,YAAY,CAAC/B,IAAD,CAAzB;;AACA,MAAIuC,MAAJ,EAAY;AACVC,IAAAA,MAAM,IAAK,IAAGtG,CAAC,CAACuG,IAAF,CAAOF,MAAM,CAAC5C,KAAP,CAAa,GAAb,CAAP,CAA0B,EAAxC;AACD;;AACD,SAAO6C,MAAP;AACD,CAND;;AAQA,MAAME,OAAO,GAAGC,IAAI,IAAI;AACtB,SAAOA,IAAI,KAAK,YAAT,IAAyBA,IAAI,KAAK,IAAlC,GAAyCpG,MAAM,CAACW,GAAP,CAAW0F,aAApD,GAAoED,IAA3E;AACD,CAFD;;AAIA,MAAME,gBAAgB,GAAGC,GAAG,IAAI;AAC9B,QAAMC,QAAQ,GAAGD,GAAG,CAACnD,KAAJ,CAAU,GAAV,EAAeqD,GAAf,EAAjB;;AACA,UAAQD,QAAR;AACE;AACE,aAAO;AAAED,QAAAA;AAAF,OAAP;AAFJ;AAID,CAND;;AAQA,MAAMG,gBAAgB,GAAGH,GAAG,IAAI;AAC9B,QAAMC,QAAQ,GAAGD,GAAG,CAACnD,KAAJ,CAAU,GAAV,EAAeqD,GAAf,EAAjB;;AACA,UAAQD,QAAR;AACE;AACE,aAAO;AAAED,QAAAA;AAAF,OAAP;AAFJ;AAID,CAND;;AAQA,MAAMI,cAAc,GAAG,CAACJ,GAAD,EAAMK,OAAN,KAAkB;AACvC,MAAIL,GAAG,IAAI,IAAX,EAAiB,OAAO,IAAP;AACjB,MAAIK,OAAJ,EAAa,OAAON,gBAAgB,CAACC,GAAD,CAAvB;AACb,SAAOG,gBAAgB,CAACH,GAAD,CAAvB;AACD,CAJD;;AAMA,MAAMM,YAAY,GAAGpD,IAAI,IAAI;AAC3B,MAAI9D,CAAC,CAACmH,OAAF,CAAUrD,IAAV,CAAJ,EAAqB;AACnB,WAAOA,IAAP;AACD;;AACD,SAAOA,IAAI,CAACL,KAAL,CAAW,GAAX,EAAgB,CAAhB,CAAP;AACD,CALD;;AAOA,MAAM2D,mBAAmB,GAAG,CAACC,QAAD,EAAWC,eAAX,KAA+B;AACzD,MAAIhB,MAAM,GAAG,EAAb;AACAe,EAAAA,QAAQ,CAAClG,OAAT,CAAiB6B,IAAI,IAAI;AACvBsD,IAAAA,MAAM,CAACiB,IAAP,CAAY;AACVC,MAAAA,WAAW,EAAExE,IAAI,CAACwE,WADR;AAEVC,MAAAA,EAAE,EAAEzE,IAAI,CAAC0E,QAAL,IAAiB1E,IAAI,CAACyE,EAAtB,IAA4BzE,IAAI,CAAC2E,EAAjC,IAAuC3E,IAAI,CAAC4E,MAA5C,IAAsD5E,IAAI,CAAC6E,EAFrD;AAGVC,MAAAA,UAAU,EAAE9E,IAAI,CAAC8E,UAAL,IAAmB9E,IAAI,CAAC+E,QAAxB,IAAoC,IAHtC;AAIVC,MAAAA,IAAI,EAAEhF,IAAI,CAACgF;AAJD,KAAZ;AAMD,GAPD;AAQA1B,EAAAA,MAAM,GAAGtG,CAAC,CAAC0B,MAAF,CAAS4E,MAAT,EAAiB2B,OAAO,IAAI;AACnC,WAAOjI,CAAC,CAACiE,QAAF,CAAWqD,eAAX,EAA4BW,OAAO,CAACR,EAApC,CAAP;AACD,GAFQ,CAAT;AAGA,SAAOnB,MAAP;AACD,CAdD;;AAgBA,MAAM4B,WAAW,GAAG,CAAC7B,MAAD,EAAS8B,IAAT,KAAkB;AACpC,MAAInI,CAAC,CAACmH,OAAF,CAAUgB,IAAV,CAAJ,EAAqB;AACnB,WAAO9B,MAAP;AACD;;AACD,SAAOrG,CAAC,CAACoI,MAAF,CAAS/B,MAAT,EAAiBrD,IAAI,IAAI;AAC9B,UAAMS,KAAK,GAAGT,IAAI,CAACwE,WAAL,CAAiB/D,KAAjB,CAAuB,GAAvB,CAAd;AACA,WAAOzD,CAAC,CAACqI,IAAF,CAAO5E,KAAP,EAAc6E,IAAI,IAAI;AAC3B,aAAOA,IAAI,CAAC3E,WAAL,GAAmBa,OAAnB,CAA2B2D,IAAI,CAACxE,WAAL,EAA3B,MAAmD,CAA1D;AACD,KAFM,CAAP;AAGD,GALM,CAAP;AAMD,CAVD;;AAYA,MAAM4E,uBAAuB,GAAGzF,KAAK,IAAI;AACvC,QAAM0F,WAAW,GAAI1F,KAAK,CAACE,IAAN,IAAcF,KAAK,CAACE,IAAN,CAAWyF,SAA1B,IAAwC5F,uBAAuB,CAACC,KAAD,EAAQ,aAAR,EAAuB,IAAvB,CAAnF;AACA,SAAO0F,WAAP;AACD,CAHD;;AAKA,MAAME,uBAAuB,GAAG5F,KAAK,IAAI;AACvC,QAAM0F,WAAW,GAAGD,uBAAuB,CAACzF,KAAD,CAA3C;AACA,SAAO0F,WAAW,GAAGA,WAAW,CAACJ,MAAZ,CAAmBO,GAAG,IAAIA,GAAG,CAACC,SAA9B,CAAH,GAA8C,EAAhE;AACD,CAHD;;AAKA,MAAMC,YAAY,GAAG,MAAM;AACzB,SAAO,CACL;AACEzH,IAAAA,GAAG,EAAE,OADP;AAEE0H,IAAAA,IAAI,EAAEC,OAAO,CAAC,oCAAD;AAFf,GADK,EAKL;AACE3H,IAAAA,GAAG,EAAE,OADP;AAEE0H,IAAAA,IAAI,EAAEC,OAAO,CAAC,oCAAD;AAFf,GALK,EASL;AACE3H,IAAAA,GAAG,EAAE,KADP;AAEE0H,IAAAA,IAAI,EAAEC,OAAO,CAAC,kCAAD;AAFf,GATK,EAaL;AACE3H,IAAAA,GAAG,EAAE,OADP;AAEE0H,IAAAA,IAAI,EAAEC,OAAO,CAAC,oCAAD;AAFf,GAbK,CAAP;AAkBD,CAnBD;;AAqBA,MAAMC,UAAU,GAAG,CAACC,SAAD,EAAYrB,MAAZ,KAAuB;AACxC,SAAO5H,CAAC,CAACqI,IAAF,CAAOY,SAAP,EAAkBlD,CAAC,IAAI;AAC5B,WAAO,CAAC,CAACA,CAAC,CAAC6B,MAAD,CAAV;AACD,GAFM,CAAP;AAGD,CAJD;;AAMA,MAAMsB,QAAQ,GAAG,MAAM;AACrB,SAAO/I,UAAU,CAACgJ,GAAX,CAAe,QAAf,EAAyBlH,KAAzB,GAAiC,GAAxC;AACD,CAFD;;AAIA,MAAMqC,OAAO,GAAGf,GAAG,IAAI;AACrB,MAAIvD,CAAC,CAACmH,OAAF,CAAU5D,GAAV,CAAJ,EAAoB;AAClB,WAAO,KAAP;AACD;;AACD,MAAIA,GAAG,CAACiB,OAAJ,CAAY,oBAAZ,MAAsC,CAA1C,EAA6C;AAC3C,WAAO,IAAP;AACD;;AACD,MAAIjB,GAAG,CAACiB,OAAJ,CAAY,iCAAZ,MAAmD,CAAvD,EAA0D;AACxD,WAAO,IAAP;AACD;AACF,CAVD;;AAYA,MAAM4E,aAAa,GAAG7F,GAAG,IAAI;AAC3B,MAAIvD,CAAC,CAACmH,OAAF,CAAU5D,GAAV,CAAJ,EAAoB;AAClB,WAAO,EAAP;AACD;;AACD,MAAIA,GAAG,CAACiB,OAAJ,CAAY,oBAAZ,MAAsC,CAA1C,EAA6C;AAC3C,UAAM6E,OAAO,GAAG,KAAhB,CAD2C,CACpB;;AACvB,WAAQ,kCAAiCA,OAAQ,EAAjD;AACD;;AACD,SAAO9F,GAAP,CAR2B,CAQf;AACb,CATD;;AAWA,MAAMc,SAAS,GAAGd,GAAG,IAAI;AACvB,MAAIvD,CAAC,CAACkD,WAAF,CAAcK,GAAd,KAAsBvD,CAAC,CAACmH,OAAF,CAAU5D,GAAV,CAA1B,EAA0C;AACxC,WAAO,KAAP;AACD;;AACD,QAAM+F,MAAM,GAAG,sEAAf;AACA,QAAMC,KAAK,GAAGhG,GAAG,CAACgG,KAAJ,CAAUD,MAAV,CAAd;;AACA,MAAIC,KAAK,IAAIA,KAAK,CAAC,CAAD,CAAL,CAAS7F,MAAT,KAAoB,EAAjC,EAAqC;AACnC,WAAO,IAAP;AACD;;AACD,SAAO,KAAP;AACD,CAVD;;AAYA,MAAM8F,eAAe,GAAGjG,GAAG,IAAI;AAC7B,QAAM+F,MAAM,GAAG,sEAAf;AACA,QAAMC,KAAK,GAAGhG,GAAG,CAACgG,KAAJ,CAAUD,MAAV,CAAd;AACA,SAAQ,iCAAgCC,KAAK,CAAC,CAAD,CAAI,aAAjD;AACD,CAJD;;AAMA,MAAMnF,WAAW,GAAG,YAAc;AAAA,MAAbb,GAAa,uEAAP,EAAO;AAChC,MAAIkG,MAAM,GAAGC,kBAAkB,CAACnG,GAAD,CAA/B;AACAkG,EAAAA,MAAM,GAAGA,MAAM,CAACE,IAAP,GAAcjF,OAAd,CAAsB,KAAtB,EAA6B,EAA7B,CAAT;;AAEA,MAAI,WAAWkF,IAAX,CAAgBH,MAAhB,CAAJ,EAA6B;AAC3B,WAAQ,QAAOA,MAAO,EAAtB;AACD;;AACD,MAAI,CAAC,oBAAoBG,IAApB,CAAyBH,MAAzB,CAAL,EAAuC;AACrC,WAAQ,WAAUA,MAAO,EAAzB;AACD;;AAED,SAAOA,MAAP;AACD,CAZD;;AAcA,MAAMI,cAAc,GAAG7G,IAAI,IAAI;AAC7B,SAAO;AACLyE,IAAAA,EAAE,EAAEzE,IAAI,CAAC8G,GADJ;AAELtC,IAAAA,WAAW,EAAExE,IAAI,CAACwE,WAFb;AAGLM,IAAAA,UAAU,EAAE9E,IAAI,CAAC8E,UAAL,IAAmB;AAH1B,GAAP;AAKD,CAND;;AAQA,MAAMiC,aAAa,GAAGC,UAAU,IAAI;AAClC,MAAIA,UAAU,KAAK,KAAnB,EAA0B;AACxB,WAAO,KAAP;AACD;;AACD,MAAIA,UAAU,KAAK,IAAnB,EAAyB;AACvB,WAAO,IAAP;AACD;;AACD,SAAO3J,MAAM,CAACW,GAAP,CAAWiJ,oBAAlB;AACD,CARD;;AAUA,SACEzJ,gBADF,EAEEC,WAFF,EAGEC,MAHF,EAIEa,kBAJF,EAKEM,cALF,EAMEW,eANF,EAOEE,kBAPF,EAQEG,uBARF,EASEM,iBATF,EAUEG,YAVF,EAWEM,WAXF,EAYEG,OAZF,EAaEU,WAbF,EAcEK,OAdF,EAeEC,WAfF,EAgBEC,aAhBF,EAiBEC,WAjBF,EAkBEO,UAlBF,EAmBEE,gBAnBF,EAoBEG,YApBF,EAqBEO,iBArBF,EAsBEI,OAtBF,EAuBEQ,cAvBF,EAwBEE,YAxBF,EAyBEE,mBAzBF,EA0BEc,WA1BF,EA2BEQ,uBA3BF,EA4BEG,YA5BF,EA6BEG,UA7BF,EA8BEE,QA9BF,EA+BE7E,SA/BF,EAgCEmF,eAhCF,EAiCEpF,WAjCF,EAkCEyF,cAlCF,EAmCEE,aAnCF,EAoCE7F,UApCF","sourcesContent":["import _ from 'lodash';\nimport { Platform, StatusBar, Dimensions } from 'react-native';\nimport Constants from 'expo-constants';\nimport Config from './config';\nimport { LINEGREY } from './colours';\nimport { getSessionTokenAWS } from './session';\n\nconst TIMESTAMP_FORMAT = 'D MMM • h:mma';\nconst DATE_FORMAT = 'D MMM YYYY';\n\nconst getUrl = (baseAction, action, query) => {\n const { baseAPIUrl, baseStage } = Config.env;\n let queryPart = '';\n if (query) {\n _.keys(query).forEach((key, index) => {\n queryPart += `${index === 0 ? '?' : '&'}${key}=${encodeURIComponent(query[key])}`;\n });\n }\n return `${baseAPIUrl}/${baseAction}-${baseStage}/${action}${queryPart}`;\n};\n\nconst getAuthTokenHeader = () => {\n return new Promise((resolve, reject) => {\n getSessionTokenAWS().then(idToken => {\n resolve(`Bearer ${idToken}`);\n });\n });\n};\n\nconst getShadowStyle = () => {\n if (Platform.OS === 'ios') {\n return {\n shadowColor: '#000',\n shadowOffset: {\n width: 0,\n height: 1,\n },\n shadowOpacity: 0.1,\n shadowRadius: 3,\n backgroundColor: '#fff',\n };\n }\n return {\n borderColor: LINEGREY,\n backgroundColor: '#fff',\n elevation: 8,\n };\n};\n\nconst StatusBarHeight = size => {\n return getStatusBarHeight() + size;\n};\n\nconst getStatusBarHeight = () => {\n return Platform.OS === 'ios' ? Constants.statusBarHeight : StatusBar.currentHeight;\n};\n\nconst getSiteSettingFromState = (state, key, defaultValue) => {\n if (state && state.user && state.user.siteSettings && !_.isUndefined(state.user.siteSettings[key])) {\n return state.user.siteSettings[key];\n }\n return defaultValue || null;\n};\n\nconst getValueOrDefault = (value, def) => {\n return !_.isUndefined(value) ? value : def;\n};\n\nconst getExtension = url => {\n if (!url) {\n return null;\n }\n const fileSplit = url.split('.');\n return fileSplit[fileSplit.length - 1].toLowerCase();\n};\n\nconst getFileName = (url, noExtension) => {\n if (!url) {\n return null;\n }\n const fileSplit = url.split('/');\n const name = fileSplit[fileSplit.length - 1].toLowerCase();\n if (!noExtension) {\n return name;\n }\n return name.split('.')[0];\n};\n\nconst isVideo = url => {\n const extension = getExtension(url);\n return ['mov', 'mp4'].includes(extension);\n};\n\nconst isVideoUrl = url => {\n const urlToCheck = getValidUrl(url);\n if (isVideo(urlToCheck)) {\n return true;\n }\n if (isYoutube(urlToCheck)) {\n return true;\n }\n if (isVimeo(urlToCheck)) {\n return true;\n }\n return false;\n};\n\nconst isStockImage = url => {\n return url.indexOf('https://pluss60-dev-uploads.s3.ap-southeast-2.amazonaws.com/uploads/library') !== -1;\n};\n\nconst getThumb300 = url => {\n if (!url) {\n return url;\n }\n if (url.indexOf('https://plussprdstorage.blob.core.windows.net/') !== -1) {\n return url.replace('https://plussprdstorage.blob.core.windows.net/', 'https://plusscdn.azureedge.net/');\n }\n if (url.indexOf('https://plusscdn.azureedge.net/') !== -1) {\n return url\n .replace('/uploads/', '/uploads-thumb/')\n .replace('/general/', '/general300/')\n .replace('/uploads1400/', '/uploads-thumb/')\n .replace('/general1400/', '/general300/');\n }\n if (isStockImage(url) || url.indexOf(Config.env.baseUploadsUrl) !== -1) {\n const extension = getExtension(url);\n let urlToUse = url;\n if (extension !== 'jpg') {\n urlToUse = `${url.substring(0, url.length - extension.length)}jpg`;\n }\n return urlToUse.replace('/1400/', '/thumb300/').replace('/uploads/', '/thumb300/');\n }\n return url;\n};\n\nconst get1400 = url => {\n if (!url) {\n return url;\n }\n if (url.indexOf('https://plussprdstorage.blob.core.windows.net/') !== -1) {\n return url.replace('https://plussprdstorage.blob.core.windows.net/', 'https://plusscdn.azureedge.net/');\n }\n if (url.indexOf('https://plusscdn.azureedge.net/') !== -1) {\n return url.replace('/uploads/', '/uploads1400/').replace('/general/', '/general1400/');\n }\n if (isStockImage(url) || url.indexOf(Config.env.baseUploadsUrl) !== -1) {\n const extension = getExtension(url);\n let urlToUse = url;\n if (extension !== 'jpg') {\n urlToUse = `${url.substring(0, url.length - extension.length)}jpg`;\n }\n return urlToUse.replace('/uploads/', '/1400/');\n }\n return url;\n};\n\nconst getMimeType = url => {\n const extension = getExtension(url);\n switch (extension) {\n case 'mov':\n return 'video/quicktime';\n case 'mp4':\n return 'video/mp4';\n default:\n return 'image/jpeg';\n }\n};\n\nconst getCompressed = url => {\n if (!url || typeof url !== 'string') return '';\n return url.replace('/uploads/', '/compressed/');\n};\n\nconst imageExists = url => {\n return new Promise(resolve => {\n fetch(url, { method: 'HEAD', cache: 'no-cache' })\n .then(response => {\n resolve(response.status === 200);\n })\n .catch(() => {\n resolve(false);\n });\n });\n};\n\nconst getPluralS = count => {\n return count === 1 ? '' : 's';\n};\n\nconst getPluralOptions = (count, singular, plural) => {\n if (count === 1) {\n return singular;\n }\n return plural;\n};\n\nconst randomString = (name = '') => {\n return `xxxxxxxx4xxxyxxxxxxxxxxxxx${name}`.replace(/[xy]/g, c => {\n // eslint-disable-next-line\n var r = (Math.random() * 16) | 0,\n v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n};\n\nconst generateImageName = (name, source) => {\n let result = randomString(name);\n if (source) {\n result += `.${_.last(source.split('.'))}`;\n }\n return result;\n};\n\nconst getSite = site => {\n return site === 'plussSpace' || site === 'hq' ? Config.env.preferredSite : site;\n};\n\nconst getTakeoverThumb = uri => {\n const filename = uri.split('/').pop();\n switch (filename) {\n default:\n return { uri };\n }\n};\n\nconst getTakeoverImage = uri => {\n const filename = uri.split('/').pop();\n switch (filename) {\n default:\n return { uri };\n }\n};\n\nconst getImageSource = (uri, isThumb) => {\n if (uri == null) return null;\n if (isThumb) return getTakeoverThumb(uri);\n return getTakeoverImage(uri);\n};\n\nconst getFirstName = name => {\n if (_.isEmpty(name)) {\n return name;\n }\n return name.split(' ')[0];\n};\n\nconst usersToSearchResult = (contacts, excludedUserIds) => {\n let result = [];\n contacts.forEach(user => {\n result.push({\n displayName: user.displayName,\n id: user.objectID || user.id || user.ID || user.userId || user.Id,\n profilePic: user.profilePic || user.photoURL || null,\n unit: user.unit,\n });\n });\n result = _.reject(result, contact => {\n return _.includes(excludedUserIds, contact.id);\n });\n return result;\n};\n\nconst searchUsers = (source, term) => {\n if (_.isEmpty(term)) {\n return source;\n }\n return _.filter(source, user => {\n const split = user.displayName.split(' ');\n return _.some(split, part => {\n return part.toLowerCase().indexOf(term.toLowerCase()) === 0;\n });\n });\n};\n\nconst getTabSettingsFromState = state => {\n const tabSettings = (state.user && state.user.interface) || getSiteSettingFromState(state, 'TabSettings', null);\n return tabSettings;\n};\n\nconst getEnabledTabsFromState = state => {\n const tabSettings = getTabSettingsFromState(state);\n return tabSettings ? tabSettings.filter(tab => tab.isEnabled) : [];\n};\n\nconst getReactions = () => {\n return [\n {\n key: 'heart',\n icon: require('./assets/icons/reactions/heart.png'),\n },\n {\n key: 'smile',\n icon: require('./assets/icons/reactions/smile.png'),\n },\n {\n key: 'sad',\n icon: require('./assets/icons/reactions/sad.png'),\n },\n {\n key: 'party',\n icon: require('./assets/icons/reactions/party.png'),\n },\n ];\n};\n\nconst hasReacted = (reactions, userId) => {\n return _.some(reactions, r => {\n return !!r[userId];\n });\n};\n\nconst isTablet = () => {\n return Dimensions.get('screen').width > 600;\n};\n\nconst isVimeo = url => {\n if (_.isEmpty(url)) {\n return false;\n }\n if (url.indexOf('https://vimeo.com/') === 0) {\n return true;\n }\n if (url.indexOf('https://player.vimeo.com/video/') === 0) {\n return true;\n }\n};\n\nconst getVimeoEmbed = url => {\n if (_.isEmpty(url)) {\n return '';\n }\n if (url.indexOf('https://vimeo.com/') === 0) {\n const vimeoId = 'lol'; //TODO\n return `https://player.vimeo.com/video/${vimeoId}`;\n }\n return url; //TODO\n};\n\nconst isYoutube = url => {\n if (_.isUndefined(url) || _.isEmpty(url)) {\n return false;\n }\n const regExp = /^.*(youtu.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=|\\&v=|\\?v=)([^#\\&\\?]*).*/;\n const match = url.match(regExp);\n if (match && match[2].length === 11) {\n return true;\n }\n return false;\n};\n\nconst getYoutubeEmbed = url => {\n const regExp = /^.*(youtu.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=|\\&v=|\\?v=)([^#\\&\\?]*).*/;\n const match = url.match(regExp);\n return `https://www.youtube.com/embed/${match[2]}?autoplay=0`;\n};\n\nconst getValidUrl = (url = '') => {\n let newUrl = decodeURIComponent(url);\n newUrl = newUrl.trim().replace(/\\s/g, '');\n\n if (/^(:\\/\\/)/.test(newUrl)) {\n return `https${newUrl}`;\n }\n if (!/^(f|ht)tps?:\\/\\//i.test(newUrl)) {\n return `https://${newUrl}`;\n }\n\n return newUrl;\n};\n\nconst getUserPreview = user => {\n return {\n id: user.uid,\n displayName: user.displayName,\n profilePic: user.profilePic || null,\n };\n};\n\nconst allowComments = canComment => {\n if (canComment === false) {\n return false;\n }\n if (canComment === true) {\n return true;\n }\n return Config.env.defaultAllowComments;\n};\n\nexport {\n TIMESTAMP_FORMAT,\n DATE_FORMAT,\n getUrl,\n getAuthTokenHeader,\n getShadowStyle,\n StatusBarHeight,\n getStatusBarHeight,\n getSiteSettingFromState,\n getValueOrDefault,\n getExtension,\n getFileName,\n isVideo,\n getThumb300,\n get1400,\n getMimeType,\n getCompressed,\n imageExists,\n getPluralS,\n getPluralOptions,\n randomString,\n generateImageName,\n getSite,\n getImageSource,\n getFirstName,\n usersToSearchResult,\n searchUsers,\n getEnabledTabsFromState,\n getReactions,\n hasReacted,\n isTablet,\n isYoutube,\n getYoutubeEmbed,\n getValidUrl,\n getUserPreview,\n allowComments,\n isVideoUrl,\n};\n"]}
1
+ {"version":3,"sources":["helper.js"],"names":["_","Platform","StatusBar","Dimensions","Constants","Config","LINEGREY","getSessionTokenAWS","detectFaces","findLandmarkRange","getScaledOffset","TIMESTAMP_FORMAT","DATE_FORMAT","getUrl","baseAction","action","query","baseAPIUrl","baseStage","env","queryPart","keys","forEach","key","index","encodeURIComponent","getAuthTokenHeader","Promise","resolve","reject","then","idToken","getShadowStyle","OS","shadowColor","shadowOffset","width","height","shadowOpacity","shadowRadius","backgroundColor","borderColor","elevation","StatusBarHeight","size","getStatusBarHeight","statusBarHeight","currentHeight","getSiteSettingFromState","state","defaultValue","user","siteSettings","isUndefined","getValueOrDefault","value","def","getExtension","url","fileSplit","split","length","toLowerCase","getFileName","noExtension","name","isVideo","extension","includes","isVideoUrl","urlToCheck","getValidUrl","isYoutube","isVimeo","isStockImage","indexOf","getThumb300","replace","baseUploadsUrl","urlToUse","substring","get1400","get300","getMimeType","getCompressed","imageExists","fetch","method","cache","response","status","catch","getPluralS","count","getPluralOptions","singular","plural","randomString","c","r","Math","random","v","toString","generateImageName","source","result","last","getSite","site","preferredSite","getTakeoverThumb","uri","filename","pop","getTakeoverImage","getImageSource","isThumb","getFirstName","isEmpty","usersToSearchResult","contacts","excludedUserIds","push","displayName","id","objectID","ID","userId","Id","profilePic","photoURL","unit","contact","searchUsers","term","filter","some","part","getTabSettingsFromState","tabSettings","interface","getEnabledTabsFromState","tab","isEnabled","getReactions","icon","require","hasReacted","reactions","isTablet","get","getVimeoEmbed","vimeoId","regExp","match","getYoutubeEmbed","newUrl","decodeURIComponent","trim","test","getUserPreview","uid","allowComments","canComment","defaultAllowComments"],"mappings":"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","sourcesContent":["import _ from 'lodash';\nimport { Platform, StatusBar, Dimensions } from 'react-native';\nimport Constants from 'expo-constants';\nimport Config from './config';\nimport { LINEGREY } from './colours';\nimport { getSessionTokenAWS } from './session';\n\n// seperated files to export\nimport detectFaces from './js/images/detectFaces';\nimport findLandmarkRange from './js/images/findLandmarkRange';\nimport getScaledOffset from './js/images/getScaledOffset';\n\nconst TIMESTAMP_FORMAT = 'D MMM • h:mma';\nconst DATE_FORMAT = 'D MMM YYYY';\n\nconst getUrl = (baseAction, action, query) => {\n const { baseAPIUrl, baseStage } = Config.env;\n let queryPart = '';\n if (query) {\n _.keys(query).forEach((key, index) => {\n queryPart += `${index === 0 ? '?' : '&'}${key}=${encodeURIComponent(query[key])}`;\n });\n }\n return `${baseAPIUrl}/${baseAction}-${baseStage}/${action}${queryPart}`;\n};\n\nconst getAuthTokenHeader = () => {\n return new Promise((resolve, reject) => {\n getSessionTokenAWS().then(idToken => {\n resolve(`Bearer ${idToken}`);\n });\n });\n};\n\nconst getShadowStyle = () => {\n if (Platform.OS === 'ios') {\n return {\n shadowColor: '#000',\n shadowOffset: {\n width: 0,\n height: 1,\n },\n shadowOpacity: 0.1,\n shadowRadius: 3,\n backgroundColor: '#fff',\n };\n }\n return {\n borderColor: LINEGREY,\n backgroundColor: '#fff',\n elevation: 8,\n };\n};\n\nconst StatusBarHeight = size => {\n return getStatusBarHeight() + size;\n};\n\nconst getStatusBarHeight = () => {\n return Platform.OS === 'ios' ? Constants.statusBarHeight : StatusBar.currentHeight;\n};\n\nconst getSiteSettingFromState = (state, key, defaultValue) => {\n if (state && state.user && state.user.siteSettings && !_.isUndefined(state.user.siteSettings[key])) {\n return state.user.siteSettings[key];\n }\n return defaultValue || null;\n};\n\nconst getValueOrDefault = (value, def) => {\n return !_.isUndefined(value) ? value : def;\n};\n\nconst getExtension = url => {\n if (!url) {\n return null;\n }\n const fileSplit = url.split('.');\n return fileSplit[fileSplit.length - 1].toLowerCase();\n};\n\nconst getFileName = (url, noExtension) => {\n if (!url) {\n return null;\n }\n const fileSplit = url.split('/');\n const name = fileSplit[fileSplit.length - 1].toLowerCase();\n if (!noExtension) {\n return name;\n }\n return name.split('.')[0];\n};\n\nconst isVideo = url => {\n const extension = getExtension(url);\n return ['mov', 'mp4'].includes(extension);\n};\n\nconst isVideoUrl = url => {\n const urlToCheck = getValidUrl(url);\n if (isVideo(urlToCheck)) {\n return true;\n }\n if (isYoutube(urlToCheck)) {\n return true;\n }\n if (isVimeo(urlToCheck)) {\n return true;\n }\n return false;\n};\n\nconst isStockImage = url => {\n return url.indexOf('https://pluss60-dev-uploads.s3.ap-southeast-2.amazonaws.com/uploads/library') !== -1;\n};\n\nconst getThumb300 = url => {\n if (!url) {\n return url;\n }\n if (url.indexOf('https://plussprdstorage.blob.core.windows.net/') !== -1) {\n return url.replace('https://plussprdstorage.blob.core.windows.net/', 'https://plusscdn.azureedge.net/');\n }\n if (url.indexOf('https://plusscdn.azureedge.net/') !== -1) {\n return url\n .replace('/uploads/', '/uploads-thumb/')\n .replace('/general/', '/general300/')\n .replace('/uploads1400/', '/uploads-thumb/')\n .replace('/general1400/', '/general300/');\n }\n if (isStockImage(url) || url.indexOf(Config.env.baseUploadsUrl) !== -1) {\n const extension = getExtension(url);\n let urlToUse = url;\n if (extension !== 'jpg') {\n urlToUse = `${url.substring(0, url.length - extension.length)}jpg`;\n }\n return urlToUse.replace('/1400/', '/thumb300/').replace('/uploads/', '/thumb300/');\n }\n return url;\n};\n\nconst get1400 = url => {\n if (!url) {\n return url;\n }\n if (url.indexOf('https://plussprdstorage.blob.core.windows.net/') !== -1) {\n return url.replace('https://plussprdstorage.blob.core.windows.net/', 'https://plusscdn.azureedge.net/');\n }\n if (url.indexOf('https://plusscdn.azureedge.net/') !== -1) {\n return url.replace('/uploads/', '/uploads1400/').replace('/general/', '/general1400/');\n }\n if (isStockImage(url) || url.indexOf(Config.env.baseUploadsUrl) !== -1) {\n const extension = getExtension(url);\n let urlToUse = url;\n if (extension !== 'jpg') {\n urlToUse = `${url.substring(0, url.length - extension.length)}jpg`;\n }\n return urlToUse.replace('/uploads/', '/1400/');\n }\n return url;\n};\n\nconst get300 = url => {\n if (!url) {\n return url;\n }\n if (isStockImage(url) || url.indexOf(Config.env.baseUploadsUrl) !== -1) {\n const extension = getExtension(url);\n let urlToUse = url;\n if (extension !== 'jpg') {\n urlToUse = `${url.substring(0, url.length - extension.length)}jpg`;\n }\n return urlToUse.replace('/uploads/', '/300/').replace('/1400/', '/300/');\n }\n return url;\n};\n\nconst getMimeType = url => {\n const extension = getExtension(url);\n switch (extension) {\n case 'mov':\n return 'video/quicktime';\n case 'mp4':\n return 'video/mp4';\n default:\n return 'image/jpeg';\n }\n};\n\nconst getCompressed = url => {\n if (!url || typeof url !== 'string') return '';\n return url.replace('/uploads/', '/compressed/');\n};\n\nconst imageExists = url => {\n return new Promise(resolve => {\n fetch(url, { method: 'HEAD', cache: 'no-cache' })\n .then(response => {\n resolve(response.status === 200);\n })\n .catch(() => {\n resolve(false);\n });\n });\n};\n\nconst getPluralS = count => {\n return count === 1 ? '' : 's';\n};\n\nconst getPluralOptions = (count, singular, plural) => {\n if (count === 1) {\n return singular;\n }\n return plural;\n};\n\nconst randomString = (name = '') => {\n return `xxxxxxxx4xxxyxxxxxxxxxxxxx${name}`.replace(/[xy]/g, c => {\n // eslint-disable-next-line\n var r = (Math.random() * 16) | 0,\n v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n};\n\nconst generateImageName = (name, source) => {\n let result = randomString(name);\n if (source) {\n result += `.${_.last(source.split('.'))}`;\n }\n return result;\n};\n\nconst getSite = site => {\n return site === 'plussSpace' || site === 'hq' ? Config.env.preferredSite : site;\n};\n\nconst getTakeoverThumb = uri => {\n const filename = uri.split('/').pop();\n switch (filename) {\n default:\n return { uri };\n }\n};\n\nconst getTakeoverImage = uri => {\n const filename = uri.split('/').pop();\n switch (filename) {\n default:\n return { uri };\n }\n};\n\nconst getImageSource = (uri, isThumb) => {\n if (uri == null) return null;\n if (isThumb) return getTakeoverThumb(uri);\n return getTakeoverImage(uri);\n};\n\nconst getFirstName = name => {\n if (_.isEmpty(name)) {\n return name;\n }\n return name.split(' ')[0];\n};\n\nconst usersToSearchResult = (contacts, excludedUserIds) => {\n let result = [];\n contacts.forEach(user => {\n result.push({\n displayName: user.displayName,\n id: user.objectID || user.id || user.ID || user.userId || user.Id,\n profilePic: user.profilePic || user.photoURL || null,\n unit: user.unit,\n });\n });\n result = _.reject(result, contact => {\n return _.includes(excludedUserIds, contact.id);\n });\n return result;\n};\n\nconst searchUsers = (source, term) => {\n if (_.isEmpty(term)) {\n return source;\n }\n return _.filter(source, user => {\n const split = user.displayName.split(' ');\n return _.some(split, part => {\n return part.toLowerCase().indexOf(term.toLowerCase()) === 0;\n });\n });\n};\n\nconst getTabSettingsFromState = state => {\n const tabSettings = (state.user && state.user.interface) || getSiteSettingFromState(state, 'TabSettings', null);\n return tabSettings;\n};\n\nconst getEnabledTabsFromState = state => {\n const tabSettings = getTabSettingsFromState(state);\n return tabSettings ? tabSettings.filter(tab => tab.isEnabled) : [];\n};\n\nconst getReactions = () => {\n return [\n {\n key: 'heart',\n icon: require('./assets/icons/reactions/heart.png'),\n },\n {\n key: 'smile',\n icon: require('./assets/icons/reactions/smile.png'),\n },\n {\n key: 'sad',\n icon: require('./assets/icons/reactions/sad.png'),\n },\n {\n key: 'party',\n icon: require('./assets/icons/reactions/party.png'),\n },\n ];\n};\n\nconst hasReacted = (reactions, userId) => {\n return _.some(reactions, r => {\n return !!r[userId];\n });\n};\n\nconst isTablet = () => {\n return Dimensions.get('screen').width > 600;\n};\n\nconst isVimeo = url => {\n if (_.isEmpty(url)) {\n return false;\n }\n if (url.indexOf('https://vimeo.com/') === 0) {\n return true;\n }\n if (url.indexOf('https://player.vimeo.com/video/') === 0) {\n return true;\n }\n};\n\nconst getVimeoEmbed = url => {\n if (_.isEmpty(url)) {\n return '';\n }\n if (url.indexOf('https://vimeo.com/') === 0) {\n const vimeoId = 'lol'; //TODO\n return `https://player.vimeo.com/video/${vimeoId}`;\n }\n return url; //TODO\n};\n\nconst isYoutube = url => {\n if (_.isUndefined(url) || _.isEmpty(url)) {\n return false;\n }\n const regExp = /^.*(youtu.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=|\\&v=|\\?v=)([^#\\&\\?]*).*/;\n const match = url.match(regExp);\n if (match && match[2].length === 11) {\n return true;\n }\n return false;\n};\n\nconst getYoutubeEmbed = url => {\n const regExp = /^.*(youtu.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=|\\&v=|\\?v=)([^#\\&\\?]*).*/;\n const match = url.match(regExp);\n return `https://www.youtube.com/embed/${match[2]}?autoplay=0`;\n};\n\nconst getValidUrl = (url = '') => {\n let newUrl = decodeURIComponent(url);\n newUrl = newUrl.trim().replace(/\\s/g, '');\n\n if (/^(:\\/\\/)/.test(newUrl)) {\n return `https${newUrl}`;\n }\n if (!/^(f|ht)tps?:\\/\\//i.test(newUrl)) {\n return `https://${newUrl}`;\n }\n\n return newUrl;\n};\n\nconst getUserPreview = user => {\n return {\n id: user.uid,\n displayName: user.displayName,\n profilePic: user.profilePic || null,\n };\n};\n\nconst allowComments = canComment => {\n if (canComment === false) {\n return false;\n }\n if (canComment === true) {\n return true;\n }\n return Config.env.defaultAllowComments;\n};\n\nexport {\n TIMESTAMP_FORMAT,\n DATE_FORMAT,\n getUrl,\n getAuthTokenHeader,\n getShadowStyle,\n StatusBarHeight,\n getStatusBarHeight,\n getSiteSettingFromState,\n getValueOrDefault,\n getExtension,\n getFileName,\n isVideo,\n get300,\n getThumb300,\n get1400,\n getMimeType,\n getCompressed,\n imageExists,\n getPluralS,\n getPluralOptions,\n randomString,\n generateImageName,\n getSite,\n getImageSource,\n getFirstName,\n usersToSearchResult,\n searchUsers,\n getEnabledTabsFromState,\n getReactions,\n hasReacted,\n isTablet,\n isYoutube,\n getYoutubeEmbed,\n getValidUrl,\n getUserPreview,\n allowComments,\n isVideoUrl,\n detectFaces,\n findLandmarkRange,\n getScaledOffset,\n};\n"]}
@@ -0,0 +1,28 @@
1
+ import { stringActions } from '../../apis';
2
+ import moment from 'moment';
3
+ import * as FileSystem from 'expo-file-system';
4
+ import * as FaceDetector from 'expo-face-detector';
5
+
6
+ const detectFaces = async remoteUrl => {
7
+ const parts = remoteUrl.split('/').splice(-2);
8
+ const mediaId = parts[0];
9
+ const extension = parts[1].split('.').splice(-1)[0];
10
+ const downloadPath = `${FileSystem.cacheDirectory}${mediaId}.${extension}`;
11
+ const {
12
+ uri: localUrl
13
+ } = await FileSystem.downloadAsync(remoteUrl, downloadPath);
14
+ const faces = await FaceDetector.detectFacesAsync(localUrl, {
15
+ mode: FaceDetector.FaceDetectorMode.accurate
16
+ });
17
+
18
+ if (faces && faces.image && faces.image.uri) {
19
+ delete faces.image.uri;
20
+ }
21
+
22
+ faces.timestamp = moment().valueOf();
23
+ stringActions.setString('plussSpace', `imagefaces_${encodeURIComponent(remoteUrl)}`, faces);
24
+ return faces;
25
+ };
26
+
27
+ export default detectFaces;
28
+ //# sourceMappingURL=detectFaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["detectFaces.js"],"names":["stringActions","moment","FileSystem","FaceDetector","detectFaces","remoteUrl","parts","split","splice","mediaId","extension","downloadPath","cacheDirectory","uri","localUrl","downloadAsync","faces","detectFacesAsync","mode","FaceDetectorMode","accurate","image","timestamp","valueOf","setString","encodeURIComponent"],"mappings":"AAAA,SAASA,aAAT,QAA8B,YAA9B;AACA,OAAOC,MAAP,MAAmB,QAAnB;AACA,OAAO,KAAKC,UAAZ,MAA4B,kBAA5B;AACA,OAAO,KAAKC,YAAZ,MAA8B,oBAA9B;;AAEA,MAAMC,WAAW,GAAG,MAAMC,SAAN,IAAmB;AACrC,QAAMC,KAAK,GAAGD,SAAS,CAACE,KAAV,CAAgB,GAAhB,EAAqBC,MAArB,CAA4B,CAAC,CAA7B,CAAd;AACA,QAAMC,OAAO,GAAGH,KAAK,CAAC,CAAD,CAArB;AACA,QAAMI,SAAS,GAAGJ,KAAK,CAAC,CAAD,CAAL,CAASC,KAAT,CAAe,GAAf,EAAoBC,MAApB,CAA2B,CAAC,CAA5B,EAA+B,CAA/B,CAAlB;AAEA,QAAMG,YAAY,GAAI,GAAET,UAAU,CAACU,cAAe,GAAEH,OAAQ,IAAGC,SAAU,EAAzE;AAEA,QAAM;AAAEG,IAAAA,GAAG,EAAEC;AAAP,MAAoB,MAAMZ,UAAU,CAACa,aAAX,CAAyBV,SAAzB,EAAoCM,YAApC,CAAhC;AAEA,QAAMK,KAAK,GAAG,MAAMb,YAAY,CAACc,gBAAb,CAA8BH,QAA9B,EAAwC;AAC1DI,IAAAA,IAAI,EAAEf,YAAY,CAACgB,gBAAb,CAA8BC;AADsB,GAAxC,CAApB;;AAIA,MAAIJ,KAAK,IAAIA,KAAK,CAACK,KAAf,IAAwBL,KAAK,CAACK,KAAN,CAAYR,GAAxC,EAA6C;AAC3C,WAAOG,KAAK,CAACK,KAAN,CAAYR,GAAnB;AACD;;AAEDG,EAAAA,KAAK,CAACM,SAAN,GAAkBrB,MAAM,GAAGsB,OAAT,EAAlB;AAEAvB,EAAAA,aAAa,CAACwB,SAAd,CAAwB,YAAxB,EAAuC,cAAaC,kBAAkB,CAACpB,SAAD,CAAY,EAAlF,EAAqFW,KAArF;AAEA,SAAOA,KAAP;AACD,CAtBD;;AAwBA,eAAeZ,WAAf","sourcesContent":["import { stringActions } from '../../apis';\nimport moment from 'moment';\nimport * as FileSystem from 'expo-file-system';\nimport * as FaceDetector from 'expo-face-detector';\n\nconst detectFaces = async remoteUrl => {\n const parts = remoteUrl.split('/').splice(-2);\n const mediaId = parts[0];\n const extension = parts[1].split('.').splice(-1)[0];\n\n const downloadPath = `${FileSystem.cacheDirectory}${mediaId}.${extension}`;\n\n const { uri: localUrl } = await FileSystem.downloadAsync(remoteUrl, downloadPath);\n\n const faces = await FaceDetector.detectFacesAsync(localUrl, {\n mode: FaceDetector.FaceDetectorMode.accurate,\n });\n\n if (faces && faces.image && faces.image.uri) {\n delete faces.image.uri;\n }\n\n faces.timestamp = moment().valueOf();\n\n stringActions.setString('plussSpace', `imagefaces_${encodeURIComponent(remoteUrl)}`, faces);\n\n return faces;\n};\n\nexport default detectFaces;\n"]}
@@ -0,0 +1,109 @@
1
+ import _ from 'lodash';
2
+ import moment from 'moment';
3
+ import { stringActions } from '../../apis';
4
+ import detectFaces from './detectFaces';
5
+ import getScaledOffset from './getScaledOffset';
6
+
7
+ const findLandmarkRange = async (url, options) => {
8
+ let cachedValues;
9
+
10
+ try {
11
+ const response = await stringActions.getString('plussSpace', `imagefaces_${encodeURIComponent(url)}`);
12
+ cachedValues = response.data;
13
+ } catch (e) {
14
+ console.log('errored from cache');
15
+ }
16
+
17
+ if (!cachedValues || !cachedValues.faces || !cachedValues.image || _.isEmpty(cachedValues.faces) && moment().add(-1, 'w').valueOf() > moment(cachedValues.timestamp).valueOf()) {
18
+ cachedValues = await detectFaces(url);
19
+ }
20
+
21
+ const {
22
+ faces,
23
+ image
24
+ } = cachedValues;
25
+ let landmarkStartX = null;
26
+ let landmarkStartY = null;
27
+ let landmarkEndX = null;
28
+ let landmarkEndY = null;
29
+
30
+ if (_.isEmpty(faces)) {
31
+ landmarkStartX = image.width / 2;
32
+ landmarkStartY = image.height / 2;
33
+ landmarkEndX = image.width / 2;
34
+ landmarkEndY = image.height / 2;
35
+ } else {
36
+ faces.forEach(face => {
37
+ const {
38
+ bounds
39
+ } = face;
40
+
41
+ if (!landmarkStartX || bounds.origin.x < landmarkStartX) {
42
+ landmarkStartX = bounds.origin.x;
43
+ }
44
+
45
+ if (!landmarkStartY || bounds.origin.y < landmarkStartY) {
46
+ landmarkStartY = bounds.origin.y;
47
+ }
48
+
49
+ const faceEndX = bounds.origin.x + bounds.size.width;
50
+
51
+ if (!landmarkEndX || faceEndX > landmarkEndX) {
52
+ landmarkEndX = faceEndX;
53
+ }
54
+
55
+ const faceEndY = bounds.origin.y + bounds.size.height;
56
+
57
+ if (!landmarkEndY || faceEndX > landmarkEndY) {
58
+ landmarkEndY = faceEndY;
59
+ }
60
+ });
61
+ }
62
+
63
+ let targetWidth = image.width;
64
+ let targetHeight = image.height;
65
+
66
+ if (options && options.targetWidth && options.targetHeight) {
67
+ const {
68
+ scaleFactor
69
+ } = getScaledOffset(image.width, image.height, options.targetWidth, options.targetHeight);
70
+ landmarkStartX *= scaleFactor;
71
+ landmarkStartY *= scaleFactor;
72
+ landmarkEndX *= scaleFactor;
73
+ landmarkEndY *= scaleFactor;
74
+ targetWidth = options.targetWidth;
75
+ targetHeight = options.targetHeight;
76
+ }
77
+
78
+ if (landmarkStartX < 0) {
79
+ landmarkStartX = 0;
80
+ }
81
+
82
+ if (landmarkStartY < 0) {
83
+ landmarkStartY = 0;
84
+ }
85
+
86
+ if (landmarkEndX > targetWidth) {
87
+ landmarkEndX = targetWidth;
88
+ }
89
+
90
+ if (landmarkEndY > targetHeight) {
91
+ landmarkEndY = targetHeight;
92
+ }
93
+
94
+ return {
95
+ start: {
96
+ x: landmarkStartX,
97
+ y: landmarkStartY
98
+ },
99
+ end: {
100
+ x: landmarkEndX,
101
+ y: landmarkEndY
102
+ },
103
+ height: image.height,
104
+ width: image.width
105
+ };
106
+ };
107
+
108
+ export default findLandmarkRange;
109
+ //# sourceMappingURL=findLandmarkRange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["findLandmarkRange.js"],"names":["_","moment","stringActions","detectFaces","getScaledOffset","findLandmarkRange","url","options","cachedValues","response","getString","encodeURIComponent","data","e","console","log","faces","image","isEmpty","add","valueOf","timestamp","landmarkStartX","landmarkStartY","landmarkEndX","landmarkEndY","width","height","forEach","face","bounds","origin","x","y","faceEndX","size","faceEndY","targetWidth","targetHeight","scaleFactor","start","end"],"mappings":"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","sourcesContent":["import _ from 'lodash';\nimport moment from 'moment';\nimport { stringActions } from '../../apis';\nimport detectFaces from './detectFaces';\nimport getScaledOffset from './getScaledOffset';\n\nconst findLandmarkRange = async (url, options) => {\n let cachedValues;\n try {\n const response = await stringActions.getString('plussSpace', `imagefaces_${encodeURIComponent(url)}`);\n cachedValues = response.data;\n } catch (e) {\n console.log('errored from cache');\n }\n if (\n !cachedValues ||\n !cachedValues.faces ||\n !cachedValues.image ||\n (_.isEmpty(cachedValues.faces) &&\n moment()\n .add(-1, 'w')\n .valueOf() > moment(cachedValues.timestamp).valueOf())\n ) {\n cachedValues = await detectFaces(url);\n }\n const { faces, image } = cachedValues;\n\n let landmarkStartX = null;\n let landmarkStartY = null;\n let landmarkEndX = null;\n let landmarkEndY = null;\n\n if (_.isEmpty(faces)) {\n landmarkStartX = image.width / 2;\n landmarkStartY = image.height / 2;\n landmarkEndX = image.width / 2;\n landmarkEndY = image.height / 2;\n } else {\n faces.forEach(face => {\n const { bounds } = face;\n\n if (!landmarkStartX || bounds.origin.x < landmarkStartX) {\n landmarkStartX = bounds.origin.x;\n }\n\n if (!landmarkStartY || bounds.origin.y < landmarkStartY) {\n landmarkStartY = bounds.origin.y;\n }\n\n const faceEndX = bounds.origin.x + bounds.size.width;\n if (!landmarkEndX || faceEndX > landmarkEndX) {\n landmarkEndX = faceEndX;\n }\n\n const faceEndY = bounds.origin.y + bounds.size.height;\n if (!landmarkEndY || faceEndX > landmarkEndY) {\n landmarkEndY = faceEndY;\n }\n });\n }\n\n let targetWidth = image.width;\n let targetHeight = image.height;\n\n if (options && options.targetWidth && options.targetHeight) {\n const { scaleFactor } = getScaledOffset(image.width, image.height, options.targetWidth, options.targetHeight);\n landmarkStartX *= scaleFactor;\n landmarkStartY *= scaleFactor;\n landmarkEndX *= scaleFactor;\n landmarkEndY *= scaleFactor;\n targetWidth = options.targetWidth;\n targetHeight = options.targetHeight;\n }\n\n if (landmarkStartX < 0) {\n landmarkStartX = 0;\n }\n if (landmarkStartY < 0) {\n landmarkStartY = 0;\n }\n if (landmarkEndX > targetWidth) {\n landmarkEndX = targetWidth;\n }\n if (landmarkEndY > targetHeight) {\n landmarkEndY = targetHeight;\n }\n\n return {\n start: {\n x: landmarkStartX,\n y: landmarkStartY,\n },\n end: {\n x: landmarkEndX,\n y: landmarkEndY,\n },\n height: image.height,\n width: image.width,\n };\n};\n\nexport default findLandmarkRange;\n"]}
@@ -0,0 +1,81 @@
1
+ const getScaledOffset = (sourceWidth, sourceHeight, targetWidth, targetHeight) => {
2
+ const sourceRatio = sourceWidth / sourceHeight;
3
+ const targetRatio = targetWidth / targetHeight; // same ratio. no adjustment needed.
4
+
5
+ if (sourceRatio === targetRatio) {
6
+ return {
7
+ width: targetWidth,
8
+ height: targetHeight,
9
+ scaleFactor: targetWidth / sourceWidth,
10
+ offset: {
11
+ x: 0,
12
+ y: 0
13
+ },
14
+ bounds: {
15
+ start: {
16
+ x: 0,
17
+ y: 0
18
+ },
19
+ end: {
20
+ x: targetWidth,
21
+ y: targetHeight
22
+ }
23
+ }
24
+ };
25
+ } // source is higher than target. height scaling and y offset required.
26
+
27
+
28
+ if (sourceRatio < targetRatio) {
29
+ const scaleFactor = targetWidth / sourceWidth;
30
+ const adjustedHeight = sourceHeight * scaleFactor;
31
+ const yOffset = (adjustedHeight - targetHeight) / 2;
32
+ return {
33
+ width: targetWidth,
34
+ height: adjustedHeight,
35
+ scaleFactor,
36
+ offset: {
37
+ x: 0,
38
+ y: -yOffset
39
+ },
40
+ bounds: {
41
+ start: {
42
+ x: 0,
43
+ y: yOffset
44
+ },
45
+ end: {
46
+ x: targetWidth,
47
+ y: yOffset + adjustedHeight
48
+ }
49
+ }
50
+ };
51
+ } // source is wider than target. width scaling and x offset required.
52
+
53
+
54
+ if (sourceRatio > targetRatio) {
55
+ const scaleFactor = targetHeight / sourceHeight;
56
+ const adjustedWidth = sourceWidth * scaleFactor;
57
+ const xOffset = (adjustedWidth - targetWidth) / 2;
58
+ return {
59
+ width: adjustedWidth,
60
+ height: targetHeight,
61
+ scaleFactor,
62
+ offset: {
63
+ x: -xOffset,
64
+ y: 0
65
+ },
66
+ bounds: {
67
+ start: {
68
+ x: xOffset,
69
+ y: 0
70
+ },
71
+ end: {
72
+ x: xOffset + adjustedWidth,
73
+ y: targetHeight
74
+ }
75
+ }
76
+ };
77
+ }
78
+ };
79
+
80
+ export default getScaledOffset;
81
+ //# sourceMappingURL=getScaledOffset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["getScaledOffset.js"],"names":["getScaledOffset","sourceWidth","sourceHeight","targetWidth","targetHeight","sourceRatio","targetRatio","width","height","scaleFactor","offset","x","y","bounds","start","end","adjustedHeight","yOffset","adjustedWidth","xOffset"],"mappings":"AAAA,MAAMA,eAAe,GAAG,CAACC,WAAD,EAAcC,YAAd,EAA4BC,WAA5B,EAAyCC,YAAzC,KAA0D;AAChF,QAAMC,WAAW,GAAGJ,WAAW,GAAGC,YAAlC;AACA,QAAMI,WAAW,GAAGH,WAAW,GAAGC,YAAlC,CAFgF,CAIhF;;AACA,MAAIC,WAAW,KAAKC,WAApB,EAAiC;AAC/B,WAAO;AACLC,MAAAA,KAAK,EAAEJ,WADF;AAELK,MAAAA,MAAM,EAAEJ,YAFH;AAGLK,MAAAA,WAAW,EAAEN,WAAW,GAAGF,WAHtB;AAILS,MAAAA,MAAM,EAAE;AACNC,QAAAA,CAAC,EAAE,CADG;AAENC,QAAAA,CAAC,EAAE;AAFG,OAJH;AAQLC,MAAAA,MAAM,EAAE;AACNC,QAAAA,KAAK,EAAE;AACLH,UAAAA,CAAC,EAAE,CADE;AAELC,UAAAA,CAAC,EAAE;AAFE,SADD;AAKNG,QAAAA,GAAG,EAAE;AACHJ,UAAAA,CAAC,EAAER,WADA;AAEHS,UAAAA,CAAC,EAAER;AAFA;AALC;AARH,KAAP;AAmBD,GAzB+E,CA2BhF;;;AACA,MAAIC,WAAW,GAAGC,WAAlB,EAA+B;AAC7B,UAAMG,WAAW,GAAGN,WAAW,GAAGF,WAAlC;AACA,UAAMe,cAAc,GAAGd,YAAY,GAAGO,WAAtC;AACA,UAAMQ,OAAO,GAAG,CAACD,cAAc,GAAGZ,YAAlB,IAAkC,CAAlD;AAEA,WAAO;AACLG,MAAAA,KAAK,EAAEJ,WADF;AAELK,MAAAA,MAAM,EAAEQ,cAFH;AAGLP,MAAAA,WAHK;AAILC,MAAAA,MAAM,EAAE;AACNC,QAAAA,CAAC,EAAE,CADG;AAENC,QAAAA,CAAC,EAAE,CAACK;AAFE,OAJH;AAQLJ,MAAAA,MAAM,EAAE;AACNC,QAAAA,KAAK,EAAE;AACLH,UAAAA,CAAC,EAAE,CADE;AAELC,UAAAA,CAAC,EAAEK;AAFE,SADD;AAKNF,QAAAA,GAAG,EAAE;AACHJ,UAAAA,CAAC,EAAER,WADA;AAEHS,UAAAA,CAAC,EAAEK,OAAO,GAAGD;AAFV;AALC;AARH,KAAP;AAmBD,GApD+E,CAsDhF;;;AACA,MAAIX,WAAW,GAAGC,WAAlB,EAA+B;AAC7B,UAAMG,WAAW,GAAGL,YAAY,GAAGF,YAAnC;AACA,UAAMgB,aAAa,GAAGjB,WAAW,GAAGQ,WAApC;AACA,UAAMU,OAAO,GAAG,CAACD,aAAa,GAAGf,WAAjB,IAAgC,CAAhD;AAEA,WAAO;AACLI,MAAAA,KAAK,EAAEW,aADF;AAELV,MAAAA,MAAM,EAAEJ,YAFH;AAGLK,MAAAA,WAHK;AAILC,MAAAA,MAAM,EAAE;AACNC,QAAAA,CAAC,EAAE,CAACQ,OADE;AAENP,QAAAA,CAAC,EAAE;AAFG,OAJH;AAQLC,MAAAA,MAAM,EAAE;AACNC,QAAAA,KAAK,EAAE;AACLH,UAAAA,CAAC,EAAEQ,OADE;AAELP,UAAAA,CAAC,EAAE;AAFE,SADD;AAKNG,QAAAA,GAAG,EAAE;AACHJ,UAAAA,CAAC,EAAEQ,OAAO,GAAGD,aADV;AAEHN,UAAAA,CAAC,EAAER;AAFA;AALC;AARH,KAAP;AAmBD;AACF,CAhFD;;AAkFA,eAAeJ,eAAf","sourcesContent":["const getScaledOffset = (sourceWidth, sourceHeight, targetWidth, targetHeight) => {\n const sourceRatio = sourceWidth / sourceHeight;\n const targetRatio = targetWidth / targetHeight;\n\n // same ratio. no adjustment needed.\n if (sourceRatio === targetRatio) {\n return {\n width: targetWidth,\n height: targetHeight,\n scaleFactor: targetWidth / sourceWidth,\n offset: {\n x: 0,\n y: 0,\n },\n bounds: {\n start: {\n x: 0,\n y: 0,\n },\n end: {\n x: targetWidth,\n y: targetHeight,\n },\n },\n };\n }\n\n // source is higher than target. height scaling and y offset required.\n if (sourceRatio < targetRatio) {\n const scaleFactor = targetWidth / sourceWidth;\n const adjustedHeight = sourceHeight * scaleFactor;\n const yOffset = (adjustedHeight - targetHeight) / 2;\n\n return {\n width: targetWidth,\n height: adjustedHeight,\n scaleFactor,\n offset: {\n x: 0,\n y: -yOffset,\n },\n bounds: {\n start: {\n x: 0,\n y: yOffset,\n },\n end: {\n x: targetWidth,\n y: yOffset + adjustedHeight,\n },\n },\n };\n }\n\n // source is wider than target. width scaling and x offset required.\n if (sourceRatio > targetRatio) {\n const scaleFactor = targetHeight / sourceHeight;\n const adjustedWidth = sourceWidth * scaleFactor;\n const xOffset = (adjustedWidth - targetWidth) / 2;\n\n return {\n width: adjustedWidth,\n height: targetHeight,\n scaleFactor,\n offset: {\n x: -xOffset,\n y: 0,\n },\n bounds: {\n start: {\n x: xOffset,\n y: 0,\n },\n end: {\n x: xOffset + adjustedWidth,\n y: targetHeight,\n },\n },\n };\n }\n};\n\nexport default getScaledOffset;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plusscommunities/pluss-core-app",
3
- "version": "1.6.0",
3
+ "version": "1.6.3-beta.0",
4
4
  "description": "Core extension package for Pluss Communities platform",
5
5
  "main": "dist/module/index.js",
6
6
  "module": "dist/module/index.js",
@@ -30,6 +30,7 @@
30
30
  "expo-av": "~10.2.0",
31
31
  "expo-calendar": "~10.1.0",
32
32
  "expo-constants": "~13.0.0",
33
+ "expo-face-detector": "~11.1.3",
33
34
  "expo-file-system": "~13.1.4",
34
35
  "expo-image-manipulator": "~10.2.0",
35
36
  "expo-image-picker": "~12.0.1",
package/src/apis/index.js CHANGED
@@ -5,6 +5,7 @@ export * from './contactActions';
5
5
  export * from './eventActions';
6
6
  export * from './analyticsActions';
7
7
  export * from './notificationActions';
8
+ export * from './stringActions';
8
9
  export * from './typeActions';
9
10
  export { default as userActions } from './userActions';
10
11
  export { default as profileActions } from './profileActions';
@@ -0,0 +1,28 @@
1
+ import axios from 'axios';
2
+ import { authedFunction } from '../session';
3
+ import { getUrl } from '../helper';
4
+
5
+ export const stringActions = {
6
+ getString: (site, id, useDefault) => {
7
+ const url = getUrl('strings', `get/${site}_${id}`, useDefault ? { useDefault } : undefined);
8
+ return axios({
9
+ method: 'GET',
10
+ url,
11
+ }).catch(error => {
12
+ console.log('getString error', error);
13
+ throw error;
14
+ });
15
+ },
16
+ setString: (site, key, value) => {
17
+ const url = getUrl('strings', 'set');
18
+ return authedFunction({
19
+ method: 'POST',
20
+ url,
21
+ data: {
22
+ site,
23
+ key,
24
+ value,
25
+ },
26
+ });
27
+ },
28
+ };
@@ -0,0 +1,135 @@
1
+ import React, { Component } from 'react';
2
+ import { View, Animated, StyleSheet } from 'react-native';
3
+ import moment from 'moment';
4
+ import { findLandmarkRange, getScaledOffset, get300 } from '../helper';
5
+
6
+ class AutoOffsetImage extends Component {
7
+ constructor(props) {
8
+ super(props);
9
+
10
+ this.paddingFactor = this.props.paddingFactor || 0.1;
11
+
12
+ this.state = {
13
+ imageStyle: {
14
+ width: this.props.width,
15
+ height: this.props.height,
16
+ },
17
+ blurRadius: new Animated.Value(100),
18
+ imageSource: get300(this.props.uri),
19
+ };
20
+ }
21
+
22
+ componentDidMount() {
23
+ this.positionImage();
24
+ }
25
+
26
+ componentDidUpdate(prevProps) {
27
+ if (prevProps.uri !== this.props.uri || prevProps.height !== this.props.height || prevProps.width !== this.props.width) {
28
+ this.positionImage();
29
+ }
30
+ }
31
+
32
+ onLoad = event => {
33
+ if (event.nativeEvent.source.uri === this.props.uri && !this.state.imageLoaded) {
34
+ //unblur
35
+ this.setState({
36
+ imageLoaded: true,
37
+ });
38
+ Animated.sequence([
39
+ Animated.delay(200),
40
+ Animated.timing(this.state.blurRadius, {
41
+ toValue: 0,
42
+ duration: 500,
43
+ useNativeDriver: false,
44
+ }),
45
+ ]).start();
46
+ }
47
+ };
48
+
49
+ positionImage = async () => {
50
+ try {
51
+ const startTime = moment().valueOf();
52
+ const image = await findLandmarkRange(this.props.uri, { targetWidth: this.props.width, targetHeight: this.props.height });
53
+ const scaledOffset = getScaledOffset(image.width, image.height, this.props.width, this.props.height);
54
+
55
+ const { start: landmarkStart, end: landmarkEnd } = image;
56
+ const { bounds: imageBounds, offset, width, height } = scaledOffset;
57
+
58
+ if (landmarkStart.y < imageBounds.start.y) {
59
+ // move up
60
+ offset.y = -Math.max(landmarkStart.y - this.props.height * this.paddingFactor, 0); // move top to 5% above start of landmark
61
+ } else if (landmarkEnd.y > imageBounds.end.y) {
62
+ // move down
63
+ offset.y = -Math.max(landmarkEnd.y + this.props.height * this.paddingFactor - this.props.height, 0); // move bottom to 5% below end of landmark
64
+ }
65
+
66
+ if (landmarkStart.x < imageBounds.start.x) {
67
+ // move right
68
+ offset.x = -Math.max(landmarkStart.x - this.props.width * this.paddingFactor, 0); // move left edge to 5% left of start of landmark
69
+ } else if (landmarkEnd.x > imageBounds.end.x) {
70
+ // move left
71
+ offset.x = -Math.max(landmarkEnd.x + this.props.width * this.paddingFactor - this.props.width, 0); // move right edge to 5% left of end of landmark
72
+ }
73
+
74
+ this.setState({
75
+ imageStyle: {
76
+ width,
77
+ height,
78
+ top: offset.y,
79
+ left: offset.x,
80
+ },
81
+ imageSource: this.props.uri,
82
+ });
83
+
84
+ const endTime = moment().valueOf();
85
+ if (endTime - startTime < 300) {
86
+ Animated.timing(this.state.blurRadius, {
87
+ toValue: 0,
88
+ duration: 0,
89
+ useNativeDriver: false,
90
+ }).start();
91
+ }
92
+ } catch (e) {
93
+ this.setState({
94
+ imageSource: this.props.uri,
95
+ });
96
+ }
97
+ };
98
+
99
+ render() {
100
+ return (
101
+ <View
102
+ style={[
103
+ styles.container,
104
+ {
105
+ width: this.props.width,
106
+ height: this.props.height,
107
+ },
108
+ this.props.style,
109
+ ]}
110
+ >
111
+ <Animated.Image
112
+ blurRadius={this.state.blurRadius}
113
+ source={{ uri: this.state.imageSource }}
114
+ style={[styles.image, this.state.imageStyle]}
115
+ onLoad={this.onLoad}
116
+ />
117
+ {this.props.children}
118
+ </View>
119
+ );
120
+ }
121
+ }
122
+
123
+ const styles = StyleSheet.create({
124
+ container: {
125
+ overflow: 'hidden',
126
+ },
127
+ image: {
128
+ position: 'absolute',
129
+ top: 0,
130
+ left: 0,
131
+ resizeMode: 'cover',
132
+ },
133
+ });
134
+
135
+ export default AutoOffsetImage;
@@ -48,6 +48,7 @@ export { default as ImageUploadProgress } from './ImageUploadProgress';
48
48
  export { default as UserListing } from './UserListing';
49
49
  export { default as PlussChat } from './PlussChat';
50
50
  export { default as PositionedImage } from './PositionedImage';
51
+ export { default as AutoOffsetImage } from './AutoOffsetImage';
51
52
  export { default as FormattedText } from './FormattedText';
52
53
  export { default as MediaPlayer } from './MediaPlayer';
53
54
  export { default as AudienceSelectorPage } from './AudienceSelectorPage';
package/src/helper.js CHANGED
@@ -5,6 +5,11 @@ import Config from './config';
5
5
  import { LINEGREY } from './colours';
6
6
  import { getSessionTokenAWS } from './session';
7
7
 
8
+ // seperated files to export
9
+ import detectFaces from './js/images/detectFaces';
10
+ import findLandmarkRange from './js/images/findLandmarkRange';
11
+ import getScaledOffset from './js/images/getScaledOffset';
12
+
8
13
  const TIMESTAMP_FORMAT = 'D MMM • h:mma';
9
14
  const DATE_FORMAT = 'D MMM YYYY';
10
15
 
@@ -155,6 +160,21 @@ const get1400 = url => {
155
160
  return url;
156
161
  };
157
162
 
163
+ const get300 = url => {
164
+ if (!url) {
165
+ return url;
166
+ }
167
+ if (isStockImage(url) || url.indexOf(Config.env.baseUploadsUrl) !== -1) {
168
+ const extension = getExtension(url);
169
+ let urlToUse = url;
170
+ if (extension !== 'jpg') {
171
+ urlToUse = `${url.substring(0, url.length - extension.length)}jpg`;
172
+ }
173
+ return urlToUse.replace('/uploads/', '/300/').replace('/1400/', '/300/');
174
+ }
175
+ return url;
176
+ };
177
+
158
178
  const getMimeType = url => {
159
179
  const extension = getExtension(url);
160
180
  switch (extension) {
@@ -400,6 +420,7 @@ export {
400
420
  getExtension,
401
421
  getFileName,
402
422
  isVideo,
423
+ get300,
403
424
  getThumb300,
404
425
  get1400,
405
426
  getMimeType,
@@ -424,4 +445,7 @@ export {
424
445
  getUserPreview,
425
446
  allowComments,
426
447
  isVideoUrl,
448
+ detectFaces,
449
+ findLandmarkRange,
450
+ getScaledOffset,
427
451
  };
@@ -0,0 +1,30 @@
1
+ import { stringActions } from '../../apis';
2
+ import moment from 'moment';
3
+ import * as FileSystem from 'expo-file-system';
4
+ import * as FaceDetector from 'expo-face-detector';
5
+
6
+ const detectFaces = async remoteUrl => {
7
+ const parts = remoteUrl.split('/').splice(-2);
8
+ const mediaId = parts[0];
9
+ const extension = parts[1].split('.').splice(-1)[0];
10
+
11
+ const downloadPath = `${FileSystem.cacheDirectory}${mediaId}.${extension}`;
12
+
13
+ const { uri: localUrl } = await FileSystem.downloadAsync(remoteUrl, downloadPath);
14
+
15
+ const faces = await FaceDetector.detectFacesAsync(localUrl, {
16
+ mode: FaceDetector.FaceDetectorMode.accurate,
17
+ });
18
+
19
+ if (faces && faces.image && faces.image.uri) {
20
+ delete faces.image.uri;
21
+ }
22
+
23
+ faces.timestamp = moment().valueOf();
24
+
25
+ stringActions.setString('plussSpace', `imagefaces_${encodeURIComponent(remoteUrl)}`, faces);
26
+
27
+ return faces;
28
+ };
29
+
30
+ export default detectFaces;
@@ -0,0 +1,102 @@
1
+ import _ from 'lodash';
2
+ import moment from 'moment';
3
+ import { stringActions } from '../../apis';
4
+ import detectFaces from './detectFaces';
5
+ import getScaledOffset from './getScaledOffset';
6
+
7
+ const findLandmarkRange = async (url, options) => {
8
+ let cachedValues;
9
+ try {
10
+ const response = await stringActions.getString('plussSpace', `imagefaces_${encodeURIComponent(url)}`);
11
+ cachedValues = response.data;
12
+ } catch (e) {
13
+ console.log('errored from cache');
14
+ }
15
+ if (
16
+ !cachedValues ||
17
+ !cachedValues.faces ||
18
+ !cachedValues.image ||
19
+ (_.isEmpty(cachedValues.faces) &&
20
+ moment()
21
+ .add(-1, 'w')
22
+ .valueOf() > moment(cachedValues.timestamp).valueOf())
23
+ ) {
24
+ cachedValues = await detectFaces(url);
25
+ }
26
+ const { faces, image } = cachedValues;
27
+
28
+ let landmarkStartX = null;
29
+ let landmarkStartY = null;
30
+ let landmarkEndX = null;
31
+ let landmarkEndY = null;
32
+
33
+ if (_.isEmpty(faces)) {
34
+ landmarkStartX = image.width / 2;
35
+ landmarkStartY = image.height / 2;
36
+ landmarkEndX = image.width / 2;
37
+ landmarkEndY = image.height / 2;
38
+ } else {
39
+ faces.forEach(face => {
40
+ const { bounds } = face;
41
+
42
+ if (!landmarkStartX || bounds.origin.x < landmarkStartX) {
43
+ landmarkStartX = bounds.origin.x;
44
+ }
45
+
46
+ if (!landmarkStartY || bounds.origin.y < landmarkStartY) {
47
+ landmarkStartY = bounds.origin.y;
48
+ }
49
+
50
+ const faceEndX = bounds.origin.x + bounds.size.width;
51
+ if (!landmarkEndX || faceEndX > landmarkEndX) {
52
+ landmarkEndX = faceEndX;
53
+ }
54
+
55
+ const faceEndY = bounds.origin.y + bounds.size.height;
56
+ if (!landmarkEndY || faceEndX > landmarkEndY) {
57
+ landmarkEndY = faceEndY;
58
+ }
59
+ });
60
+ }
61
+
62
+ let targetWidth = image.width;
63
+ let targetHeight = image.height;
64
+
65
+ if (options && options.targetWidth && options.targetHeight) {
66
+ const { scaleFactor } = getScaledOffset(image.width, image.height, options.targetWidth, options.targetHeight);
67
+ landmarkStartX *= scaleFactor;
68
+ landmarkStartY *= scaleFactor;
69
+ landmarkEndX *= scaleFactor;
70
+ landmarkEndY *= scaleFactor;
71
+ targetWidth = options.targetWidth;
72
+ targetHeight = options.targetHeight;
73
+ }
74
+
75
+ if (landmarkStartX < 0) {
76
+ landmarkStartX = 0;
77
+ }
78
+ if (landmarkStartY < 0) {
79
+ landmarkStartY = 0;
80
+ }
81
+ if (landmarkEndX > targetWidth) {
82
+ landmarkEndX = targetWidth;
83
+ }
84
+ if (landmarkEndY > targetHeight) {
85
+ landmarkEndY = targetHeight;
86
+ }
87
+
88
+ return {
89
+ start: {
90
+ x: landmarkStartX,
91
+ y: landmarkStartY,
92
+ },
93
+ end: {
94
+ x: landmarkEndX,
95
+ y: landmarkEndY,
96
+ },
97
+ height: image.height,
98
+ width: image.width,
99
+ };
100
+ };
101
+
102
+ export default findLandmarkRange;
@@ -0,0 +1,83 @@
1
+ const getScaledOffset = (sourceWidth, sourceHeight, targetWidth, targetHeight) => {
2
+ const sourceRatio = sourceWidth / sourceHeight;
3
+ const targetRatio = targetWidth / targetHeight;
4
+
5
+ // same ratio. no adjustment needed.
6
+ if (sourceRatio === targetRatio) {
7
+ return {
8
+ width: targetWidth,
9
+ height: targetHeight,
10
+ scaleFactor: targetWidth / sourceWidth,
11
+ offset: {
12
+ x: 0,
13
+ y: 0,
14
+ },
15
+ bounds: {
16
+ start: {
17
+ x: 0,
18
+ y: 0,
19
+ },
20
+ end: {
21
+ x: targetWidth,
22
+ y: targetHeight,
23
+ },
24
+ },
25
+ };
26
+ }
27
+
28
+ // source is higher than target. height scaling and y offset required.
29
+ if (sourceRatio < targetRatio) {
30
+ const scaleFactor = targetWidth / sourceWidth;
31
+ const adjustedHeight = sourceHeight * scaleFactor;
32
+ const yOffset = (adjustedHeight - targetHeight) / 2;
33
+
34
+ return {
35
+ width: targetWidth,
36
+ height: adjustedHeight,
37
+ scaleFactor,
38
+ offset: {
39
+ x: 0,
40
+ y: -yOffset,
41
+ },
42
+ bounds: {
43
+ start: {
44
+ x: 0,
45
+ y: yOffset,
46
+ },
47
+ end: {
48
+ x: targetWidth,
49
+ y: yOffset + adjustedHeight,
50
+ },
51
+ },
52
+ };
53
+ }
54
+
55
+ // source is wider than target. width scaling and x offset required.
56
+ if (sourceRatio > targetRatio) {
57
+ const scaleFactor = targetHeight / sourceHeight;
58
+ const adjustedWidth = sourceWidth * scaleFactor;
59
+ const xOffset = (adjustedWidth - targetWidth) / 2;
60
+
61
+ return {
62
+ width: adjustedWidth,
63
+ height: targetHeight,
64
+ scaleFactor,
65
+ offset: {
66
+ x: -xOffset,
67
+ y: 0,
68
+ },
69
+ bounds: {
70
+ start: {
71
+ x: xOffset,
72
+ y: 0,
73
+ },
74
+ end: {
75
+ x: xOffset + adjustedWidth,
76
+ y: targetHeight,
77
+ },
78
+ },
79
+ };
80
+ }
81
+ };
82
+
83
+ export default getScaledOffset;