<commit_before>/**
    WorkPhotos activity
**/
'use strict';

var ko = require('knockout'),
    $ = require('jquery'),
    Activity = require('../components/Activity');

var WorkPhoto = require('../models/WorkPhoto'),
    photoTools = require('../utils/photoTools');

var A = Activity.extend(function WorkPhotosActivity() {

    Activity.apply(this, arguments);

    this.accessLevel = this.app.UserType.serviceProfessional;
    this.viewModel = new ViewModel(this.app);
    // Defaults settings for navBar.
    this.navBar = Activity.createSubsectionNavBar('Job Title');

    // Event handlers for photo list management
    this.registerHandler({
        target: this.$activity,
        selector: '.WorkPhotos-imgBtn',
        event: 'click',
        handler: function(event) {
            if (!this.viewModel.state.isLocked())
                $(event.target).closest('li').toggleClass('is-selected');
        }.bind(this)
    });
});

exports.init = A.init;

A.prototype.show = function show(options) {
    // Reset
    this.viewModel.list.removeAll();
    this.viewModel.removedItems.removeAll();
    this.viewModel.jobTitleID(0);
    
    Activity.prototype.show.call(this, options);

    var params = options && options.route && options.route.segments;
    var jobTitleID = params[0] |0;
    this.viewModel.jobTitleID(jobTitleID);
    if (jobTitleID) {
        // Get data for the Job title ID
        this.app.model.workPhotos.getList(jobTitleID)
        .then(function(list) {
            // Save for use in the view
            this.viewModel.list(this.app.model.workPhotos.asModel(list));
        }.bind(this))
        .catch(function (err) {
            this.app.modals.showError({
                title: 'There was an error while loading.',
                error: err
            });
        }.bind(this));
    }
    else {
        this.viewModel.list([]);
    }
};

function ViewModel(app) {

    this.jobTitleID = ko.observable(0);
    this.list = ko.observableArray([]);
    this.removedItems = ko.observableArray([]);
    
    this.state = app.model.workPhotos.state;
    
    this.saveBtnText = ko.pureComputed(function() {
        return this.state.isSaving() ? 'Saving..' : this.state.isLoading() ? 'Loading..' : this.state.isDeleting() ? 'Deleting..' : 'Save';
    }, this);
    
    
    // IMPORTANT: Size like the server 'original' photo, that's the 'visible size on screen' multiply
    // by the scale for the original used to create hidpi versions and to crop with quality.
    var cameraSettings = {
        targetWidth: 442 * 3,
        targetHeight: 332 * 3,
        correctOrientation: true
    };

    var addNew = function(fromCamera) {
        // Pick a new photo
        this.openPhotoPicker(fromCamera)
        .then(function(data) {
            var newItem = new WorkPhoto({
                workPhotoID: 0,
                jobTitleID: this.jobTitleID(),
                url: data.previewUrl,
                localTempFilePath: data.localUrl,
                caption: ''
            });
            this.list.push(newItem);
        }.bind(this))
        .catch(function(err) {
            app.modals.showError({ error: err, title: 'Error getting photo.' });
        });
    }.bind(this);
    
    this.takePhotoForNew = function() {
        addNew(true);
    }.bind(this);
    
    this.pickPhotoForNew = function() {
        addNew(false);
    }.bind(this);

    this.removeImg = function(item) {
        this.removedItems.push(item);
        this.list.remove(item);
    }.bind(this);

    this.openPhotoPicker = function(fromCamera) {
        var settings = $.extend({}, cameraSettings, {
            sourceType: fromCamera ?
                window.Camera && window.Camera.PictureSourceType.CAMERA :
                window.Camera && window.Camera.PictureSourceType.PHOTOLIBRARY
        });
        if (photoTools.takePhotoSupported()) {
            return photoTools.cameraGetPicture(settings)
            .then(function(imgLocalUrl) {
                return {
                    localUrl: imgLocalUrl,
                    previewUrl: photoTools.getPreviewPhotoUrl(imgLocalUrl)
                };
            });
        }
        else {
            return Promise.reject('Take photo is not supported on the web right now');
        }
    };
    
    this.updateSort = function(/*info*/) {
        // TODO Update rankPosition on every item using the sorting info
    };
    
    // Delete on remote REST API all the registered items for deletion
    var remoteDeleteFlaggedItems = function() {
        return this.removedItems().reduce(function(cur, next) {<commit_msg>Completed the ability to re-order work photos #699 (was mostly implemented, only added the javascript to update rankPosition after an UI sortable update).<commit_after>/**
    WorkPhotos activity
**/
'use strict';

var ko = require('knockout'),
    $ = require('jquery'),
    Activity = require('../components/Activity');

var WorkPhoto = require('../models/WorkPhoto'),
    photoTools = require('../utils/photoTools');

var A = Activity.extend(function WorkPhotosActivity() {

    Activity.apply(this, arguments);

    this.accessLevel = this.app.UserType.serviceProfessional;
    this.viewModel = new ViewModel(this.app);
    // Defaults settings for navBar.
    this.navBar = Activity.createSubsectionNavBar('Job Title');

    // Event handlers for photo list management
    this.registerHandler({
        target: this.$activity,
        selector: '.WorkPhotos-imgBtn',
        event: 'click',
        handler: function(event) {
            if (!this.viewModel.state.isLocked())
                $(event.target).closest('li').toggleClass('is-selected');
        }.bind(this)
    });
});

exports.init = A.init;

A.prototype.show = function show(options) {
    // Reset
    this.viewModel.list.removeAll();
    this.viewModel.removedItems.removeAll();
    this.viewModel.jobTitleID(0);
    
    Activity.prototype.show.call(this, options);

    var params = options && options.route && options.route.segments;
    var jobTitleID = params[0] |0;
    this.viewModel.jobTitleID(jobTitleID);
    if (jobTitleID) {
        // Get data for the Job title ID
        this.app.model.workPhotos.getList(jobTitleID)
        .then(function(list) {
            // Save for use in the view
            this.viewModel.list(this.app.model.workPhotos.asModel(list));
        }.bind(this))
        .catch(function (err) {
            this.app.modals.showError({
                title: 'There was an error while loading.',
                error: err
            });
        }.bind(this));
    }
    else {
        this.viewModel.list([]);
    }
};

function ViewModel(app) {

    this.jobTitleID = ko.observable(0);
    this.list = ko.observableArray([]);
    this.removedItems = ko.observableArray([]);
    
    this.state = app.model.workPhotos.state;
    
    this.saveBtnText = ko.pureComputed(function() {
        return this.state.isSaving() ? 'Saving..' : this.state.isLoading() ? 'Loading..' : this.state.isDeleting() ? 'Deleting..' : 'Save';
    }, this);
    
    
    // IMPORTANT: Size like the server 'original' photo, that's the 'visible size on screen' multiply
    // by the scale for the original used to create hidpi versions and to crop with quality.
    var cameraSettings = {
        targetWidth: 442 * 3,
        targetHeight: 332 * 3,
        correctOrientation: true
    };

    var addNew = function(fromCamera) {
        // Pick a new photo
        this.openPhotoPicker(fromCamera)
        .then(function(data) {
            var newItem = new WorkPhoto({
                workPhotoID: 0,
                jobTitleID: this.jobTitleID(),
                url: data.previewUrl,
                localTempFilePath: data.localUrl,
                caption: ''
            });
            this.list.push(newItem);
        }.bind(this))
        .catch(function(err) {
            app.modals.showError({ error: err, title: 'Error getting photo.' });
        });
    }.bind(this);
    
    this.takePhotoForNew = function() {
        addNew(true);
    }.bind(this);
    
    this.pickPhotoForNew = function() {
        addNew(false);
    }.bind(this);

    this.removeImg = function(item) {
        this.removedItems.push(item);
        this.list.remove(item);
    }.bind(this);

    this.openPhotoPicker = function(fromCamera) {
        var settings = $.extend({}, cameraSettings, {
            sourceType: fromCamera ?
                window.Camera && window.Camera.PictureSourceType.CAMERA :
                window.Camera && window.Camera.PictureSourceType.PHOTOLIBRARY
        });
        if (photoTools.takePhotoSupported()) {
            return photoTools.cameraGetPicture(settings)
            .then(function(imgLocalUrl) {
                return {
                    localUrl: imgLocalUrl,
                    previewUrl: photoTools.getPreviewPhotoUrl(imgLocalUrl)
                };
            });
        }
        else {
            return Promise.reject('Take photo is not supported on the web right now');
        }
    };
    
    this.updateSort = function(info) {
        /* info {
            item: Model,
            sourceIndex: 0,
            targetIndex: 1,
            sourceParent: observableArray, // The list
            targetParent: observableArray, // The same as sourceParent in this case
            sourceparentNode: domElement
        }
        */
        // Rather than try to update only affected indexes (the targetIndex and everything
        // after it), update all items to keep the rankPosition sane (edge cases like deletions
        // or server side bigger rankPositions could complicate that minor optimization, so just
        // all is less problem and is still quick).
        var list = info.sourceParent();
        for (var i = 0, l = list.length; i < l; i++) {
            list[i].rankPosition(i + 1);
        }
    };
    
    // Delete on remote REST API all the registered items for deletion
    var remoteDeleteFlaggedItems = function() {
        return this.removedItems().reduce(function(cur, next) {
{'fraction_non_alphanumeric': 0.12239013720421554, 'fraction_numerical': 0.003280970371843309, 'mean_word_length': 2.1346213773761296, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 3, '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': '2541609', 'n_tokens_mistral': 2897, 'n_tokens_neox': 2773, 'n_words': 650}