@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.
- package/dist/module/apis/index.js +1 -0
- package/dist/module/apis/index.js.map +1 -1
- package/dist/module/apis/stringActions.js +30 -0
- package/dist/module/apis/stringActions.js.map +1 -0
- package/dist/module/components/AutoOffsetImage.js +137 -0
- package/dist/module/components/AutoOffsetImage.js.map +1 -0
- package/dist/module/components/index.js +1 -0
- package/dist/module/components/index.js.map +1 -1
- package/dist/module/helper.js +25 -2
- package/dist/module/helper.js.map +1 -1
- package/dist/module/js/images/detectFaces.js +28 -0
- package/dist/module/js/images/detectFaces.js.map +1 -0
- package/dist/module/js/images/findLandmarkRange.js +109 -0
- package/dist/module/js/images/findLandmarkRange.js.map +1 -0
- package/dist/module/js/images/getScaledOffset.js +81 -0
- package/dist/module/js/images/getScaledOffset.js.map +1 -0
- package/package.json +2 -1
- package/src/apis/index.js +1 -0
- package/src/apis/stringActions.js +28 -0
- package/src/components/AutoOffsetImage.js +135 -0
- package/src/components/index.js +1 -0
- package/src/helper.js +24 -0
- package/src/js/images/detectFaces.js +30 -0
- package/src/js/images/findLandmarkRange.js +102 -0
- package/src/js/images/getScaledOffset.js +83 -0
|
@@ -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,
|
|
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"]}
|
package/dist/module/helper.js
CHANGED
|
@@ -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":"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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\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;
|
package/src/components/index.js
CHANGED
|
@@ -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;
|