cartodb-4.42/lib/assets/javascripts/dashboard/views/public-profile/feed-view.js

306 lines
8.0 KiB
JavaScript

var $ = require('jquery');
var _ = require('underscore');
var Backbone = require('backbone');
var CoreView = require('backbone/core-view');
var moment = require('moment');
require('moment/locale/zh-cn');
var Utils = require('builder/helpers/utils');
var checkAndBuildOpts = require('builder/helpers/required-opts');
var randomQuote = require('builder/components/loading/random-quote');
var Visualizations = require('./user-feed/feed-collection');
var ViewFactory = require('builder/components/view-factory');
var MapCardPreview = require('dashboard/components/mapcard-preview-view');
var feedTemplate = require('./user-feed/feed.tpl');
var mapTemplate = require('./user-feed/map-item.tpl');
var datasetTemplate = require('./user-feed/dataset-item.tpl');
var loaderTemplatePath = require('./user-feed/loading.tpl');
var emptyTemplatePath = require('./user-feed/empty.tpl');
var errorTemplatePath = require('./user-feed/error.tpl');
var REQUIRED_OPTS = [
'config',
'authenticatedUser'
];
module.exports = CoreView.extend({
tagName: 'div',
_PAGE: 1,
_ITEMS_PER_PAGE: 8,
_SMALL_WIDTH: 544,
_CARD_HEIGHT: 170,
_LOADER_TITLE: 'Loading visualizations',
events: {
'click .js-more': '_onClickMore'
},
initialize: function (options) {
checkAndBuildOpts(options, REQUIRED_OPTS, this);
_.bindAll(this, '_onFetchError', '_onWindowResize', '_renderStaticMaps');
this.maps = [];
this._initModels();
this._initBindings();
},
render: function () {
this.$el.html(feedTemplate());
this._renderLoader();
this._fetchItems({ page: this._PAGE });
return this;
},
_onWindowResize: function () {
var width = $(window).width();
if (width <= this._SMALL_WIDTH) {
this.model.set('size', 'small');
} else {
this.model.set('size', 'big');
}
this._renderStaticMaps();
},
_initModels: function () {
var size = 'big';
var wWidth = $(window).width();
if (wWidth <= this._SMALL_WIDTH) {
size = 'small';
}
this.model = new Backbone.Model({
vis_count: 0,
type: '',
size: size,
page: 0,
order_by: 'updated_at'
});
this.collection = new Visualizations([], {
config: this._config
});
this.collection.on('reset', this._renderVisualizations, this);
},
_initBindings: function () {
this.model.on('change:show_more', this._onChangeShowMore, this);
this.model.on('change:show_loader', this._onChangeShowLoader, this);
this.model.on('change:show_mast', this._onChangeShowMast, this);
this.model.on('change:vis_count', this._onChangeVisCount, this);
$(window).on('resize', this._onWindowResize);
},
_onChangeVisCount: function () {
if (this.model.get('vis_count') >= this.collection.total_entries) {
this.model.set({ show_more: false });
} else {
this.model.set({ show_more: true });
}
},
_onChangeShowMast: function () {
if (this.model.get('show_mast')) {
this.$('.js-mast').removeClass('is-hidden');
} else {
this.$('.js-mast').addClass('is-hidden');
}
},
_onChangeShowLoader: function () {
if (this.model.get('show_loader')) {
this.loader.show();
} else {
this.loader.hide();
}
},
_onChangeShowMore: function () {
this.$('.js-more').toggleClass('is-hidden', !this.model.get('show_more'));
},
_renderLoader: function () {
this.loader = ViewFactory.createByTemplate(loaderTemplatePath, {
title: this._LOADER_TITLE,
quote: randomQuote()
});
this.$el.append(this.loader.render().$el);
},
_renderError: function () {
this.error = ViewFactory.createByTemplate(errorTemplatePath, {
});
this.$el.append(this.error.render().$el);
},
_renderEmpty: function () {
this.empty = ViewFactory.createByTemplate(emptyTemplatePath, {
name: this._config.user_name
});
this.$el.append(this.empty.render().$el);
},
_getDatasetSize: function (item) {
var size = item.get('table').size;
return size ? Utils.readablizeBytes(size, true).split(' ') : 0;
},
_getGeometryType: function (geomTypes) {
if (geomTypes && geomTypes.length > 0) {
var types = ['point', 'polygon', 'line', 'raster'];
var geomType = geomTypes[0];
return _.find(types, function (type) {
return geomType.toLowerCase().indexOf(type) !== -1;
});
}
return null;
},
_renderVisualizations: function () {
if (this.collection.length === 0) {
this.model.set({ show_loader: false });
this._renderEmpty();
return;
}
this.model.set({
vis_count: this.model.get('vis_count') + this.collection.length,
show_loader: false,
show_more: true,
show_filters: true,
show_mast: true
});
this.collection.each(function (item) {
var template = item.get('type') === 'derived' ? mapTemplate : datasetTemplate;
var geomType = (item.get('table') && item.get('table').geometry_types) ? this._getGeometryType(item.get('table').geometry_types) : null;
var owner = item.get('permission').owner;
var el = template({
vis: item.attributes,
datasetSize: this._getDatasetSize(item),
username: owner.username,
avatar_url: owner.avatar_url,
table_count: owner.table_count,
maps_count: owner.maps_count,
geomType: geomType,
account_host: this._config.get('account_host'),
base_url: this._config.get('base_url'),
updated: moment(item.get('updated_at')).fromNow(),
showLikeButton: this._userLoggedIn()
});
this.$('.js-items').append(el);
var $item = this.$('.js-items').find('[data-vis-id="' + item.get('id') + '"]');
if (item.get('type') === 'derived') {
this.maps.push(item);
}
if (item.get('type') === 'derived' && !item.get('rendered_' + this.model.get('size'))) {
this._renderStaticMap(item, $item);
}
}, this);
},
_renderStaticMaps: function () {
_.each(this.maps, function (item) {
if (!item.get('rendered_' + this.model.get('size'))) {
var $item = this.$('.js-items').find('[data-vis-id="' + item.get('id') + '"]');
this._renderStaticMap(item, $item);
}
}, this);
},
_renderStaticMap: function (vis, $el) {
var visId = vis.get('id');
var username = vis.get('permission').owner.username;
var width = 540;
var className = 'is-' + this.model.get('size');
if (this.model.get('size') === 'small') {
width = 288;
}
if (visId && username) {
vis.set('rendered_' + this.model.get('size'), true);
new MapCardPreview({
el: $el.find('.js-header'),
width: width,
height: this._CARD_HEIGHT,
mapsApiResource: this._config.getMapsResourceName(username),
username: username,
visId: visId,
className: className,
config: this._config
}).load();
}
},
_getLikesEndpoint: function (vis) {
return '/api/v1/viz/' + vis.get('id') + '/like';
},
_userLoggedIn: function () {
return this._authenticatedUser && !!this._authenticatedUser.get('username');
},
_fetchLike: function (model, url) {
if (this._authenticatedUser.get('username')) {
// no more loadModelCompleted event
model.once('change', function () {
model.set('likeable', true);
});
model.url = url;
model.sync = Backbone.withCORS;
model.fetch();
}
},
_fetchItems: function (params) {
var data = _.extend({
types: 'table,derived',
privacy: 'public',
only_published: 'true',
exclude_shared: 'true',
per_page: this._ITEMS_PER_PAGE,
order: 'updated_at'
}, params);
this.collection.fetch({
data: data,
error: this._onFetchError,
reset: true
});
},
_onFetchError: function () {
this.model.set({ show_loader: false });
this._renderError();
},
_onClickMore: function (e) {
this.killEvent(e);
this.model.set({ show_more: false, show_loader: true });
this._fetchItems({ page: ++this._PAGE });
}
});