UNPKG

io3fix

Version:

toolkit for interior apps

188 lines (169 loc) 5.21 kB
import getFurnitureInfo from '../furniture/get-info.js' import callService from '../utils/services/call.js' import normalizeFurnitureInfo from '../furniture/common/normalize-furniture-info.js' var config = { default_margin: 0.05, default_search: 'isPublished:true -generic', tag_black_list: [ 'simplygon', 'hasChangeableMaterials', 'autofurnish', 'wallAttached', '2 seater', '3 seater', '4 seater' ], tag_white_list: [ 'shelf', 'armchair', 'sofa', 'chair', 'plant', 'sideboard', 'coffee table', 'dining table', 'bed', 'round', 'tv', 'washing machine', 'lamps', 'free standing lamp', 'living', //'dining', 'relaxing', 'picture', 'bathroom', 'storage', 'tables', 'seating', 'L shaped left', 'L shaped right' ], edgeAligned: [ 'sofa', 'shelf', 'armchair', 'sideboad', 'double bed', 'single bed', 'bed' ] } export default function getAlternatives(id, options) { // API options = options || {} var userQuery = options.query !== undefined ? options.query : null var params = { userQuery: userQuery, searchCount: 0, margin: config['default_margin'] } return getFurnitureInfo(id) .then(function(info) { params.info = info // check for tables to ( they should change in size too much ) var isTable = params.info.categories.indexOf('tables') > -1 // set max search Count ( each one is increasing size margin ) params.maxSearchCount = isTable ? 4 : 8 return search(getQuery(params)) }) .then(function(result) { return verifyResult(result, id, params) }) .catch(function(error) { console.error(error) }) } function verifyResult(result, id, params) { var info = params.info if (params.searchCount > 10) { return Promise.reject('No furniture was found') } var rawResult = result.filter(function(el) { return el.productResourceId !== id }) // if we didn't find enough in the first place // let's increase dimensions a bit var continueSearching = rawResult.length < 8 && params.searchCount < params.maxSearchCount if (continueSearching) { if (params.searchCount >= 1) params.margin += 0.05 var searchQuery = getQuery(params) params.searchCount += 1 return search(searchQuery) .then(function(result) { return verifyResult(result, id, params) }) .catch(function(error) { return Promise.reject('No alternatives were found') }) } else if (rawResult.length) { var cleanResult = rawResult.map(normalizeFurnitureInfo).map(function(res) { return { furniture: res, offset: getOffset(info, res) } }) return Promise.resolve(cleanResult) } else Promise.reject('No alternatives were found') } function getQuery(params) { var info = params.info var queries = [config['default_search']] var tags = info.tags.concat(info.categories) tags = tags.filter(function(tag) { // removes blacklisted tags as well as 1P, 2P, ... config['tag_black_list'] = config['tag_black_list'].map(tag => tag.toLowerCase()) return config['tag_black_list'].indexOf(tag.toLowerCase()) < 0 && !/^\d+P$/.test(tag) }) // remove secondary tags after the second search if (params.searchCount > 2) { tags = tags.filter(function(tag) { config['tag_white_list'] = config['tag_white_list'].map(tag => tag.toLowerCase()) return config['tag_white_list'].indexOf(tag.toLowerCase()) > -1 }) } queries = queries.concat(tags) if (params.userQuery && tags.indexOf('tv') < 0) queries = queries.concat(params.userQuery) var searchQuery = { query: queries.join(' ') } // add dimension search params if source provides dimensions var dim = info.boundingBox if (dim) { ['length', 'height', 'width'].forEach(function(d) { if (dim[d] - params.margin > 0) { searchQuery[d + 'Min'] = Math.round((dim[d] - params.margin) * 1e2) / 1e2 searchQuery[d + 'Max'] = Math.round((dim[d] + params.margin) * 1e2) / 1e2 } }) } return searchQuery } function search(searchQuery) { // let's make sure we don't have trailing or double spaces searchQuery.query = searchQuery.query.trim().replace(/\s+/g, ' ') return callService('Product.search', { searchQuery: searchQuery, limit: 200 }) } // get offset based on bounding boxes function getOffset(a, b) { // for elements that are aligned at the wall we want to compute the offset accordingly var edgeAligned = config.edgeAligned var tags = a.tags a = a.boundingPoints b = b.boundingPoints if (!a || !b) return { x: 0, y: 0, z: 0 } // check if the furniture's virtual origin should be center or edge var isEdgeAligned = edgeAligned.some(function(t) { return tags.includes(t) }) var zOffset // compute offset between edges or centers if (isEdgeAligned) zOffset = a.min[2] - b.min[2] else zOffset = (a.max[2] + a.min[2]) / 2 - (b.max[2] + b.min[2]) / 2 var offset = { // compute offset between centers x: (a.max[0] + a.min[0]) / 2 - (b.max[0] + b.min[0]) / 2, y: 0, z: zOffset } return offset }