Skip to content

Commit

Permalink
Merge pull request #116 from BuildFire/ai-seeder
Browse files Browse the repository at this point in the history
feat: Added AI state seeder to the plugin
  • Loading branch information
mas-iota authored Nov 2, 2023
2 parents 1b869ac + 468e12c commit 9258372
Show file tree
Hide file tree
Showing 8 changed files with 290 additions and 129 deletions.
16 changes: 16 additions & 0 deletions control/content/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,22 @@
});
}
});
// fix google places autocomplete dropdown position
setTimeout(() => {
const target = document.querySelector('.pac-container');
if (target) {
const observer = new MutationObserver(() => {
document.querySelectorAll('.pac-item span, .pac-item')
.forEach((n) => n.classList.add('needsclick'));
const autocompleteBoundaries = document.getElementById('googleMapAutocomplete').getBoundingClientRect();
target.style.top = (autocompleteBoundaries.top + autocompleteBoundaries.height )+ 'px';
});
observer.observe(target, { childList: true, attributes: true,
characterData: true,
});
}
console.log('observer target :', target);
}, 2000);
}
};
})
Expand Down
215 changes: 215 additions & 0 deletions control/content/app.services.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,219 @@
}
}
}])
.factory('DefaultInfo', ['LAYOUTS', function(LAYOUTS) {
return {
content: {
carouselImages: [],
description: '<p>&nbsp;<br></p>',
addressTitle: '',
address: {
type:'',
location:'',
location_coordinates: [],
},
links: [],
showMap: false
},
design: {
listLayout: LAYOUTS.listLayouts[0].name,
backgroundImage: ''
}
}
}])
.factory('AIStateSeeder', ['DefaultInfo', 'DataStore', 'TAG_NAMES', '$rootScope', function(DefaultInfo, DataStore, TAG_NAMES, $rootScope ) {
let stateSeederInstance;
let ContactInfo = DefaultInfo;
const jsonTemplate = {
imagesURLs: [],
description: '',
phoneNumber: '',
email: '',
location: '',
}

const getAddress = function(location) {
return new Promise((resolve) => {
if (location) {
const geocoder = new google.maps.Geocoder();
geocoder.geocode({'address': location}, function(result, status) {
if (status == google.maps.GeocoderStatus.OK) {
resolve(
{
type: 'Location',
location: result[0].formatted_address || location,
location_coordinates: [result[0].geometry.location.lng(), result[0].geometry.location.lat()]
});
} else {
resolve({
type: 'Location',
location: location,
location_coordinates: []
});
};
});
} else {
resolve(null);
};
});
};

const parseImageURL = function(url) {
const optimizedURL = url.replace('1080x720', '100x100');
return new Promise((resolve) => {
if (url.includes("http")){
const xhr = new XMLHttpRequest();
xhr.open("GET", optimizedURL);
xhr.onerror = (error) => {
console.warn('provided URL is not a valid image', error);
resolve('');
}
xhr.onload = () => {
if (xhr.responseURL.includes('source-404') || xhr.status == 404) {
return resolve('');
} else {
return resolve(xhr.responseURL.replace('h=100', 'h=720').replace('w=100', 'w=1080'));
}
};
xhr.send();
} else resolve('');
});
}

const getCurrentUser = function () {
return new Promise((resolve, reject) => {
buildfire.auth.getCurrentUser((err, currentUser) => {
if (err) reject(err);
resolve(currentUser);
});
});
}

const _applyDefaults = function (data) {
// create HTML div element for the description, to avoid breaking the WYSIWYG
const descriptionElement = document.createElement('div');
descriptionElement.innerHTML = data.description || '';
// default address in case there was no address provided
let address = {
type: 'Location',
location: '501 Pacific Hwy, San Diego, CA 92101, USA',
location_coordinates: [-117.17096400000003,32.7100444]
}
if (data.address) {
address = data.address;
}
if (data.imagesURLs && data.imagesURLs.length) {
for (let i = 0; i < data.imagesURLs.length; i++) {
data.imagesURLs[i] = {
action: 'noAction',
iconUrl: data.imagesURLs[i],
title: 'image'
}
}
} else {
data.imagesURLs = [];
}

// add links based on the contact info provided
let links = [];
const emailRegex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/;
if (data.email && data.email.match(emailRegex)) {
links.push({
title: 'Email',
action:'sendEmail',
email: data.email,
subject: 'Contact US',
});
}
if (data.phoneNumber) {
links.push({
title:'Call',
action:'callNumber',
phoneNumber: data.phoneNumber
});
}
return {
showMap: true,
carouselImages: data.imagesURLs,
description : descriptionElement.outerHTML,
addressTitle: 'Navigate to Location',
address: address,
links: links,
}
}

const handleAIReq = function(err, response) {
if (
err ||
!response ||
typeof response !== 'object' ||
!Object.keys(response).length || !response.data
) {
return buildfire.dialog.toast({
message: 'Bad AI request, please try changing your request.',
type: 'danger',
});
}

let optimizedURLs = [];
let promises = response.data.imagesURLs.map(url => {
return parseImageURL(url)
});

Promise.allSettled(promises).then(parsingResults => {
parsingResults.forEach(parsingResult => {
if (parsingResult.status == 'fulfilled' && parsingResult.value) {
optimizedURLs.push(parsingResult.value);
}
})
response.data.imagesURLs = optimizedURLs;
DataStore.get(TAG_NAMES.CONTACT_INFO).then(info => {
if (info && info.data && Object.keys(info.data).length) {
ContactInfo = info.data;
}
getAddress(response.data.location).then(locationResult => {
response.data.address = locationResult;
ContactInfo.content = _applyDefaults(response.data);
DataStore.save(ContactInfo, TAG_NAMES.CONTACT_INFO).then(() => {
stateSeederInstance?.requestResult?.complete();
$rootScope.initContentHome();
}).catch(err => {
stateSeederInstance?.requestResult?.complete();
console.warn('error saving data to datastore', err);
return buildfire.dialog.toast({
message: 'Something went wrong, try again later.',
type: 'danger',
});
});
});
}).catch(err => {
stateSeederInstance?.requestResult?.complete();
console.warn('error getting data from datastore', err);
return buildfire.dialog.toast({
message: 'Something went wrong, try again later.',
type: 'danger',
});
});
});
};

return {
initStateSeeder: function() {
getCurrentUser().then(user => {
stateSeederInstance = new buildfire.components.aiStateSeeder({
generateOptions: {
userMessage: `Generate a contact us information related to [business-type] located in [target-region].\nFor phone number use [+1 555 555-1234].\nFor email use [${user?.email || ''}].`,
maxRecords: 5,
systemMessage:
'images are two 1080x720 images URLs related to location, use source.unsplash.com for images, URL should not have premium_photo or source.unsplash.com/random. return description as HTML',
jsonTemplate: jsonTemplate,
callback: handleAIReq.bind(this),
hintText: 'Replace values between brackets to match your requirements.',
},
}).smartShowEmptyState();
});
return true;
},
}
}])
})(window.angular, window.buildfire);
69 changes: 10 additions & 59 deletions control/content/controllers/content.home.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,61 +3,13 @@
(function (angular) {
angular
.module('contactUsPluginContent')
.controller('ContentHomeCtrl', ['$scope', 'Buildfire', 'LAYOUTS', 'DataStore', 'TAG_NAMES', 'STATUS_CODE', 'ADDRESS_TYPE', 'Utils', '$timeout',
function ($scope, Buildfire, LAYOUTS, DataStore, TAG_NAMES, STATUS_CODE, ADDRESS_TYPE, Utils, $timeout) {
var _data = {
"content": {
"carouselImages": [],
"description": '<p>&nbsp;<br></p>',
"addressTitle": "",
"address": {
type:"",
location:"",
location_coordinates:[]
},
"links": [],
"showMap": false
},
"design": {
"listLayout": LAYOUTS.listLayouts[0].name,
"backgroundImage": ""
}
};

// var initDummyFlag=true;

//init dummy data
var _dummyData= {
content: {
showMap:true,
carouselImages: [{
action: "noAction",
iconUrl: "http://buildfire.imgix.net/1462345835888-04866688400506973/6ac49110-11c7-11e6-92ea-27ed66023d52.jpeg?fit=crop&w=342&h=193",
title: "image"
},
{
action: "noAction",
iconUrl: "http://buildfire.imgix.net/1462345835888-04866688400506973/6bf3c240-11c7-11e6-ad08-375cc71b6ca7.jpg?fit=crop&w=342&h=193",
title: "image"
}],
description : "<p>With the wysiwyg, you can include text and lists, embed images, embed videos, and link to webpages, emails, phone numbers and more. Check out the tutorial on the wysiwyg for detailed information.</p>",
addressTitle:"",
address:{
type:"Location",
location:"501 Pacific Hwy, San Diego, CA 92101, USA",
location_coordinates:[-117.17096400000003,32.7100444]
},
links:[{"title":"Call","action":"callNumber","phoneNumber":"6195551234"},{"title":"Email","action":"sendEmail"}]
},
design:{
listLayout:"Layout_1",
backgroundImage:""
},
default : true
};
.controller('ContentHomeCtrl', ['$scope', 'Buildfire', 'DataStore', 'TAG_NAMES', 'STATUS_CODE', 'ADDRESS_TYPE', 'Utils', '$timeout', 'DefaultInfo', 'AIStateSeeder', '$rootScope',
function ($scope, Buildfire, DataStore, TAG_NAMES, STATUS_CODE, ADDRESS_TYPE, Utils, $timeout, DefaultInfo, AIStateSeeder, $rootScope) {
AIStateSeeder.initStateSeeder();
$rootScope.initContentHome = () => {init()};
var _data = DefaultInfo;
var ContentHome = this;
ContentHome.masterData = _dummyData;
// ContentHome.data = angular.copy(_data);
ContentHome.data = angular.copy(_data);
ContentHome.validCoordinatesFailure = false;

// create a new instance of the buildfire carousel editor
Expand Down Expand Up @@ -103,7 +55,7 @@
$scope.$digest();
};

updateMasterItem(_dummyData);
updateMasterItem(_data);

ContentHome.bodyWYSIWYGOptions = {
plugins: 'advlist autolink link image lists charmap print preview',
Expand All @@ -126,7 +78,6 @@
var init = function () {
var success = function (result) {
if (result && result.id && result.data) {
// initDummyFlag=false;
console.info('init success result:', result);
ContentHome.data = result.data;
if(!ContentHome.data) {
Expand Down Expand Up @@ -155,9 +106,9 @@
updateMasterItem(ContentHome.data);
if (tmrDelay)clearTimeout(tmrDelay);
}else{
//initDummyFlag=true;
ContentHome.data=_dummyData;
// $scope.$digest();

ContentHome.data= _data;

if (ContentHome.data.content) {
if (!ContentHome.data.content.carouselImages)
editor.loadItems([]);
Expand Down
1 change: 1 addition & 0 deletions control/content/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<script src="../../../../scripts/jquery/jquery-ui.min.js"></script>
<script src="../../../../scripts/angular/angular-ui-sortable.js"></script>
<script src="../../../../scripts/buildfire/components/carousel/carousel.js"></script>
<script src="../../../../scripts/buildfire/components/aiStateSeeder/aiStateSeeder.js"></script>
<script src="../../../../scripts/tinymce/tinymce.min.js"></script>
<script src="../../../../scripts/tinymce/ui-tinymce.js"></script>
<script src="../../../../scripts/angular/ui-bootstrap.min.js"></script>
Expand Down
20 changes: 20 additions & 0 deletions control/design/app.services.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,24 @@
}
}
}])
.factory('DefaultInfo', ['LAYOUTS', function(LAYOUTS) {
return {
content: {
carouselImages: [],
description: '<p>&nbsp;<br></p>',
addressTitle: '',
address: {
type:'',
location:'',
location_coordinates: [],
},
links: [],
showMap: false
},
design: {
listLayout: LAYOUTS.listLayouts[0].name,
backgroundImage: ''
}
}
}])
})(window.angular, window.buildfire);
Loading

0 comments on commit 9258372

Please sign in to comment.