muba-posting 5.0.13 → 5.0.15
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/Posting.js +28 -1
- package/Publish1.js +1 -59
- package/Publish2.js +1 -1
- package/Publish2b.js +1 -1
- package/Publish4.js +290 -30
- package/locales/ar.json +9 -2
- package/locales/en.json +9 -2
- package/locales/es.json +9 -2
- package/locales/fr.json +9 -2
- package/locales/it.json +9 -2
- package/locales/nl.json +9 -2
- package/package.json +1 -1
package/Posting.js
CHANGED
|
@@ -20,6 +20,7 @@ import Publish6 from './Publish6';
|
|
|
20
20
|
import Preview from './Preview';
|
|
21
21
|
import PublishProgressBar from './PublishProgressBar.js';
|
|
22
22
|
import EditHead from './EditHead.js';
|
|
23
|
+
import PictureSelector from 'muba-picture';
|
|
23
24
|
import PopupPermissions from 'muba-popup-permissions';
|
|
24
25
|
import PaymentOnlinePopup from 'muba-payment-online';
|
|
25
26
|
import { createIconSetFromFontello } from 'react-native-vector-icons';
|
|
@@ -58,6 +59,7 @@ export default class Posting extends React.Component {
|
|
|
58
59
|
currentScreen: 1,
|
|
59
60
|
fontLoaded: false,
|
|
60
61
|
isLoading: false,
|
|
62
|
+
showImageBrowser: false,
|
|
61
63
|
headerHeight: 0,
|
|
62
64
|
progressBarHeight: 0,
|
|
63
65
|
adId: this.props.adId,
|
|
@@ -90,7 +92,6 @@ export default class Posting extends React.Component {
|
|
|
90
92
|
pax: null,
|
|
91
93
|
minNights: null,
|
|
92
94
|
images: [],
|
|
93
|
-
deletedFiles: [],
|
|
94
95
|
age: null,
|
|
95
96
|
floorType: null,
|
|
96
97
|
floorNumber: null,
|
|
@@ -430,6 +431,20 @@ export default class Posting extends React.Component {
|
|
|
430
431
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
431
432
|
}
|
|
432
433
|
|
|
434
|
+
_openPictureSelector() {
|
|
435
|
+
this.setState({ showImageBrowser: true })
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
imageBrowserCallback = async (photos) => {
|
|
439
|
+
this.setState({
|
|
440
|
+
showImageBrowser: false
|
|
441
|
+
}, () => {
|
|
442
|
+
for (let photo of photos) {
|
|
443
|
+
this.publish4?.loadUri(photo)
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
|
|
433
448
|
getAd = async (id) => {
|
|
434
449
|
const responseJson = await this.props.request(this, AD, {
|
|
435
450
|
adId: id
|
|
@@ -438,6 +453,12 @@ export default class Posting extends React.Component {
|
|
|
438
453
|
return responseJson;
|
|
439
454
|
}
|
|
440
455
|
|
|
456
|
+
_savePicture = async (picture) => {
|
|
457
|
+
this.setState({
|
|
458
|
+
showImageBrowser: false
|
|
459
|
+
}, () => this.publish4?.loadUri(picture));
|
|
460
|
+
}
|
|
461
|
+
|
|
441
462
|
render() {
|
|
442
463
|
return (
|
|
443
464
|
<View style={[commonStyles.flex1, commonStyles.containerBg]}>
|
|
@@ -447,6 +468,10 @@ export default class Posting extends React.Component {
|
|
|
447
468
|
<View onLayout={(event) => this.setState({ headerHeight: event.nativeEvent.layout.height })}>
|
|
448
469
|
{!this.state.showImageBrowser && this.state.view !== Views.PAYMENT_ONLINE ? this.props.topBar : null}
|
|
449
470
|
</View>
|
|
471
|
+
{this.state.showImageBrowser ?
|
|
472
|
+
<PictureSelector max={this.state.maxPictures - this.state.postingAd.images.length} callback={this.imageBrowserCallback} savePicture={this._savePicture} goBack={() => this.goBack(true)} />
|
|
473
|
+
:
|
|
474
|
+
null}
|
|
450
475
|
|
|
451
476
|
<PopupPermissions ref={(element) => this.popupPermissions = element} camera={true} mediaLibrary={true} message={strings('setup.permissionsMessage')} onClose={this.loadData} />
|
|
452
477
|
|
|
@@ -468,6 +493,7 @@ export default class Posting extends React.Component {
|
|
|
468
493
|
|
|
469
494
|
{this.state.view === Views.PUBLISH_1 ?
|
|
470
495
|
<Publish1 postingAd={this.state.postingAd}
|
|
496
|
+
baseUrl={this.props.baseUrl}
|
|
471
497
|
request={this.props.request}
|
|
472
498
|
context={this.props.context}
|
|
473
499
|
showLoading={() => this._showLoading()}
|
|
@@ -548,6 +574,7 @@ export default class Posting extends React.Component {
|
|
|
548
574
|
fullPosting={this.state.fullPosting}
|
|
549
575
|
progressBarHeight={this.state.progressBarHeight}
|
|
550
576
|
headerHeight={this.state.headerHeight}
|
|
577
|
+
openPictureSelector={() => this._openPictureSelector()}
|
|
551
578
|
maxPictures={this.state.maxPictures} />
|
|
552
579
|
:
|
|
553
580
|
null
|
package/Publish1.js
CHANGED
|
@@ -3,12 +3,9 @@ import { Text, View, TouchableHighlight, Dimensions } from 'react-native';
|
|
|
3
3
|
import { strings } from 'muba-i18n';
|
|
4
4
|
import commonStyles from './commonStyles';
|
|
5
5
|
import RadioButtonGroup from 'muba-radio-button-group';
|
|
6
|
-
import InputSelect from 'muba-input-select';
|
|
7
6
|
import { Views } from './utils/Views';
|
|
8
7
|
const window = Dimensions.get('window');
|
|
9
8
|
|
|
10
|
-
const GET_PROMOTIONS = { method: 'GET', url: '/controller/posting/promotions' };
|
|
11
|
-
const PROMOTION_LOCATION = { method: 'GET', url: '/controller/promotions/{promotionId}/location' };
|
|
12
9
|
const GET_TRANSACTIONS = { method: 'GET', url: '/controller/transactions' };
|
|
13
10
|
|
|
14
11
|
export default class Publish1 extends React.Component {
|
|
@@ -21,10 +18,6 @@ export default class Publish1 extends React.Component {
|
|
|
21
18
|
this.state = {
|
|
22
19
|
isLoading: false,
|
|
23
20
|
showTypeBienError: false,
|
|
24
|
-
promotionOptions: {
|
|
25
|
-
elements: [{ section: true, value: null, label: strings('setup.selectPromotion') }],
|
|
26
|
-
selectedItem: this.props.postingAd.promotionId
|
|
27
|
-
},
|
|
28
21
|
transactionOptions: { elements: [], selectedItem: this.props.postingAd.transaction },
|
|
29
22
|
typeBienOptions: { elements: [], selectedItem: this.props.postingAd.adType }
|
|
30
23
|
};
|
|
@@ -54,24 +47,6 @@ export default class Publish1 extends React.Component {
|
|
|
54
47
|
if (this.state.minHeight != minHeight) {
|
|
55
48
|
this.setState({ minHeight: minHeight })
|
|
56
49
|
}
|
|
57
|
-
|
|
58
|
-
this.loadPromotions();
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async loadPromotions() {
|
|
62
|
-
const responseJson = await this.props.request(this.props.context, GET_PROMOTIONS);
|
|
63
|
-
if (responseJson.httpStatus === 200) {
|
|
64
|
-
const promotionOptions = {
|
|
65
|
-
elements: [this.state.promotionOptions.elements[0]],
|
|
66
|
-
selectedItem: this.props.postingAd.promotionId
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
responseJson.list.map((item) => {
|
|
70
|
-
promotionOptions.elements.push(item);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
this.setState({ promotionOptions: promotionOptions });
|
|
74
|
-
}
|
|
75
50
|
}
|
|
76
51
|
|
|
77
52
|
getAdTypes(transaction) {
|
|
@@ -113,23 +88,6 @@ export default class Publish1 extends React.Component {
|
|
|
113
88
|
this.props.postingAd.adType = value;
|
|
114
89
|
}
|
|
115
90
|
|
|
116
|
-
async changePromotion(value) {
|
|
117
|
-
const responseJson = await this.props.request(this.props.context, PROMOTION_LOCATION, {
|
|
118
|
-
promotionId: value
|
|
119
|
-
});
|
|
120
|
-
if (responseJson.httpStatus === 200) {
|
|
121
|
-
this.props.postingAd.latitude = responseJson.latitude;
|
|
122
|
-
this.props.postingAd.longitude = responseJson.longitude;
|
|
123
|
-
this.props.postingAd.region = responseJson.regionId;
|
|
124
|
-
this.props.postingAd.province = responseJson.provinceId;
|
|
125
|
-
this.props.postingAd.city = responseJson.cityId;
|
|
126
|
-
this.props.postingAd.district = responseJson.districtId;
|
|
127
|
-
this.props.postingAd.town = responseJson.townId;
|
|
128
|
-
this.props.postingAd.exactlyLocated = true;
|
|
129
|
-
}
|
|
130
|
-
this.props.postingAd.promotionId = value;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
91
|
async nextStep() {
|
|
134
92
|
if (this.validateForm()) {
|
|
135
93
|
for (var i = 0; i < this.state.typeBienOptions.elements.length; i++) {
|
|
@@ -156,11 +114,7 @@ export default class Publish1 extends React.Component {
|
|
|
156
114
|
}
|
|
157
115
|
|
|
158
116
|
validateForm() {
|
|
159
|
-
|
|
160
|
-
if (!validPromotions) {
|
|
161
|
-
validPromotions = this.inputSelectPromotions.onSubmitValidate();
|
|
162
|
-
}
|
|
163
|
-
return validPromotions && this.radioButtonAdType.onSubmitValidate();
|
|
117
|
+
return this.radioButtonAdType.onSubmitValidate();
|
|
164
118
|
}
|
|
165
119
|
|
|
166
120
|
render() {
|
|
@@ -170,18 +124,6 @@ export default class Publish1 extends React.Component {
|
|
|
170
124
|
<View style={commonStyles.progressbarInputArea}>
|
|
171
125
|
<Text style={commonStyles.progressbarInputAreaH3}>{strings('setup.typeTransaction')}</Text>
|
|
172
126
|
|
|
173
|
-
<InputSelect
|
|
174
|
-
label={strings('setup.selectPromotion')}
|
|
175
|
-
placeholder={strings('setup.select')}
|
|
176
|
-
labelStyle={commonStyles.progressbarField}
|
|
177
|
-
ref={(element) => this.inputSelectPromotions = element}
|
|
178
|
-
visible={this.state.promotionOptions.elements.length > 1}
|
|
179
|
-
required={true}
|
|
180
|
-
scroll={(ref) => this.props.scroll(ref)}
|
|
181
|
-
options={this.state.promotionOptions}
|
|
182
|
-
onChange={(value) => this.changePromotion(value)}
|
|
183
|
-
selectStyle={commonStyles.inputSelect} />
|
|
184
|
-
|
|
185
127
|
<RadioButtonGroup
|
|
186
128
|
style={commonStyles.progressbarFieldContainer}
|
|
187
129
|
required={true}
|
package/Publish2.js
CHANGED
|
@@ -29,7 +29,7 @@ export default class Publish2 extends React.Component {
|
|
|
29
29
|
if (await this.validateLocation()) {
|
|
30
30
|
const responseCheckZone = await this.props.request(this.props.context, GET_CHECK_ZONE, {
|
|
31
31
|
businessId: this.props.postingAd.businessId,
|
|
32
|
-
|
|
32
|
+
cityId: this.props.postingAd.city
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
if (responseCheckZone.value === 'true') {
|
package/Publish2b.js
CHANGED
|
@@ -220,7 +220,7 @@ export default class Publish2b extends React.Component {
|
|
|
220
220
|
if (this.validateForm()) {
|
|
221
221
|
const responseCheckZone = await this.props.request(this.props.context, GET_CHECK_ZONE, {
|
|
222
222
|
businessId: this.props.postingAd.businessId,
|
|
223
|
-
|
|
223
|
+
cityId: this.props.postingAd.city
|
|
224
224
|
});
|
|
225
225
|
|
|
226
226
|
if (responseCheckZone.value === 'true') {
|
package/Publish4.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Text, View, TouchableHighlight, TouchableOpacity, ImageBackground, Dimensions, Image } from 'react-native';
|
|
3
3
|
import PopupAdvice from 'muba-popup-advice';
|
|
4
|
-
import PictureSelector from 'muba-picture';
|
|
5
4
|
import { strings } from 'muba-i18n';
|
|
6
5
|
import commonStyles from './commonStyles';
|
|
7
6
|
import { Views } from './utils/Views';
|
|
@@ -15,11 +14,24 @@ export default class Publish4 extends React.Component {
|
|
|
15
14
|
super(props);
|
|
16
15
|
|
|
17
16
|
this.state = {
|
|
18
|
-
|
|
17
|
+
images: [],
|
|
18
|
+
popupSelectPhotoVisible: false,
|
|
19
|
+
showErrorNoSelectedImages: false,
|
|
20
|
+
allPhotosSelected: false,
|
|
21
|
+
updateMainPhoto: false,
|
|
22
|
+
isLoading: false,
|
|
23
|
+
imageBrowserOpen: false,
|
|
24
|
+
imageSize: [],
|
|
25
|
+
containerWidth: 0,
|
|
26
|
+
containerHeight: 0
|
|
19
27
|
}
|
|
20
28
|
}
|
|
21
29
|
|
|
22
30
|
componentDidMount() {
|
|
31
|
+
for (let photo of this.props.postingAd.images) {
|
|
32
|
+
this.loadImage(photo);
|
|
33
|
+
}
|
|
34
|
+
|
|
23
35
|
const componentsHeight = this.props.headerHeight + this.props.progressBarHeight;
|
|
24
36
|
const minHeight = window.height - componentsHeight;
|
|
25
37
|
if (this.state.minHeight != minHeight) {
|
|
@@ -27,19 +39,227 @@ export default class Publish4 extends React.Component {
|
|
|
27
39
|
}
|
|
28
40
|
}
|
|
29
41
|
|
|
42
|
+
componentDidUpdate = async (prevProps) => {
|
|
43
|
+
if (!this.isSameList(prevProps.postingAd.images, this.props.postingAd.images)) {
|
|
44
|
+
this.setState({ images: [] }, () => {
|
|
45
|
+
for (let photo of this.props.postingAd.images) {
|
|
46
|
+
this.loadImage(photo);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
isSameList = (firstList, secondList) => {
|
|
53
|
+
if (firstList.length != secondList.length) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
for (let index = 0; index < firstList.length; ++index) {
|
|
57
|
+
if (firstList[index].id != secondList[index].id || firstList[index].uri != secondList[index].uri) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async loadUri(photo) {
|
|
65
|
+
if (photo) {
|
|
66
|
+
const photoStr = photo.uri.lastIndexOf('.') > 0 && photo.uri.lastIndexOf('.') > photo.uri.length - 5 ? photo.uri : photo.filename;
|
|
67
|
+
const fileType = photoStr.substring(photoStr.lastIndexOf('.') + 1).toLowerCase();
|
|
68
|
+
|
|
69
|
+
const image = {
|
|
70
|
+
uri: photo.uri,
|
|
71
|
+
name: 'photo_' + this.state.images.length + '.' + fileType,
|
|
72
|
+
type: 'image/' + fileType,
|
|
73
|
+
mainPicture: this.state.images.length === 0,
|
|
74
|
+
referenceType: 'AD',
|
|
75
|
+
referenceId: this.props.postingAd.id,
|
|
76
|
+
extraInfo: this.state.images.length,
|
|
77
|
+
width: photo.width,
|
|
78
|
+
height: photo.height
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
this.loadImage(image);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
loadImage(image) {
|
|
86
|
+
let imagesArray = this.state.images;
|
|
87
|
+
imagesArray.push(image);
|
|
88
|
+
|
|
89
|
+
this.calculateImageSize(image, imagesArray.length - 1)
|
|
90
|
+
|
|
91
|
+
this.setState({
|
|
92
|
+
showErrorNoSelectedImages: false,
|
|
93
|
+
images: imagesArray
|
|
94
|
+
}, () => {
|
|
95
|
+
if (this.state.images.length == this.props.maxPictures) {
|
|
96
|
+
this.setState({ allPhotosSelected: true });
|
|
97
|
+
} else if (this.state.images.length == 1) {
|
|
98
|
+
this.selectMainPhoto(this.state.images[0]);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async imageExists(imageUrl) {
|
|
104
|
+
return fetch(imageUrl).then(response => response.status === 200);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async deleteImage(itemId, index) {
|
|
108
|
+
if (itemId) {
|
|
109
|
+
if (!this.props.postingAd.deletedFiles) {
|
|
110
|
+
this.props.postingAd.deletedFiles = [];
|
|
111
|
+
}
|
|
112
|
+
this.props.postingAd.deletedFiles.push(itemId);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
let imagesArray = [...this.state.images];
|
|
116
|
+
let imageSize = [...this.state.imageSize];
|
|
117
|
+
imagesArray.splice(index, 1)
|
|
118
|
+
imageSize.splice(index, 1)
|
|
119
|
+
|
|
120
|
+
await this.setState({
|
|
121
|
+
allPhotosSelected: false,
|
|
122
|
+
images: imagesArray,
|
|
123
|
+
imageSize: imageSize
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
if (this.state.images.length >= 1) {
|
|
127
|
+
this.selectMainPhoto(this.state.images[0]);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
selectMainPhoto(itemSelected) {
|
|
132
|
+
let imagesArray = this.state.images.slice();
|
|
133
|
+
let imageSize = this.state.imageSize.slice();
|
|
134
|
+
|
|
135
|
+
for (let imageObject of imagesArray) {
|
|
136
|
+
imageObject.mainPicture = false;
|
|
137
|
+
|
|
138
|
+
if (imageObject.uri === itemSelected.uri) {
|
|
139
|
+
imageObject.mainPicture = true;
|
|
140
|
+
const imageIndex = imagesArray.indexOf(imageObject);
|
|
141
|
+
imagesArray.splice(imageIndex, 1);
|
|
142
|
+
imagesArray.splice(0, 0, imageObject);
|
|
143
|
+
|
|
144
|
+
const size = imageSize.splice(imageIndex, 1);
|
|
145
|
+
imageSize.splice(0, 0, ...size);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
let index = 0;
|
|
149
|
+
for (let imageObject of imagesArray) {
|
|
150
|
+
imageObject.name = 'photo_' + index + (imageObject.id ? '_' + imageObject.id : '') + imageObject.name.substring(imageObject.name.indexOf('.'));
|
|
151
|
+
imageObject.extraInfo = index;
|
|
152
|
+
++index;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
this.setState({
|
|
156
|
+
updateMainPhoto: true,
|
|
157
|
+
images: imagesArray,
|
|
158
|
+
imageSize: imageSize
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
30
162
|
nextStep() {
|
|
31
|
-
this.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
this.props.
|
|
163
|
+
if (this.state.images.length == 0) {
|
|
164
|
+
this.setState({ showErrorNoSelectedImages: true });
|
|
165
|
+
} else {
|
|
166
|
+
this.props.postingAd.images = this.state.images;
|
|
167
|
+
this.setState({ showErrorNoSelectedImages: false });
|
|
168
|
+
if (this.props.postingAd.id == null || this.props.fullPosting) {
|
|
169
|
+
if (this.props.postingAd.adTypeDetails.filter(function (detail) {
|
|
170
|
+
return detail.value !== 'surface' && detail.value !== 'baths' && detail.value !== 'pax' && detail.value !== 'minNights' &&
|
|
171
|
+
detail.value !== 'rooms' && detail.value !== 'pieces' && detail.value !== 'pricePeriod'
|
|
172
|
+
}).length > 0) {
|
|
173
|
+
this.props.goToPage(Views.PUBLISH_5);
|
|
174
|
+
} else {
|
|
175
|
+
this.props.goToPage(Views.PUBLISH_6);
|
|
176
|
+
}
|
|
38
177
|
} else {
|
|
39
|
-
this.props.
|
|
178
|
+
this.props.saveEditAd();
|
|
40
179
|
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
rerenderImage(index) {
|
|
184
|
+
const images = this.state.images;
|
|
185
|
+
if (images[index].uri.indexOf('?t=') < 0) {
|
|
186
|
+
images[index].uri = images[index].uri + '?t=' + Date.now();
|
|
41
187
|
} else {
|
|
42
|
-
|
|
188
|
+
images[index].uri = images[index].uri.substring(0, images[index].uri.indexOf('?t=')) + '?t=' + Date.now();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
setTimeout(() => {
|
|
192
|
+
this.setState({
|
|
193
|
+
images: images
|
|
194
|
+
});
|
|
195
|
+
}, 500);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
calculateImageSize = async (image) => {
|
|
199
|
+
if (image.width && image.height) {
|
|
200
|
+
this.setImageSize(image.width, image.height);
|
|
201
|
+
} else if (!image.uri.startsWith('https://') || await this.imageExists(image.uri)) {
|
|
202
|
+
Image.getSize(image.uri, (width, height) => {
|
|
203
|
+
this.setImageSize(width, height);
|
|
204
|
+
});
|
|
205
|
+
} else {
|
|
206
|
+
setTimeout(() => this.calculateImageSize(image), 500);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
setImageSize(width, height) {
|
|
211
|
+
let imageSize = this.state.imageSize;
|
|
212
|
+
if (this.state.containerWidth !== 0 && this.state.containerHeight !== 0) {
|
|
213
|
+
const containerRatio = this.state.containerWidth / this.state.containerHeight;
|
|
214
|
+
const imageRatio = width / height;
|
|
215
|
+
|
|
216
|
+
let finalWidth;
|
|
217
|
+
let finalHeight;
|
|
218
|
+
if (imageRatio > containerRatio) {
|
|
219
|
+
if (width > this.state.containerWidth) {
|
|
220
|
+
finalWidth = this.state.containerWidth;
|
|
221
|
+
} else {
|
|
222
|
+
finalWidth = width;
|
|
223
|
+
}
|
|
224
|
+
finalHeight = height * (finalWidth / width);
|
|
225
|
+
} else if (imageRatio < containerRatio) {
|
|
226
|
+
if (height > this.state.containerHeight) {
|
|
227
|
+
finalHeight = this.state.containerHeight;
|
|
228
|
+
} else {
|
|
229
|
+
finalHeight = height;
|
|
230
|
+
}
|
|
231
|
+
finalWidth = width * (finalHeight / height);
|
|
232
|
+
} else {
|
|
233
|
+
if (width > this.state.containerWidth) {
|
|
234
|
+
finalWidth = this.state.containerWidth;
|
|
235
|
+
finalHeight = this.state.containerHeight;
|
|
236
|
+
} else {
|
|
237
|
+
finalWidth = width;
|
|
238
|
+
finalHeight = height;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
imageSize.push({
|
|
242
|
+
width: finalWidth,
|
|
243
|
+
height: finalHeight,
|
|
244
|
+
marginVertical: (this.state.containerHeight - finalHeight) / 2,
|
|
245
|
+
marginHorizontal: (this.state.containerWidth - finalWidth) / 2
|
|
246
|
+
});
|
|
247
|
+
} else {
|
|
248
|
+
imageSize.push({
|
|
249
|
+
width: '100%',
|
|
250
|
+
height: '100%',
|
|
251
|
+
marginVertical: 0,
|
|
252
|
+
marginHorizontal: 0
|
|
253
|
+
})
|
|
254
|
+
}
|
|
255
|
+
this.setState({
|
|
256
|
+
imageSize: imageSize
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
setContainerWidth = (event) => {
|
|
261
|
+
if (this.state.containerWidth === 0) {
|
|
262
|
+
this.setState({ containerWidth: event.nativeEvent.layout.width, containerHeight: event.nativeEvent.layout.height })
|
|
43
263
|
}
|
|
44
264
|
}
|
|
45
265
|
|
|
@@ -47,24 +267,64 @@ export default class Publish4 extends React.Component {
|
|
|
47
267
|
return (
|
|
48
268
|
<View style={{ minHeight: this.state.minHeight }}>
|
|
49
269
|
<View style={commonStyles.formFieldset}>
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
270
|
+
<View style={commonStyles.progressbarInputArea}>
|
|
271
|
+
<Text style={commonStyles.progressbarInputAreaH3}>{strings('setup.publishPhotos')}</Text>
|
|
272
|
+
{this.state.allPhotosSelected ?
|
|
273
|
+
<View style={commonStyles.confirmNote}>
|
|
274
|
+
<View style={commonStyles.row}>
|
|
275
|
+
<FontAwesomeIcon style={commonStyles.confirmIcon} name="check" />
|
|
276
|
+
<Text style={commonStyles.confirmNoteText}>{strings('setup.allPicturesSelected')}</Text>
|
|
277
|
+
</View>
|
|
278
|
+
</View>
|
|
279
|
+
:
|
|
280
|
+
<View>
|
|
281
|
+
<Text style={this.state.showErrorNoSelectedImages ? [commonStyles.subNote, commonStyles.red] : commonStyles.subNote}>{strings('setup.publishPhotosSubNote1', { maxPictures: this.props.maxPictures })}</Text>
|
|
282
|
+
<Text style={commonStyles.subNote}>{strings('setup.publishPhotosSubNote2')}</Text>
|
|
283
|
+
</View>
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
<View style={commonStyles.progressbarFieldContainer}>
|
|
287
|
+
<View style={{ flexDirection: 'row', flex: 1, flexWrap: 'wrap', alignItems: 'flex-start' }}>
|
|
288
|
+
{this.state.allPhotosSelected ?
|
|
289
|
+
null
|
|
290
|
+
:
|
|
291
|
+
<TouchableOpacity onLayout={this.setContainerWidth} style={[commonStyles.photoBox, this.state.showErrorNoSelectedImages ? commonStyles.fieldError : null]} onPress={() => this.props.openPictureSelector()}>
|
|
292
|
+
<TouchableOpacity style={[commonStyles.photoBoxAddIcon]} onPress={() => this.props.openPictureSelector()}>
|
|
293
|
+
<TouchableHighlight underlayColor="#104a7a" onPress={() => this.props.openPictureSelector()}>
|
|
294
|
+
<FontAwesomeIcon style={commonStyles.photoAddIcon} name="plus-circled" />
|
|
295
|
+
</TouchableHighlight>
|
|
296
|
+
<TouchableOpacity activeOpacity={0.5} onPress={() => this.props.openPictureSelector()}>
|
|
297
|
+
<Text style={commonStyles.photoAddText}>{strings('setup.addPhotos')}</Text>
|
|
298
|
+
</TouchableOpacity>
|
|
299
|
+
</TouchableOpacity>
|
|
300
|
+
</TouchableOpacity>
|
|
301
|
+
}
|
|
302
|
+
{this.state.images.map((item, index) => {
|
|
303
|
+
return (
|
|
304
|
+
<View style={[commonStyles.photoBox]} onLayout={this.setContainerWidth} key={index}>
|
|
305
|
+
<Image style={{ width: this.state.imageSize[index]?.width, height: this.state.imageSize[index]?.height, marginVertical: this.state.imageSize[index]?.marginVertical, marginHorizontal: this.state.imageSize[index]?.marginHorizontal }}
|
|
306
|
+
resizeMode='cover' source={{ uri: item.uri }} borderRadius={10} onError={() => this.rerenderImage(index)} />
|
|
307
|
+
<ImageBackground style={[commonStyles.photoControls, commonStyles.row]} source={require('./assets/images/bg-shadow.png')} resizeMode='stretch' borderRadius={1.5}>
|
|
308
|
+
|
|
309
|
+
<TouchableHighlight style={commonStyles.leftIcon} onPress={() => this.deleteImage(item.id, index)}>
|
|
310
|
+
<FontAwesomeIcon style={commonStyles.whiteIcon} name="cancel-circled" />
|
|
311
|
+
</TouchableHighlight>
|
|
312
|
+
<TouchableHighlight style={commonStyles.rightIcon} onPress={() => this.selectMainPhoto(item)}>
|
|
313
|
+
<FontAwesomeIcon style={[commonStyles.heartIcon, item.mainPicture ? '' : commonStyles.whiteIcon]} name={item.mainPicture ? 'heart' : 'heart-empty'} />
|
|
314
|
+
</TouchableHighlight>
|
|
315
|
+
|
|
316
|
+
</ImageBackground>
|
|
317
|
+
</View>
|
|
318
|
+
)
|
|
319
|
+
})}
|
|
320
|
+
</View>
|
|
321
|
+
<View style={commonStyles.conseilBox}>
|
|
322
|
+
<TouchableOpacity style={commonStyles.alignCenter} activeOpacity={1} onPress={() => this.popupShowAdvice.show()}>
|
|
323
|
+
<FontAwesomeIcon style={commonStyles.conseilIcon} name="help-circled" />
|
|
324
|
+
<Text style={commonStyles.conseilText}>{strings('setup.advice')}</Text>
|
|
325
|
+
</TouchableOpacity>
|
|
326
|
+
</View>
|
|
327
|
+
</View>
|
|
68
328
|
</View>
|
|
69
329
|
</View>
|
|
70
330
|
<View style={commonStyles.buttomButton}>
|
|
@@ -79,7 +339,7 @@ export default class Publish4 extends React.Component {
|
|
|
79
339
|
<Text />
|
|
80
340
|
<Text style={commonStyles.popupText}>{strings('setup.adviceText2')}</Text>
|
|
81
341
|
</PopupAdvice>
|
|
82
|
-
</View
|
|
342
|
+
</View>
|
|
83
343
|
);
|
|
84
344
|
}
|
|
85
345
|
}
|
package/locales/ar.json
CHANGED
|
@@ -30,7 +30,12 @@
|
|
|
30
30
|
"propertyCharacteristics": "خصائص العقار",
|
|
31
31
|
"price": "السعر",
|
|
32
32
|
"currency": "العملة",
|
|
33
|
+
"selectPicture": "حدد الصورة",
|
|
34
|
+
"galleryOrCamera": "هل تريد استخدام الرواق أو الكاميرا؟",
|
|
35
|
+
"addPhotos": "إضافة",
|
|
33
36
|
"publishPhotos": "انشروا صوركم",
|
|
37
|
+
"publishPhotosSubNote1": "الحد الأدنى صورة واحدة. الحد الأقصى {{maxPictures}} صورة.",
|
|
38
|
+
"publishPhotosSubNote2": "انقروا على القلب للقيام بصورة الغلاف",
|
|
34
39
|
"advice": "نصائح",
|
|
35
40
|
"adviceText1": " الحد الأقصى لحجم الصورة 5 ميغابايت ويجب ألا يتجاوز 3456 × 3456 بكسل. يجب تنزيل الصور بحجم .jpg أو .gif أو .png.",
|
|
36
41
|
"adviceText2": "المنشورات التي تتضمن صورة تتلقى ما يصل إلى 3 مرات أكثر من الزيارات. اختر كصورة غلاف تلك التي تمثل أفضل ميزات العقار.",
|
|
@@ -104,14 +109,16 @@
|
|
|
104
109
|
"posting_tip_description_9": "من الأفضل ذكر جميع الخصائص المميزة لهذا العقار ",
|
|
105
110
|
"posting_tip_description_10": "ملاحظة: لا تضع رقم الهاتف أو البريد الإلكتروني في المكان المخصص للوصف، سيتم ربطكم مباشرة مع الزبون ",
|
|
106
111
|
"contactOwner": "اتصل بالناشر",
|
|
112
|
+
"allPicturesSelected": "لقد قمت بتحديد جميع الصور",
|
|
113
|
+
"selected": "المختار(ة)",
|
|
114
|
+
"max": "(كحد أقصى)",
|
|
107
115
|
"orientation": "اتجاه",
|
|
108
116
|
"north": "شمال",
|
|
109
117
|
"south": "جنوب",
|
|
110
118
|
"west": "الغرب",
|
|
111
119
|
"est": "شرق",
|
|
112
120
|
"highlight": "رفع قيمة",
|
|
113
|
-
"ad_cant_post_zone":
|
|
114
|
-
"selectPromotion": "إلى أي ترويج وتخفيض تنتمي الممتلكات الخاصة بك؟*"
|
|
121
|
+
"ad_cant_post_zone":"لا يمكنك النشر في هذه المدينة"
|
|
115
122
|
},
|
|
116
123
|
"product": {
|
|
117
124
|
"LISTING": "قوائم",
|
package/locales/en.json
CHANGED
|
@@ -30,7 +30,12 @@
|
|
|
30
30
|
"propertyCharacteristics": "Characteristics of the property",
|
|
31
31
|
"price": "Price",
|
|
32
32
|
"currency": "Currency",
|
|
33
|
+
"selectPicture": "Select image",
|
|
34
|
+
"galleryOrCamera": "Do you want to use the gallery or the camera?",
|
|
35
|
+
"addPhotos": "Add",
|
|
33
36
|
"publishPhotos": "Publish your photos",
|
|
37
|
+
"publishPhotosSubNote1": "Minimum 1 photo. Maximum {{maxPictures}} photos.",
|
|
38
|
+
"publishPhotosSubNote2": "Click on the heart to make the cover photo.",
|
|
34
39
|
"advice": "Advices",
|
|
35
40
|
"adviceText1": "The size of the image has a maximum of 5 MB and must not exceed 3456 x 3456 pixels. Images must be downloaded in .jpg, .gif or .png format.",
|
|
36
41
|
"adviceText2": "Publications including a photo receive up to 3 times more visits. Choose as a cover photo which best represents the most important features of the property",
|
|
@@ -104,14 +109,16 @@
|
|
|
104
109
|
"posting_tip_description_9": "Highlight the qualities which make this property stand out.",
|
|
105
110
|
"posting_tip_description_10": "Note: Don't include your telephone number or email address in these observations they'll be shown to anyone interested when they send a request for more information.",
|
|
106
111
|
"contactOwner": "Price on request",
|
|
112
|
+
"allPicturesSelected": "You have already selected all the photos",
|
|
113
|
+
"selected": "Selected",
|
|
114
|
+
"max": "(max)",
|
|
107
115
|
"orientation": "Orientation",
|
|
108
116
|
"north": "North",
|
|
109
117
|
"south": "South",
|
|
110
118
|
"west": "West",
|
|
111
119
|
"est": "Est",
|
|
112
120
|
"highlight": "Highlight",
|
|
113
|
-
"ad_cant_post_zone":
|
|
114
|
-
"selectPromotion": "What promotion does your property belong to? *"
|
|
121
|
+
"ad_cant_post_zone":"You can't post in this city"
|
|
115
122
|
},
|
|
116
123
|
"product": {
|
|
117
124
|
"LISTING": "Listing",
|
package/locales/es.json
CHANGED
|
@@ -30,7 +30,12 @@
|
|
|
30
30
|
"propertyCharacteristics": "Características de la propiedad",
|
|
31
31
|
"price": "Precio",
|
|
32
32
|
"currency": "Moneda",
|
|
33
|
+
"selectPicture": "Seleccionar foto",
|
|
34
|
+
"galleryOrCamera": "¿Quieres usar la galería o la cámara?",
|
|
35
|
+
"addPhotos": "Añadir",
|
|
33
36
|
"publishPhotos": "Subir fotos",
|
|
37
|
+
"publishPhotosSubNote1": "Mínimo 1 foto. Máximo {{maxPictures}} fotos.",
|
|
38
|
+
"publishPhotosSubNote2": "Haz click en el corazón para marcar la foto de portada",
|
|
34
39
|
"advice": "Consejos",
|
|
35
40
|
"adviceText1": "El tamaño de la imagen tiene un máximo de 20 MB y no debe exceder los 3456 x 3456 píxeles. Las imágenes deben descargarse en formato .jpg, .gif o .png.",
|
|
36
41
|
"adviceText2": "Las anuncios que incluyan fotos reciben hasta 3 veces más de visitas. Elija como foto de portada la que mejor represente las características más importantes de la propiedad.",
|
|
@@ -104,14 +109,16 @@
|
|
|
104
109
|
"posting_tip_description_9": "Comenta las cualidades que hacen que esta propiedad destaque.",
|
|
105
110
|
"posting_tip_description_10": "Nota: No incluyas tu número de teléfono o dirección de correo electrónico en estas observaciones. Se mostrarán a cualquier persona interesada cuando envíen una solicitud para obtener más información.",
|
|
106
111
|
"contactOwner": "Precio a consultar",
|
|
112
|
+
"allPicturesSelected": "Ya has seleccionado todas las fotos",
|
|
113
|
+
"selected": "Seleccionado",
|
|
114
|
+
"max": "(max)",
|
|
107
115
|
"orientation": "Orientación",
|
|
108
116
|
"north": "Norte",
|
|
109
117
|
"south": "Sur",
|
|
110
118
|
"west": "Oeste",
|
|
111
119
|
"est": "Este",
|
|
112
120
|
"highlight": "Destacar",
|
|
113
|
-
"ad_cant_post_zone":
|
|
114
|
-
"selectPromotion": "¿A qué promoción pertenece tu bien? *"
|
|
121
|
+
"ad_cant_post_zone":"No puedes publicar en esta ciudad"
|
|
115
122
|
},
|
|
116
123
|
"product": {
|
|
117
124
|
"LISTING": "Listing",
|
package/locales/fr.json
CHANGED
|
@@ -30,7 +30,12 @@
|
|
|
30
30
|
"propertyCharacteristics": "Caractéristiques du bien",
|
|
31
31
|
"price": "Prix",
|
|
32
32
|
"currency": "Devise",
|
|
33
|
+
"selectPicture": "Sélectionnez l'image",
|
|
34
|
+
"galleryOrCamera": "Voulez-vous utiliser la galerie ou la caméra?",
|
|
35
|
+
"addPhotos": "Ajouter",
|
|
33
36
|
"publishPhotos": "Publiez vos photos",
|
|
37
|
+
"publishPhotosSubNote1": "Minimum 1 photo. Maximum {{maxPictures}} photos.",
|
|
38
|
+
"publishPhotosSubNote2": "Cliquez sur Favoris pour sélectionner la photo de couverture.",
|
|
34
39
|
"advice": "Conseils",
|
|
35
40
|
"adviceText1": "La taille de l'image a un maximum de 5 Mo et ne doit pas dépasser 3456 x 3456 pixels. Les images doivent être téléchargées au format .jpg, .gif ou .png.",
|
|
36
41
|
"adviceText2": "Les publications incluant une photo reçoivent jusqu'à 3 fois plus de visites. Choisissez comme photo de couverture celle qui représente le mieux les caractéristiques les plus importantes du bien",
|
|
@@ -104,14 +109,16 @@
|
|
|
104
109
|
"posting_tip_description_9": "Renforcez les caractéristiques uniques de ce bien.",
|
|
105
110
|
"posting_tip_description_10": "Remarque: Ne mettez pas votre numéro de téléphone ou votre adresse email dans les commentaires, notre équipe se chargera de vous envoyer automatiquement toutes les demandes d'informations.",
|
|
106
111
|
"contactOwner": "Prix à consulter",
|
|
112
|
+
"allPicturesSelected": "Vous avez déjà sélectionné toutes les photos",
|
|
113
|
+
"selected": "Sélectionné(s)",
|
|
114
|
+
"max": "(max)",
|
|
107
115
|
"orientation": "Orientation",
|
|
108
116
|
"north": "Nord",
|
|
109
117
|
"south": "South",
|
|
110
118
|
"west": "Ouest",
|
|
111
119
|
"est": "Est",
|
|
112
120
|
"highlight": "Mettre en valeur",
|
|
113
|
-
"ad_cant_post_zone":
|
|
114
|
-
"selectPromotion": "A quelle promotion appartient votre bien? *"
|
|
121
|
+
"ad_cant_post_zone":"Vous ne pouvez pas poster dans cette ville"
|
|
115
122
|
},
|
|
116
123
|
"product": {
|
|
117
124
|
"LISTING": "Liste",
|
package/locales/it.json
CHANGED
|
@@ -30,7 +30,12 @@
|
|
|
30
30
|
"propertyCharacteristics": "Caratteristiche principali dell’immobile",
|
|
31
31
|
"price": "Prezzo",
|
|
32
32
|
"currency": "Valuta",
|
|
33
|
+
"selectPicture": "Seleziona immagine",
|
|
34
|
+
"galleryOrCamera": "Vuoi usare la galleria o la fotocamera?",
|
|
35
|
+
"addPhotos": "Aggiungi",
|
|
33
36
|
"publishPhotos": "Pubblica le tue foto",
|
|
37
|
+
"publishPhotosSubNote1": "Minimo 1 foto. Massimo {{maxPictures}} foto.",
|
|
38
|
+
"publishPhotosSubNote2": "Clicca sul cuore per creare l’immagine di copertina.",
|
|
34
39
|
"advice": "Consigli",
|
|
35
40
|
"adviceText1": "La dimensione massima dell’immagine è di 20 MB e non può superare i 3456 x 3456 pixel. Le immagini devono essere scaricate in .jpg, .gif o .png.",
|
|
36
41
|
"adviceText2": "Le pubblicazioni con foto ricevono fino a 3 volte più visualizzazioni. Scegli l’immagine di copertina che meglio rappresenta la caratteristica principale dell’immobile",
|
|
@@ -104,14 +109,16 @@
|
|
|
104
109
|
"posting_tip_description_9": "Risalta le qualità principali dell’immobile.",
|
|
105
110
|
"posting_tip_description_10": "Nota: Non includere il tuo numero di telefono o indirizzo e-mail in queste osservazioni. Verranno mostrate agli interessati quando invieranno la richiesta.",
|
|
106
111
|
"contactOwner": "Prezzo su richiesta",
|
|
112
|
+
"allPicturesSelected": "Hai già selezionato tutte le foto",
|
|
113
|
+
"selected": "Selezionato",
|
|
114
|
+
"max": "(max)",
|
|
107
115
|
"orientation": "Orientamento",
|
|
108
116
|
"north": "Nord",
|
|
109
117
|
"south": "Sud",
|
|
110
118
|
"west": "Ovest",
|
|
111
119
|
"est": "Est",
|
|
112
120
|
"highlight": "Evidenziare",
|
|
113
|
-
"ad_cant_post_zone":
|
|
114
|
-
"selectPromotion": "A quale promozione appartiene il tuo immobile? *"
|
|
121
|
+
"ad_cant_post_zone":"Non puoi postare in questa città"
|
|
115
122
|
},
|
|
116
123
|
"product": {
|
|
117
124
|
"LISTING": "Inserzioni",
|
package/locales/nl.json
CHANGED
|
@@ -30,7 +30,12 @@
|
|
|
30
30
|
"propertyCharacteristics": "De belangrijkste kenmerken van het pand",
|
|
31
31
|
"price": "Prijs",
|
|
32
32
|
"currency": "Valuta",
|
|
33
|
+
"selectPicture": "Afbeelding selecteren",
|
|
34
|
+
"galleryOrCamera": "Wilt u de galerij of de camera gebruiken?",
|
|
35
|
+
"addPhotos": "Toevoegen",
|
|
33
36
|
"publishPhotos": "Publiceer uw foto's",
|
|
37
|
+
"publishPhotosSubNote1": "Minimaa 1 foto. Maximaal {{maxPictures}} foto's.",
|
|
38
|
+
"publishPhotosSubNote2": "Klik op het hartje om hier uw omslagfoto van te maken.",
|
|
34
39
|
"advice": "Adviezen",
|
|
35
40
|
"adviceText1": "De afbeelding mag maximaal 20 MG zijn en mag niet meer dan 3456 x 3456 pixels zijn. Afbeeldingen moeten worden gedownload als .jpg, .gif of .png.",
|
|
36
41
|
"adviceText2": "Publicaties met een foto worden drie keer zo vaak bezocht. Kies een omslagfoto die de belangrijkste kenmerken van het pand het beste benadrukken",
|
|
@@ -104,14 +109,16 @@
|
|
|
104
109
|
"posting_tip_description_9": "Benadruk de kenmerken waardoor dit pand opvalt.",
|
|
105
110
|
"posting_tip_description_10": "Opmerking: vermeld hier niet uw telefoonnummer of e-mailadres. Die worden getoond aan mensen die interesse hebben wanneer ze om meer informatie vragen.",
|
|
106
111
|
"contactOwner": "Prijs op aanvraag",
|
|
112
|
+
"allPicturesSelected": "U hebt alle foto's al geselecteerd",
|
|
113
|
+
"selected": "Geselecteerd",
|
|
114
|
+
"max": "(max)",
|
|
107
115
|
"orientation": "Oriëntatie",
|
|
108
116
|
"north": "North",
|
|
109
117
|
"south": "Zuid",
|
|
110
118
|
"west": "Oost",
|
|
111
119
|
"est": "North",
|
|
112
120
|
"highlight": "Highlighting",
|
|
113
|
-
"ad_cant_post_zone":
|
|
114
|
-
"selectPromotion": "Bij welke promotie hoort uw accommodatie? *"
|
|
121
|
+
"ad_cant_post_zone":"In deze stad mag je niet posten"
|
|
115
122
|
},
|
|
116
123
|
"product": {
|
|
117
124
|
"LISTING": "Advertenties",
|