kahuna/public/js/util/crop.js (61 lines of code) (raw):
import angular from 'angular';
import { landscape, portrait, video, square, freeform, cropOptions } from './constants/cropOptions';
const CROP_TYPE_STORAGE_KEY = 'cropType';
const CUSTOM_CROP_STORAGE_KEY = 'customCrop';
const CROP_DEFAULT_TYPE_STORAGE_KEY = 'defaultCropType';
const customCrop = (label, xRatio, yRatio) => {
return { key:label, ratio: xRatio / yRatio, ratioString: `${xRatio}:${yRatio}`};
};
export const cropUtil = angular.module('util.crop', ['util.storage']);
cropUtil.constant('landscape', landscape);
cropUtil.constant('portrait', portrait);
cropUtil.constant('video', video);
cropUtil.constant('square', square);
cropUtil.constant('freeform', freeform);
cropUtil.constant('cropOptions', cropOptions);
cropUtil.constant('defaultCrop', cropOptions.find(_ => _.isDefault) || cropOptions[0]);
cropUtil.factory('cropSettings', ['storage', function(storage) {
function getCropOptions() {
const customCrop = storage.getJs(CUSTOM_CROP_STORAGE_KEY, true);
return customCrop ? cropOptions.concat(customCrop) : cropOptions;
}
const isValidCropType = cropType => getCropOptions().some(_ => _.key === cropType);
const isValidRatio = ratio => {
const [label, x, y] = ratio.split(',');
return label && !isNaN(x) && !isNaN(y);
};
const parseRatio = ratio => {
// example ratio 'longcrop,1,5'
if (isValidRatio(ratio)) {
const [label, x, y] = ratio.split(',');
return {
label,
x: parseInt(x, 10),
y: parseInt(y, 10)
};
}
};
const setCropType = (cropType) => {
if (isValidCropType(cropType)) {
storage.setJs(CROP_TYPE_STORAGE_KEY, cropType, true);
} else {
storage.clearJs(CROP_TYPE_STORAGE_KEY);
}
};
const setDefaultCropType = (defaultCropType) => {
if (isValidCropType(defaultCropType)) {
storage.setJs(CROP_DEFAULT_TYPE_STORAGE_KEY, defaultCropType, true);
} else {
storage.clearJs(CROP_DEFAULT_TYPE_STORAGE_KEY);
}
};
const setCustomCrop = customRatio => {
const parsedRatio = parseRatio(customRatio);
if (parsedRatio) {
storage.setJs(CUSTOM_CROP_STORAGE_KEY, customCrop(parsedRatio.label, parsedRatio.x, parsedRatio.y), true);
} else {
storage.clearJs(CUSTOM_CROP_STORAGE_KEY);
}
};
function set({cropType, customRatio, defaultCropType}) {
// set customRatio first in case cropType relies on a custom crop
if (customRatio) {
setCustomCrop(customRatio);
}
if (cropType) {
setCropType(cropType);
}
if (defaultCropType) {
setDefaultCropType(defaultCropType);
}
}
function getCropType() {
const cropType = storage.getJs(CROP_TYPE_STORAGE_KEY, true);
if (isValidCropType(cropType)) {
return cropType;
}
}
function getDefaultCropType() {
const defaultCropType = storage.getJs(CROP_DEFAULT_TYPE_STORAGE_KEY, true);
if (isValidCropType(defaultCropType)) {
return defaultCropType;
}
}
return { set, getCropType, getCropOptions, getDefaultCropType };
}]);
cropUtil.filter('asCropType', function() {
return ratioString => {
const cropSpec = cropOptions.find(_ => _.ratioString === ratioString) || freeform;
return cropSpec.key;
};
});
cropUtil.factory('pollUntilCropCreated', ['$q', 'apiPoll', function($q, apiPoll) {
return function pollUntilCropCreated(image, newCropId) {
return apiPoll(() => image.get().then(maybeUpdatedImage => {
if (maybeUpdatedImage.data.exports.find(crop => crop.id === newCropId) === undefined) {
return $q.reject();
}
}));
};
}]);