main.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. /**
  2. * Copyright (c) UNA, Inc - https://una.io
  3. * MIT License - https://opensource.org/licenses/MIT
  4. *
  5. * @defgroup Timeline Timeline
  6. * @ingroup UnaModules
  7. *
  8. * @{
  9. */
  10. function BxTimelineMain() {
  11. this.sIdPost = '#bx-timeline-post';
  12. this.sIdPostForm = 'form#bx_timeline_post';
  13. this.sId = '#bx-timeline';
  14. this.sSP = 'bx-tl';
  15. this.sClassView = this.sSP + '-view';
  16. this.sClassMasonry = this.sSP + '-masonry';
  17. this.sClassItems = this.sSP + '-items';
  18. this.sClassItem = this.sSP + '-item';
  19. this.sClassItemCnt = this.sSP + '-item-cnt';
  20. this.sClassDividerToday = this.sSP + '-divider-today';
  21. this.sClassItemContent = this.sSP + '-item-content';
  22. this.sClassItemComments = this.sSP + '-item-comments-holder';
  23. this.sClassItemImages = this.sSP + '-item-images';
  24. this.sClassItemImage = this.sSP + '-item-image';
  25. this.sClassItemVideos = this.sSP + '-item-videos';
  26. this.sClassItemVideo = this.sSP + '-item-video';
  27. this.sClassItemAttachments = this.sSP + '-item-attachments';
  28. this.sClassItemAttachment = this.sSP + '-item-attachment';
  29. this.sClassSample = this.sSP + '-sample';
  30. this.sClassBlink = this.sSP + '-blink';
  31. this.sClassJumpTo = this.sSP + '-jump-to';
  32. this.oView = null;
  33. this.bViewTimeline = false;
  34. this.bViewOutline = false;
  35. this.bViewItem = false;
  36. this._iLimitAttachLinks = 0;
  37. this._sLimitAttachLinksErr = '';
  38. this._oAttachedLinks = {};
  39. }
  40. BxTimelineMain.prototype.updateOptions = function(oOptions) {
  41. var $this = this;
  42. Object.keys(oOptions).map(function(sOption) {
  43. var sField = '_' + sOption;
  44. if($this[sField] != undefined)
  45. $this[sField] = oOptions[sOption];
  46. });
  47. };
  48. BxTimelineMain.prototype.initView = function() {
  49. //Do some basic initialization here.
  50. };
  51. BxTimelineMain.prototype.initVideos = function(oParent) {
  52. oParent.find('iframe').load(function() {
  53. $(this).height(($(this).contents().find('video').height()) + 'px');
  54. });
  55. };
  56. BxTimelineMain.prototype.isMasonry = function() {
  57. return this.oView.find('.' + this.sClassItems).hasClass(this.sClassMasonry);
  58. };
  59. BxTimelineMain.prototype.isMasonryEmpty = function() {
  60. return this.oView.find('.' + this.sClassItems + ' .' + this.sClassItem).length == 0;
  61. };
  62. BxTimelineMain.prototype.initMasonry = function(onComplete) {
  63. var $this = this;
  64. var oHolder = this.oView.find('.' + this.sClassItems);
  65. var oItems = oHolder.find('.' + this.sClassItem);
  66. if(oItems.length == 0)
  67. return;
  68. oItems.resize(function(){
  69. $this.reloadMasonry();
  70. }).find('.bx-tl-item-text .bx-tl-content').bxCheckOverflowHeight(this.sSP + '-overflow', function(oElement) {
  71. $this.onFindOverflow(oElement);
  72. });
  73. oHolder.addClass(this.sClassMasonry).masonry({
  74. itemSelector: '.' + this.sClassItem,
  75. columnWidth: '.' + this.sSP + '-grid-sizer'
  76. }).masonry('once', 'layoutComplete', function() {
  77. if(typeof onComplete === 'function')
  78. onComplete(oItems);
  79. });
  80. };
  81. BxTimelineMain.prototype.destroyMasonry = function() {
  82. this.oView.find('.' + this.sClassItems).removeClass(this.sClassMasonry).masonry('destroy');
  83. };
  84. BxTimelineMain.prototype.appendMasonry = function(oItems, onComplete) {
  85. var $this = this;
  86. var oItems = $(oItems);
  87. oItems.resize(function(){
  88. $this.reloadMasonry();
  89. }).find('iframe').load(function() {
  90. $this.reloadMasonry();
  91. }).find('img.' + this.sSP + '-item-image').load(function() {
  92. $this.reloadMasonry();
  93. });
  94. var oHolder = this.oView.find('.' + this.sClassItems).masonry('layout').append(oItems);
  95. if(!this.isMasonry())
  96. this.initMasonry(onComplete);
  97. else
  98. oHolder.masonry('appended', oItems).masonry('layout').masonry('once', 'layoutComplete', function() {
  99. if(typeof onComplete === 'function')
  100. onComplete(oItems);
  101. });
  102. };
  103. BxTimelineMain.prototype.prependMasonry = function(oItems, onComplete) {
  104. var $this = this;
  105. var oItems = $(oItems);
  106. oItems.resize(function(){
  107. $this.reloadMasonry();
  108. }).find('iframe').load(function() {
  109. $this.reloadMasonry();
  110. }).find('img.' + this.sSP + '-item-image').load(function() {
  111. $this.reloadMasonry();
  112. });
  113. var oHolder = this.oView.find('.' + this.sClassItems).masonry('layout').prepend(oItems);
  114. if(!this.isMasonry())
  115. this.initMasonry(onComplete);
  116. else
  117. oHolder.masonry('prepended', oItems).masonry('layout').masonry('once', 'layoutComplete', function() {
  118. if(typeof onComplete === 'function')
  119. onComplete(oItems);
  120. });
  121. };
  122. BxTimelineMain.prototype.removeMasonry = function(oItems, onRemove) {
  123. var $this = this;
  124. var oItems = $(oItems);
  125. var oHolder = this.oView.find('.' + this.sClassItems);
  126. if(typeof onRemove === 'function')
  127. oHolder.masonry('once', 'removeComplete', onRemove);
  128. oHolder.masonry('remove', oItems).masonry('layout');
  129. };
  130. BxTimelineMain.prototype.reloadMasonry = function() {
  131. this.oView.find('.' + this.sClassItems).masonry('reloadItems').masonry('layout');
  132. };
  133. BxTimelineMain.prototype.initFlickityImages = function(oParent, sSelectorItemImage) {
  134. var sItem = sSelectorItemImage ? sSelectorItemImage : 'div.' + this.sClassItemImage;
  135. if(oParent.find(sItem).length <= 1)
  136. return;
  137. var oCarousel = oParent;
  138. oCarousel.flickity({
  139. cellSelector: sItem,
  140. cellAlign: 'left',
  141. imagesLoaded: true,
  142. wrapAround: true,
  143. pageDots: false
  144. });
  145. oCarousel.find(sItem + ' img').each(function() {
  146. $(this).load(function() {
  147. oCarousel.flickity('resize');
  148. });
  149. });
  150. };
  151. BxTimelineMain.prototype.initFlickityVideos = function(oParent) {
  152. var sItem = 'div.' + this.sClassItemVideo;
  153. if(oParent.find(sItem).length <= 1)
  154. return;
  155. var oCarousel = oParent;
  156. oCarousel.flickity({
  157. cellSelector: sItem,
  158. cellAlign: 'left',
  159. imagesLoaded: true,
  160. wrapAround: true,
  161. pageDots: false
  162. });
  163. oCarousel.find(sItem + ' video').each(function() {
  164. this.addEventListener('loadedmetadata', function() {
  165. oCarousel.flickity('resize');
  166. }, true);
  167. });
  168. };
  169. BxTimelineMain.prototype.initFlickityAttachments = function(oParent) {
  170. var sItem = 'div.' + this.sClassItemAttachment;
  171. if(oParent.find(sItem).length <= 1)
  172. return;
  173. var oCarousel = oParent;
  174. oCarousel.flickity({
  175. cellSelector: sItem,
  176. cellAlign: 'left',
  177. imagesLoaded: true,
  178. wrapAround: true,
  179. pageDots: false
  180. });
  181. oCarousel.find(sItem + ' img').each(function() {
  182. $(this).load(function() {
  183. oCarousel.flickity('resize');
  184. });
  185. });
  186. oCarousel.find(sItem + ' video').each(function() {
  187. this.addEventListener('loadedmetadata', function() {
  188. oCarousel.flickity('resize');
  189. }, true);
  190. });
  191. };
  192. BxTimelineMain.prototype.initFlickity = function(oView) {
  193. var $this = this;
  194. //--- init Flickity for images (may be used in header section)
  195. oView.find('.' + this.sClassItem + ' .' + this.sClassItemImages + '.' + this.sSP + '-ii-gallery').each(function() {
  196. $this.initFlickityImages($(this));
  197. });
  198. //--- init Flickity for videos (may be used in header section)
  199. oView.find('.' + this.sClassItem + ' .' + this.sClassItemVideos + '.' + this.sSP + '-iv-gallery').each(function() {
  200. $this.initFlickityVideos($(this));
  201. });
  202. //--- init Flickity for attachments (images and video in attachments seation)
  203. oView.find('.' + this.sClassItem + ' .' + this.sClassItemAttachments + '.' + this.sSP + '-ia-gallery').each(function() {
  204. $this.initFlickityAttachments($(this));
  205. });
  206. //--- init Flickity for attachments (files in attachments seation) - DISABLED for now
  207. if(this._bScrollForFiles) {
  208. oView.find('.' + this.sClassItem + ' .' + this.sClassItemAttachments + '.' + this.sSP + '-iaf-gallery').each(function() {
  209. $this.initFlickityAttachments($(this));
  210. });
  211. }
  212. };
  213. BxTimelineMain.prototype.initFlickityByItem = function(oItem) {
  214. //--- init Flickity for images (may be used in header section)
  215. var oGalleryImages = $(oItem).find('.' + this.sClassItemImages + '.' + this.sSP + '-ii-gallery');
  216. if(oGalleryImages.length > 0)
  217. this.initFlickityImages(oGalleryImages);
  218. //--- init Flickity for videos (may be used in header section)
  219. var oGalleryVideos = $(oItem).find('.' + this.sClassItemVideos + '.' + this.sSP + '-iv-gallery');
  220. if(oGalleryVideos.length > 0)
  221. this.initFlickityVideos(oGalleryVideos);
  222. //--- init Flickity for attachments (images and video in attachments seation)
  223. var oGalleryAttachments = $(oItem).find('.' + this.sClassItemAttachments + '.' + this.sSP + '-ia-gallery');
  224. if(oGalleryAttachments.length > 0)
  225. this.initFlickityAttachments(oGalleryAttachments);
  226. };
  227. BxTimelineMain.prototype.initTrackerInsertSpace = function(sFormId, iEventId)
  228. {
  229. var $this = this;
  230. var oForm = $('#' + sFormId);
  231. var oTextarea = oForm.find('textarea');
  232. this._oAttachedLinks = [];
  233. if (typeof window.glOnSpaceEnterInEditor === 'undefined')
  234. window.glOnSpaceEnterInEditor = [];
  235. window.glOnSpaceEnterInEditor.push(function(sData, sSelector) {
  236. if(!oTextarea.is(sSelector))
  237. return;
  238. $this.parseContent(oForm, iEventId, sData, true);
  239. });
  240. };
  241. BxTimelineMain.prototype.initTrackerInsertImage = function(sFormId)
  242. {
  243. var $this = this;
  244. var oForm = $('#' + sFormId);
  245. var oTextarea = oForm.find('textarea');
  246. if (typeof window.glOnInsertImageInEditor === 'undefined')
  247. window.glOnInsertImageInEditor = [];
  248. window.glOnInsertImageInEditor.push(function (oFile, sSelector) {
  249. if(!oTextarea.is(sSelector))
  250. return false;
  251. const oFormData = new FormData();
  252. oFormData.append('file', oFile);
  253. oFormData.append('u', $this._sAutoUploader);
  254. oFormData.append('uid', $this._sAutoUploaderId);
  255. fetch($this._sActionsUrl + 'auto_attach_insertion/', {method: "POST", body: oFormData})
  256. .then(response => response.json())
  257. .then(result => {
  258. processJsonData(result)
  259. });
  260. return true;
  261. });
  262. };
  263. BxTimelineMain.prototype.parseContent = function(oForm, iId, sData, bPerformAttach)
  264. {
  265. var oExp, aMatch = null;
  266. oExp = new RegExp(bx_get_regexp('tag'), "ig");
  267. sData = sData.replace(oExp, '');
  268. oExp = new RegExp(bx_get_regexp('mention'), "ig");
  269. sData = sData.replace(oExp, '');
  270. oExp = new RegExp(bx_get_regexp('url'), "ig");
  271. while(aMatch = oExp.exec(sData)) {
  272. var sUrl = aMatch[0].replace(/^(\s|(&nbsp;))+|(\s|(&nbsp;))+$/gm,'');
  273. if(!sUrl.length || this._oAttachedLinks[sUrl] != undefined || (this._iLimitAttachLinks != 0 && Object.keys(this._oAttachedLinks).length >= this._iLimitAttachLinks))
  274. continue;
  275. //--- Mark that 'attach link' process was started.
  276. this._oAttachedLinks[sUrl] = 0;
  277. if(bPerformAttach) {
  278. this.lockForm(oForm);
  279. this.addAttachLink(oForm, iId, sUrl);
  280. }
  281. }
  282. };
  283. BxTimelineMain.prototype.lockForm = function(oForm)
  284. {
  285. if(this.isLockedForm(oForm))
  286. return;
  287. oForm.attr('bx_form_locked', 1).find('input[type="submit"],button[type="submit"]').addClass('bx-btn-disabled');
  288. };
  289. BxTimelineMain.prototype.unlockForm = function(oForm)
  290. {
  291. if(!this.isLockedForm(oForm))
  292. return;
  293. oForm.removeAttr('bx_form_locked').find('input[type="submit"],button[type="submit"]').removeClass('bx-btn-disabled');
  294. };
  295. BxTimelineMain.prototype.isLockedForm = function(oForm)
  296. {
  297. return oForm.attr('bx_form_locked') == 1;
  298. };
  299. BxTimelineMain.prototype.addAttachLink = function(oElement, iId, sUrl)
  300. {
  301. if(!sUrl || (this._iLimitAttachLinks != 0 && Object.keys(this._oAttachedLinks).length > this._iLimitAttachLinks))
  302. return;
  303. var $this = this;
  304. var oData = this._getDefaultData();
  305. oData['url'] = sUrl;
  306. if(iId != undefined)
  307. oData['event_id'] = iId;
  308. jQuery.post (
  309. this._sActionsUrl + 'add_attach_link/',
  310. oData,
  311. function(oData) {
  312. var iEventId = 0;
  313. if(oData && oData.event_id != undefined)
  314. iEventId = parseInt(oData.event_id);
  315. if(!oData.id || !oData.item || !$.trim(oData.item).length){
  316. $this.unlockForm($('#' + $this._aHtmlIds['attach_link_form_field'] + iEventId).parents('form:first'));
  317. return;
  318. }
  319. //--- Mark that 'attach link' process was finished.
  320. $this._oAttachedLinks[sUrl] = oData.id;
  321. var oItem = $(oData.item).hide();
  322. $('#' + $this._aHtmlIds['attach_link_form_field'] + iEventId).prepend(oItem).find('#' + oItem.attr('id')).bx_anim('show', $this._sAnimationEffect, $this._sAnimationSpeed, function() {
  323. $(this).bxProcessHtml();
  324. });
  325. $this.unlockForm($('#' + $this._aHtmlIds['attach_link_form_field'] + iEventId).parents('form:first'));
  326. },
  327. 'json'
  328. );
  329. };
  330. BxTimelineMain.prototype.onFindOverflow = function(oElement) {
  331. $(oElement).after($(oElement).parents('.' + this.sClassView + ':first').find('.' + this.sSP + '-content-show-more:hidden:first').clone().show());
  332. };
  333. BxTimelineMain.prototype.loadingInButton = function(e, bShow) {
  334. if($(e).length)
  335. bx_loading_btn($(e), bShow);
  336. else
  337. bx_loading($('body'), bShow);
  338. };
  339. BxTimelineMain.prototype.loadingInItem = function(e, bShow) {
  340. var oParent = $('body');
  341. if($(e).length)
  342. oParent = !$(e).hasClass(this.sClassItem) ? $(e).parents('.' + this.sClassItem + ':first') : $(e);
  343. bx_loading(oParent.find('.' + this.sClassItemCnt), bShow);
  344. };
  345. BxTimelineMain.prototype.loadingInBlock = function(e, bShow) {
  346. var oParent = $(e).length ? $(e).parents('.bx-db-container:first') : $('body');
  347. bx_loading(oParent, bShow);
  348. };
  349. BxTimelineMain.prototype.loadingInBlockHeaderCustom = function(e, bShow) {
  350. var oParent = $(e).length ? $(e).parents('.bx-tl-v-header:first') : $('body');
  351. bx_loading(oParent, bShow);
  352. };
  353. BxTimelineMain.prototype.loadingInPopup = function(e, bShow) {
  354. var oParent = $(e).length ? $(e).parents('.bx-popup-content:first') : $('body');
  355. bx_loading(oParent, bShow);
  356. };
  357. BxTimelineMain.prototype.loadingIn = function(e, bShow) {
  358. var oElement = $(e);
  359. var bElement = oElement.length > 0;
  360. if(bElement && oElement.hasClass('bx-btn'))
  361. this.loadingInButton(e, bShow);
  362. else if(bElement && (oElement.hasClass(this.sClassItem) || oElement.parents('.' + this.sClassItem + ':first').length > 0))
  363. this.loadingInItem(e, bShow);
  364. else if(bElement && oElement.parents('.bx-popup-content:first').length > 0)
  365. this.loadingInPopup(e, bShow);
  366. else if(bElement && oElement.parents('.bx-db-container:first').length > 0)
  367. this.loadingInBlock(e, bShow);
  368. else if(bElement && oElement.parents('.bx-tl-v-header:first').length > 0)
  369. this.loadingInBlockHeaderCustom(e, bShow);
  370. else
  371. bx_loading($('body'), bShow);
  372. };
  373. BxTimelineMain.prototype._loading = function(e, bShow) {
  374. var oParent = $(e).length ? $(e) : $('body');
  375. bx_loading(oParent, bShow);
  376. };
  377. BxTimelineMain.prototype._getViewObject = function(oElement) {
  378. oElement = $(oElement);
  379. var oView = oElement;
  380. if(oView.hasClass(this.sClassView))
  381. return oView;
  382. oView = oElement.parents('.' + this.sClassView + ':first');
  383. if(oView.hasClass(this.sClassView))
  384. return oView;
  385. oView = oElement.parents('.bx-page-block-container:first').find('.' + this.sClassView + ':first');
  386. if(oView.hasClass(this.sClassView))
  387. return oView;
  388. return null;
  389. };
  390. BxTimelineMain.prototype._getView = function(oElement) {
  391. var oView = this._getViewObject(oElement);
  392. if(!oView || oView.length == 0)
  393. return '';
  394. if(oView.hasClass(this.sClassView + '-item'))
  395. return 'item';
  396. if(oView.hasClass(this.sClassView + '-timeline'))
  397. return 'timeline';
  398. if(oView.hasClass(this.sClassView + '-outline'))
  399. return 'outline';
  400. if(oView.hasClass(this.sClassView + '-search'))
  401. return 'search';
  402. return '';
  403. };
  404. BxTimelineMain.prototype._getName = function(oData, oRules)
  405. {
  406. oRules = jQuery.extend({}, oRules);
  407. var bWithView = oRules.with_view === undefined || oRules.with_view === true;
  408. var bWithType = oRules.with_type === undefined || oRules.with_type === true;
  409. var bWithOwner = oRules.with_owner !== undefined && oRules.with_owner === true;
  410. var sGlue = oRules.glue !== undefined && oRules.glue ? oRules.glue : '_';
  411. var aAddons = [];
  412. if(oData['name'])
  413. aAddons.push(oData['name']);
  414. else {
  415. if(bWithView && oData['view'])
  416. aAddons.push(oData['view']);
  417. if(bWithType && oData['type'])
  418. aAddons.push(oData['type']);
  419. }
  420. if(bWithOwner)
  421. aAddons.push(this._iOwnerId);
  422. return aAddons.length > 0 ? aAddons.join(sGlue) : '';
  423. };
  424. BxTimelineMain.prototype._getHtmlId = function(sKey, oData, oRules)
  425. {
  426. oRules = jQuery.extend({}, oRules);
  427. var bWhole = oRules.whole === undefined || oRules.whole === true;
  428. var bHash = oRules.hash === undefined || oRules.hash === true;
  429. var sGlue = oRules.glue !== undefined && oRules.glue ? oRules.glue : '_';
  430. var sHtmlId = this.sId + sGlue + sKey + sGlue + this._getName(oData, oRules) + (!bWhole ? sGlue : '');
  431. if(!bHash)
  432. sHtmlId = sHtmlId.substr(1);
  433. return sHtmlId.replace(new RegExp(sGlue, 'g'), '-');
  434. };
  435. BxTimelineMain.prototype._getDefaultData = function() {
  436. var oDate = new Date();
  437. return jQuery.extend({}, this._oRequestParams, {_t:oDate.getTime()});
  438. };
  439. BxTimelineMain.prototype._getPost = function(oView, iId, aParams) {
  440. var $this = this;
  441. var oData = this._getDefaultData();
  442. oData = jQuery.extend({}, oData, {js_object: this._sObjName, id: iId}, aParams != undefined ? aParams : {});
  443. this.loadingInBlock(oView, true);
  444. jQuery.post (
  445. this._sActionsUrl + 'get_post/',
  446. oData,
  447. function(oData) {
  448. $this.loadingInBlock(oView, false);
  449. processJsonData(oData);
  450. },
  451. 'json'
  452. );
  453. };
  454. /**
  455. * Allows to attache callback functions on Get Post event
  456. * @param oView
  457. * @param iId
  458. * @param aParams
  459. */
  460. BxTimelineMain.prototype.onGetPost = function(oView, iId, aParams) {
  461. const mixedCallback = this.aGetPostCallbacks;
  462. if (!mixedCallback)
  463. return;
  464. if (typeof mixedCallback === 'function')
  465. mixedCallback(oView, iId, aParams);
  466. if (Array.isArray(mixedCallback)){
  467. for (let i in mixedCallback) {
  468. if (typeof mixedCallback[i] === 'function')
  469. mixedCallback[i](oView, iId, aParams);
  470. }
  471. }
  472. }