<commit_before>/**
 * Onboarding tracking information
 */
// TODO store-jsdocs
'use strict';

var OnboardingProgress = require('../viewmodels/OnboardingProgress');
var NavAction = require('../viewmodels/NavAction');
var ko = require('knockout');
var userProfile = require('./userProfile');
var local = require('./drivers/localforage');
var onboardingSuccessModal = require('../modals/onboardingSuccess');

var NAVBAR_TITLE = 'Create your first listing';

// Onboarding management and state, initially empty so no progress
var api = new OnboardingProgress();
module.exports = api;

api.navbarTitle = function() {
    return NAVBAR_TITLE;
};

api.currentActivity = ko.observable('');

// Requires initialization to receive and app instance
// TODO: Rething to refactor this; will require decoupling app.shell
api.init = function init(app) {
    api.app = app;
    api.currentActivity(app.shell.currentRoute && app.shell.currentRoute.name);
    app.shell.on(app.shell.events.itemReady, function() {
        api.currentActivity(app.shell.currentRoute.name);
    });
};

/**
 * Set-up the onboarding with preset data after a signup or restoring a session.
 * @param {Object} options
 * @param {string} options.step The step where the user left the process or starts with.
 * @param {number} [options.jobTitleID] The jobTitleID selected at a previous
 * signup form or saved after the addJobTitle step.
 * @param {boolean} [options.isServiceProfessional] It set-ups the equivalent flag
 * and when value is 'true', it skips the 'welcome' step (that has the
 * selector buttons for the type of profile) in case that's the current one.
 */
api.setup = function(options) {
    var step = options.step;
    if (options.isServiceProfessional === true && options.step === 'welcome') {
        step = api.stepAfter(step).stepName();
    }
    api.isServiceProfessional(options.isServiceProfessional);
    if (options.jobTitleID |0 > 0) {
        api.selectedJobTitleID(options.jobTitleID);
    }
    api.setStep(step);
};

// Extended with new methods

// Set the correct onboarding progress and step given a step name
// (usually from database)
api.setStep = function(stepName) {
    if (this.setStepByName(stepName)) {
        return true;
    }

    // No progress:
    this.model.reset();
    return false;
};

// Update the given navbar with the current onboarding information (only if in progress)
api.updateNavBar = function(navBar) {
    var yep = this.inProgress();
    if (yep) {
        navBar.leftAction(NavAction.menuIn);
        navBar.title(api.navbarTitle());
    }
    return yep;
};

api.goCurrentStep = function() {
    // Go current step of onboarding, and if no one, go to dashboard
    var url = this.inProgress() ? this.stepUrl() : 'dashboard';
    this.app.shell.go(url);
};

api.goNext = function goNext() {
    var url;
    var showOnboardingSuccess = false;

    if(this.isAtCurrentStep()) {
        this.incrementStep();
        userProfile.saveOnboardingStep(this.stepName());

        url = this.isFinished() ? this.stepAfterFinish() : this.stepUrl();
        // When onboarding finishes, we will prepare to display a 'success' message
        if (this.isFinished()) {
            showOnboardingSuccess = true;
        }
    }
    else {
        url = this.stepAfter(api.currentActivity()).stepUrl();
    }

    // replaceState flag is true, preventing browser back button to move between onboarding steps
    this.app.shell.go(url, null, true);

    // Display modal with notification when required
    if (showOnboardingSuccess) {
        onboardingSuccessModal.show({
            isServiceProfessional: this.isServiceProfessional()
        });
    }
};

api.isAtCurrentStep = ko.pureComputed(function() {
    return this.currentActivity() === this.stepName();
}, api);

/**
    Check if onboarding is enabled on the user profile
    and redirects to the current step, or do nothing.
**/
api.goIfEnabled = function() {
    if (this.inProgress() && !api.isAtCurrentStep()) {
        // Go to the step URL if we are NOT already there, by checking name to
        // not overwrite additional details, like a jobTitleID at the URL
        api.app.shell.go(api.stepUrl());
    }

    return this.inProgress();
};

/// Workaround for #374:
/// Local copy of the onboarding selectedJobTitleID, returned by
/// login/signup API as onboardingJobTitleID, to be able to
/// resume onboarding with the correct jobTitle, fixing #374
/// NOTE: I think is a workaround that needs a better solution through a
/// refactor just to make the code more readable and clear, but still
/// works perfect for the case.
var LOCAL_JOBTITLEID_KEY = 'onboardingJobTitleID';
/**
 * Store local copy of the ID to allow for resuming.
 * @private
 * @param {number} jobTitleID
 * @returns {Promise}
 */
var persistLocalJobTitleID = function(jobTitleID) {
    return local.setItem(LOCAL_JOBTITLEID_KEY, jobTitleID);
};
/**
 * Get the jobTitleID stored locally after a sign-up or in course onboarding,
 * needed to restore the onboarding process correctly.
 * @returns {Promise<number>} The jobTitleID
 */
api.getLocalJobTitleID = function() {
    return local.getItem(LOCAL_JOBTITLEID_KEY);
};
// At any point that selected job title ID is changed, we persist it
api.selectedJobTitleID.subscribe(persistLocalJobTitleID);
<commit_msg>Fixed double redirection starting onboarding for non US users #722<commit_after>/**
 * Onboarding tracking information
 */
// TODO store-jsdocs
'use strict';

var OnboardingProgress = require('../viewmodels/OnboardingProgress');
var NavAction = require('../viewmodels/NavAction');
var ko = require('knockout');
var userProfile = require('./userProfile');
var local = require('./drivers/localforage');
var onboardingSuccessModal = require('../modals/onboardingSuccess');

var NAVBAR_TITLE = 'Create your first listing';

// Onboarding management and state, initially empty so no progress
var api = new OnboardingProgress();
module.exports = api;

api.navbarTitle = function() {
    return NAVBAR_TITLE;
};

api.currentActivity = ko.observable('');

// Requires initialization to receive and app instance
// TODO: Rething to refactor this; will require decoupling app.shell
api.init = function init(app) {
    api.app = app;
    api.currentActivity(app.shell.currentRoute && app.shell.currentRoute.name);
    app.shell.on(app.shell.events.itemReady, function() {
        api.currentActivity(app.shell.currentRoute.name);
    });
};

/**
 * Set-up the onboarding with preset data after a signup or restoring a session.
 * @param {Object} options
 * @param {string} options.step The step where the user left the process or starts with.
 * @param {number} [options.jobTitleID] The jobTitleID selected at a previous
 * signup form or saved after the addJobTitle step.
 * @param {boolean} [options.isServiceProfessional] It set-ups the equivalent flag
 * and when value is 'true', it skips the 'welcome' step (that has the
 * selector buttons for the type of profile) in case that's the current one.
 */
api.setup = function(options) {
    var step = options.step;
    if (options.isServiceProfessional === true && options.step === 'welcome') {
        step = api.stepAfter(step).stepName();
    }
    api.isServiceProfessional(options.isServiceProfessional);
    if (options.jobTitleID |0 > 0) {
        api.selectedJobTitleID(options.jobTitleID);
    }
    api.setStep(step);
};

// Extended with new methods

// Set the correct onboarding progress and step given a step name
// (usually from database)
api.setStep = function(stepName) {
    if (this.setStepByName(stepName)) {
        return true;
    }

    // No progress:
    this.model.reset();
    return false;
};

// Update the given navbar with the current onboarding information (only if in progress)
api.updateNavBar = function(navBar) {
    var yep = this.inProgress();
    if (yep) {
        navBar.leftAction(NavAction.menuIn);
        navBar.title(api.navbarTitle());
    }
    return yep;
};

api.goCurrentStep = function() {
    // Go current step of onboarding, and if no one, go to dashboard
    var url = this.inProgress() ? this.stepUrl() : 'dashboard';
    this.app.shell.go(url);
};

api.goNext = function goNext() {
    var url;
    var showOnboardingSuccess = false;

    if(this.isAtCurrentStep()) {
        this.incrementStep();
        userProfile.saveOnboardingStep(this.stepName());

        url = this.isFinished() ? this.stepAfterFinish() : this.stepUrl();
        // When onboarding finishes, we will prepare to display a 'success' message
        if (this.isFinished()) {
            showOnboardingSuccess = true;
        }
    }
    else {
        url = this.stepAfter(api.currentActivity()).stepUrl();
    }

    // replaceState flag is true, preventing browser back button to move between onboarding steps
    this.app.shell.go(url, null, true);

    // Display modal with notification when required
    if (showOnboardingSuccess) {
        onboardingSuccessModal.show({
            isServiceProfessional: this.isServiceProfessional()
        });
    }
};

api.isAtCurrentStep = ko.pureComputed(function() {
    return this.currentActivity() === this.stepName();
}, api);

/**
    Check if onboarding is enabled on the user profile
    and redirects to the current step, or do nothing.
**/
api.goIfEnabled = function() {
    var inProgress = this.inProgress();
    if (inProgress && !api.isAtCurrentStep()) {
        // Go to the step URL if we are NOT already there, by checking name to
        // not overwrite additional details, like a jobTitleID at the URL
        api.app.shell.go(api.stepUrl());
    }

    return inProgress;
};

/// Workaround for #374:
/// Local copy of the onboarding selectedJobTitleID, returned by
/// login/signup API as onboardingJobTitleID, to be able to
/// resume onboarding with the correct jobTitle, fixing #374
/// NOTE: I think is a workaround that needs a better solution through a
/// refactor just to make the code more readable and clear, but still
/// works perfect for the case.
var LOCAL_JOBTITLEID_KEY = 'onboardingJobTitleID';
/**
 * Store local copy of the ID to allow for resuming.
 * @private
 * @param {number} jobTitleID
 * @returns {Promise}
 */
var persistLocalJobTitleID = function(jobTitleID) {
    return local.setItem(LOCAL_JOBTITLEID_KEY, jobTitleID);
};
/**
 * Get the jobTitleID stored locally after a sign-up or in course onboarding,
 * needed to restore the onboarding process correctly.
 * @returns {Promise<number>} The jobTitleID
 */
api.getLocalJobTitleID = function() {
    return local.getItem(LOCAL_JOBTITLEID_KEY);
};
// At any point that selected job title ID is changed, we persist it
api.selectedJobTitleID.subscribe(persistLocalJobTitleID);

{'fraction_non_alphanumeric': 0.11234487263226649, 'fraction_numerical': 0.0017728842026686572, 'mean_word_length': 3.486395981582252, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5158673', 'n_tokens_mistral': 3198, 'n_tokens_neox': 3038, 'n_words': 996}