Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions interface.html
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ <h4 class="panel-title collapsed" role="button" data-toggle="collapse" data-pare
</div>
<div class="fl-bundleId-field">
<div class="col-sm-8">
<input type="text" name="fl-store-bundleId" class="form-control" id="fl-store-bundleId" pattern="^(?=.*[\.])[0-9a-zA-Z.-]{1,}$" data-error="Please make sure the bundle ID contains at least one period (.) and contains only alphanumeric characters (A–Z, a–z, and 0–9), hyphens (-), and periods (.)" data-required-error="Please enter the Bundle ID" maxlength="155" required />
<input type="text" name="fl-store-bundleId" class="form-control" id="fl-store-bundleId" pattern="^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*){1,}$" data-pattern-error="Please make sure the bundle ID contains at least two segments separated by dots, each starting with a letter, containing only lowercase letters [a–z], numbers [0–9], and underscores (_). " data-required-error="Please enter the Bundle ID" maxlength="155" required />
<div class="help-block with-errors"></div>
<p class="help-block"><small>This value needs to be unique and the structure must be <code>com.<i>organizationName</i>.<i>appName</i></code>.</small></p>
</div>
Expand Down Expand Up @@ -335,7 +335,7 @@ <h4 class="panel-title collapsed" role="button" data-toggle="collapse" data-pare
</div>
<div class="fl-bundleId-field">
<div class="col-sm-8">
<input type="text" name="fl-ent-bundleId" class="form-control" id="fl-ent-bundleId" pattern="^(?=.*[\.])[0-9a-zA-Z.-]{1,}$" data-error="Please make sure the bundle ID contains at least one period (.) and contains only alphanumeric characters (A–Z, a–z, and 0–9), hyphens (-), and periods (.)" data-required-error="Please enter the Bundle ID" maxlength="155" required />
<input type="text" name="fl-ent-bundleId" class="form-control" id="fl-ent-bundleId" pattern="^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$" data-pattern-error="Please make sure the bundle ID has at least two segments separated by dots, each starting with a letter, containing only lowercase letters [a–z], numbers [0–9], and underscores (_)." data-required-error="Please enter the Bundle ID" maxlength="155" required />
<div class="help-block with-errors"></div>
<p class="help-block"><small>This value needs to be unique and the structure must be <code>com.<i>organizationName</i>.<i>appName</i></code>.</small></p>
</div>
Expand Down Expand Up @@ -365,7 +365,7 @@ <h4>Push notifications</h4>
<div class="col-xs-5 save-btn-holder col-xs-offset-2 text-right">
{{#if appFeatures.appStores.google.private }}
<p class="help-block"><small>Submit your information when you are ready!<br>We will take care of the rest.</small></p>
<button type="submit" class="btn btn-primary fl-green button-enterprise-request" data-enterprise-build>Request App <i class="fa fa-paper-plane"></i></button>
<button type="submit" class="btn btn-primary fl-green button-enterprise-request" data-enterprise-build>Request App<i class="fa fa-paper-plane"></i></button>
{{else}}
<p class="help-block"><small>Upgrade to an app plan to request your app to be published.</small></p>
<button type="submit" class="btn btn-warning button-appStore-request" data-app-store-build>Upgrade to publish</button>
Expand Down Expand Up @@ -409,7 +409,7 @@ <h4 class="font-semibold m-0 mb-2">Push notifications technical details</h4>
<div class="flex mb-8">
<div class="font-bold" style="width: 85px">Step 4</div>
<div>
Visit <a href="https://console.cloud.google.com/" target="_blank">Google Cloud</a> to set up your FCM Service account.
Visit <a href="https://console.cloud.google.com/" target="_blank">Google Cloud</a> to set up your FCM Service account.
<br/> Follow detailed instructions <a href="https://help.fliplet.com/push-notifications/#2" target="_blank">here</a>.
</div>
</div>
Expand Down
111 changes: 83 additions & 28 deletions js/interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ var formInputSelectors = [

/* FUNCTIONS */

var createBundleId = function(bundleId) {
return $.ajax({
url: 'https://itunes.apple.com/lookup?bundleId=' + bundleId,
dataType: 'jsonp'
var createBundleId = async function(bundleId) {
const response = await Fliplet.API.request({
method: 'GET',
url: `v1/apps/bundle/android/exists/${bundleId}`
});

return response.exists;
};

function incrementVersionNumber(versionNumber) {
Expand Down Expand Up @@ -70,7 +72,7 @@ function addThumb(thumb) {
}

function loadAppStoreData() {
$('#appStoreConfiguration [name]').each(function(i, el) {
$('#appStoreConfiguration [name]').each(async function(i, el) {
var name = $(el).attr('name');

/* APP SCREENSHOTS */
Expand Down Expand Up @@ -107,17 +109,16 @@ function loadAppStoreData() {

/* ADD BUNDLE ID */
if (name === 'fl-store-bundleId' && typeof appStoreSubmission.data[name] === 'undefined') {
var bundleId = 'com.' + _.camelCase(organizationName) + '.' + _.camelCase(appName);
var bundleId = 'com.' + _.camelCase(organizationName) + '.' + _.camelCase(appName).toLowerCase();
const bundleIdExists = await createBundleId(bundleId);

createBundleId(bundleId).then(function(response) {
if (response.resultCount === 0) {
$('.bundleId-store-text').html(bundleId);
$('[name="' + name + '"]').val(bundleId);
} else {
$('.bundleId-store-text').html(bundleId + (response.resultCount + 1));
$('[name="' + name + '"]').val(bundleId + (response.resultCount + 1));
}
});
if (!bundleIdExists) {
$('.bundleId-store-text').html(bundleId);
$('[name="' + name + '"]').val(bundleId);
} else {
$('.bundleId-store-text').html(bundleId + 1);
$('[name="' + name + '"]').val(bundleId + 1);
}

return;
}
Expand Down Expand Up @@ -221,22 +222,21 @@ function checkFileExtension(fileName, element) {
}

function loadEnterpriseData() {
$('#enterpriseConfiguration [name]').each(function(i, el) {
$('#enterpriseConfiguration [name]').each(async function(i, el) {
var name = $(el).attr('name');

/* ADD BUNDLE ID */
if (name === 'fl-ent-bundleId' && typeof enterpriseSubmission.data[name] === 'undefined') {
var bundleId = 'com.' + _.camelCase(organizationName) + '.' + _.camelCase(appName);
var bundleId = 'com.' + _.camelCase(organizationName) + '.' + _.camelCase(appName).toLowerCase();
const bundleIdExists = await createBundleId(bundleId);

createBundleId(bundleId).then(function(response) {
if (response.resultCount === 0) {
$('.bundleId-apk-text').html(bundleId);
$('[name="' + name + '"]').val(bundleId);
} else {
$('.bundleId-apk-text').html(bundleId + (response.resultCount + 1));
$('[name="' + name + '"]').val(bundleId + (response.resultCount + 1));
}
});
if (!bundleIdExists) {
$('.bundleId-apk-text').html(bundleId);
$('[name="' + name + '"]').val(bundleId);
} else {
$('.bundleId-apk-text').html(bundleId + 1);
$('[name="' + name + '"]').val(bundleId + 1);
}

return;
}
Expand Down Expand Up @@ -681,6 +681,38 @@ function validateImageUrl(url, imageSelector, errorSelector) {
});
}

async function isBundleIdUnique(configuration) {
var bundleIdValue = ($(`[name="fl-${configuration}-bundleId"]`).val() || '').trim();

try {
var bundleIdExists = await createBundleId(bundleIdValue);

if (bundleIdExists) {
var $input = $('#fl-store-bundleId');
var $group = $input.closest('.form-group');
var $block = $group.find('.help-block.with-errors');

$block.html('<ul class="list-unstyled"><li>Bundle ID already exists on the Play Store. Please choose a unique Bundle ID.</li></ul>');
$group.addClass('has-error has-danger');
$('.fl-sb-appStore .fl-bundleId-holder').addClass('hidden');
$('.fl-sb-appStore .fl-bundleId-field').addClass('show');
setTimeout(checkGroupErrors, 0);

Fliplet.Modal.alert({
message: 'Bundle ID already exists. Please choose a unique Bundle ID.'
});

return false;
}

return true;
} catch (e) {
Fliplet.Modal.alert({
message: 'We could not verify the Bundle ID. Please try again.'
});
}
}

/* ATTACH LISTENERS */

$('[data-toggle="tooltip"]').tooltip({
Expand Down Expand Up @@ -734,6 +766,21 @@ $('a[data-toggle="tab"]').on('shown.bs.tab', function() {
Fliplet.Widget.autosize();
});

// Force on-the-fly validation for Bundle ID fields (validate only the field, not the whole form)
$(document).on('input focusout', '#fl-store-bundleId, #fl-ent-bundleId', function() {
var $field = $(this);
var $form = $field.closest('form');
var validator = $form.data('bs.validator');

$form.validator('update');

if (validator && typeof validator.validateInput === 'function') {
validator.validateInput($field);
}

checkGroupErrors();
});

$('[name="fl-store-keywords"]').on('tokenfield:createtoken', function(e) {
var currentValue = e.currentTarget.value.replace(/,\s+/g, ',');
var newValue = e.attrs.value;
Expand Down Expand Up @@ -905,7 +952,7 @@ $('form').validator({
}
});

$('#appStoreConfiguration').validator().on('submit', function(event) {
$('#appStoreConfiguration').validator().on('submit', async function(event) {
if (!storeFeatures.public) {
Fliplet.Studio.emit('overlay', {
name: 'app-settings',
Expand Down Expand Up @@ -959,6 +1006,10 @@ $('#appStoreConfiguration').validator().on('submit', function(event) {
return;
}

if (!await isBundleIdUnique('store')) {
return;
}

if (appInfo && appInfo.productionAppId) {
if (allAppData.indexOf('appStore') > -1) {
var message = 'Are you sure you wish to update your published app?';
Expand Down Expand Up @@ -991,7 +1042,7 @@ $('#appStoreConfiguration').validator().on('submit', function(event) {
setTimeout(checkGroupErrors, 0);
});

$('#enterpriseConfiguration').validator().on('submit', function(event) {
$('#enterpriseConfiguration').validator().on('submit', async function(event) {
if (!storeFeatures.private) {
Fliplet.Studio.emit('overlay', {
name: 'app-settings',
Expand Down Expand Up @@ -1045,6 +1096,10 @@ $('#enterpriseConfiguration').validator().on('submit', function(event) {
return;
}

if (!await isBundleIdUnique('ent')) {
return;
}

if (appInfo && appInfo.productionAppId) {
if (allAppData.indexOf('enterprise') > -1) {
var message = 'Are you sure you wish to update your published app?';
Expand Down
4 changes: 2 additions & 2 deletions js/interface.templates.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ this["Fliplet"]["Widget"]["Templates"] = this["Fliplet"]["Widget"]["Templates"]
this["Fliplet"]["Widget"]["Templates"]["templates.thumbs"] = Handlebars.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var helper;

return "<div class=\"col-xs-3\">\r\n <img src=\""
return "<div class=\"col-xs-3\">\n <img src=\""
+ container.escapeExpression(((helper = (helper = helpers.url || (depth0 != null ? depth0.url : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"url","hash":{},"data":data}) : helper)))
+ "\"/>\r\n</div>";
+ "\"/>\n</div>";
},"useData":true});