<commit_before>/**
* ownCloud - News app
*
* @author <NAME>
* Copyright (c) 2012 - <NAME> <<EMAIL>>
*
* This file is licensed under the Affero General Public License version 3 or later.
* See the COPYING-README file
*
*/

/**
 * This file includes the cache and access for feed items
 */

var News = News || {};

(function(){

    /*##########################################################################
     * Items
     *########################################################################*/
    /**
     * Creates a new item instance and tells it to put the items into
     * the selected div
     * @param cssSelector the selector of the div which holds the ul for the feeds
     */
    var Items = function(cssSelector){
        var self = this;
        this._$articleList = $(cssSelector);
        this._$articleList.scrollTop(0);
        this._$articleList.children('ul').children('.feed_item:eq(0)').addClass('viewed');
        this._itemCache = new ItemCache();

        this._setScrollBottom();
        $(window).resize(function(){
            self._setScrollBottom();
        });
        
        // mark items whose title was hid under the top edge as read
        this._scrollTimeoutMiliSecs = 100;
        this._markReadTimeoutMiliSecs = 500;
        this._isScrolling = false;
        this._$articleList.scroll(function(){
            // prevent too many scroll requests;
            if(!self._isScrolling){
                self._isScrolling = true;
                setTimeout(function(){
                    self._isScrolling = false;
                }, self._scrollTimeoutMiliSecs);

                $(this).children('ul').children('.feed_item:not(.read)').each(function(){
                    var item = this;
                    var itemOffset = $(item).position().top;
                    if(itemOffset <= 0){
                        setTimeout(function(){ 
                            self._markItemAsReadTimeout(item);
                        }, self._markReadTimeoutMiliSecs);
                    }
                });
                self._markCurrentlyViewed();
            }
        });

        this._itemCache.populate(this._$articleList.children('ul'));
    }

    /**
     * Marks an item as read which is called by the timeout
     * @param item the dom item
     */
    Items.prototype._markItemAsReadTimeout = function(item) {
        var itemId = parseInt($(item).data('id'));
        var itemOffset = $(item).position().top;
        var item = this._itemCache.getItem(itemId);
        if(itemOffset < 0){
            if(!item.isLocked()){
                // lock item to prevent massive request when scrolling
                item.setLocked(true);
                item.setRead(true);
            }
        } 
    };

    /**
     * Loads the feeds into the righ view
     * @param type the type (MenuNodeType)
     * @param id the id
     * @param onSuccessCallback a callback that is executed when the loading succeeded
     */
    Items.prototype.load = function(type, id, onSuccessCallback) {
        var self = this;
        var data = {
            id: id,
            type: type,
            mostRecentItemId: this._itemCache.getMostRecentItemId(type, id)
        };

        this._$articleList.addClass('loading');
        this._$articleList.children('ul').hide();

        $.post(OC.filePath('news', 'ajax', 'loadfeed.php'), data, function(jsonData) {
            if(jsonData.status == 'success'){
                self._$articleList.empty() // FIXME: does this also removed cached items?
                self._itemCache.populate(jsonData.data.feedItems);

                var $items = self._itemCache.getFeedHtml(type, id);
                self._$articleList.append($items);
                self._$articleList.scrollTop(0);
                onSuccessCallback();
            } else {
                OC.dialogs.alert(t('news', 'Error while loading the feed'), t('news', 'Error'));
                self._$articleList.children('ul').show();
            }
            self._$articleList.removeClass('loading');
            self._setScrollBottom();
        });
    };


    /**
     * Jumps to the next visible element
     */
    Items.prototype.jumpToNext = function() {<commit_msg> If you click on a feed and then on a second feed, the first one is still loaded into the main view if the second one finished faster : fixed<commit_after>/**
* ownCloud - News app
*
* @author <NAME>
* Copyright (c) 2012 - <NAME> <<EMAIL>>
*
* This file is licensed under the Affero General Public License version 3 or later.
* See the COPYING-README file
*
*/

/**
 * This file includes the cache and access for feed items
 */

var News = News || {};

(function(){

    /*##########################################################################
     * Items
     *########################################################################*/
    /**
     * Creates a new item instance and tells it to put the items into
     * the selected div
     * @param cssSelector the selector of the div which holds the ul for the feeds
     */
    var Items = function(cssSelector){
        var self = this;
        this._$articleList = $(cssSelector);
        this._$articleList.scrollTop(0);
        this._$articleList.children('ul').children('.feed_item:eq(0)').addClass('viewed');
        this._itemCache = new ItemCache();

        this._setScrollBottom();
        $(window).resize(function(){
            self._setScrollBottom();
        });
        
        // mark items whose title was hid under the top edge as read
        this._scrollTimeoutMiliSecs = 100;
        this._markReadTimeoutMiliSecs = 500;
        this._isScrolling = false;
        this._$articleList.scroll(function(){
            // prevent too many scroll requests;
            if(!self._isScrolling){
                self._isScrolling = true;
                setTimeout(function(){
                    self._isScrolling = false;
                }, self._scrollTimeoutMiliSecs);

                $(this).children('ul').children('.feed_item:not(.read)').each(function(){
                    var item = this;
                    var itemOffset = $(item).position().top;
                    if(itemOffset <= 0){
                        setTimeout(function(){ 
                            self._markItemAsReadTimeout(item);
                        }, self._markReadTimeoutMiliSecs);
                    }
                });
                self._markCurrentlyViewed();
            }
        });

        this._itemCache.populate(this._$articleList.children('ul'));
    }

    /**
     * Marks an item as read which is called by the timeout
     * @param item the dom item
     */
    Items.prototype._markItemAsReadTimeout = function(item) {
        var itemId = parseInt($(item).data('id'));
        var itemOffset = $(item).position().top;
        var item = this._itemCache.getItem(itemId);
        if(itemOffset < 0){
            if(!item.isLocked()){
                // lock item to prevent massive request when scrolling
                item.setLocked(true);
                item.setRead(true);
            }
        } 
    };

    /**
     * Loads the feeds into the righ view
     * @param type the type (MenuNodeType)
     * @param id the id
     * @param onSuccessCallback a callback that is executed when the loading succeeded
     */
    Items.prototype.load = function(type, id, onSuccessCallback) {
        this._lastActiveFeedId = id;
        this._lastActiveFeedType = type;

        var self = this;
        var data = {
            id: id,
            type: type,
            mostRecentItemId: this._itemCache.getMostRecentItemId(type, id)
        };

        this._$articleList.addClass('loading');
        this._$articleList.children('ul').hide();

        $.post(OC.filePath('news', 'ajax', 'loadfeed.php'), data, function(jsonData) {
            // prevent loading in selected feeds that are not active any more when
            // the post finishes later
            if(self._lastActiveFeedType === type && self._lastActiveFeedId === id){
                if(jsonData.status == 'success'){
                    self._$articleList.empty() // FIXME: does this also removed cached items?
                    self._itemCache.populate(jsonData.data.feedItems);

                    var $items = self._itemCache.getFeedHtml(type, id);
                    self._$articleList.append($items);
                    self._$articleList.scrollTop(0);
                    onSuccessCallback();
                } else {
                    OC.dialogs.alert(t('news', 'Error while loading the feed'), t('news', 'Error'));
                    self._$articleList.children('ul').show();
                }
                self._$articleList.removeClass('loading');
                self._setScrollBottom();
            }
        });
    };


    /**
     * Jumps to the next visible element
     */
    Items.prototype.jumpToNext = function() {
{'fraction_non_alphanumeric': 0.14725299317444332, 'fraction_numerical': 0.0035806198948192904, 'mean_word_length': 1.9095052083333333, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 11, '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': '3159309', 'n_tokens_mistral': 2368, 'n_tokens_neox': 2237, 'n_words': 579}