PageSourceSearch

https://camberwellsharks.com.au/wp-content/plugins/teamstuff-calen…/public/js/teamstuff-calendar.js?ver=1.1.0

js camberwellsharks.com.au collected 2026-10-08 20:52:15 UTC 14,069 bytes, 402 lines download raw bytes

1(function( $, globals ) {
2	'use strict';
3
4  function TeamstuffCalendar(widget) {
5  	this.widget = widget;
6  	this.template = widget.children('.ts-calendar-row.hidden').clone().removeClass('hidden'); // create a visible copy of the row template for use later
7  	this.eventRows = widget.children('#ts-calendar-event-rows');
8  	this.locale = widget.children('#ts-calendar-locale').val();
9		this.url = widget.children('#ts-calendar-rest-url').val();
10  	this.teamName = widget.find("#ts-calendar-team-name").text();
11  	this.cache = {};
12  	this.cacheRefreshMs = 1000*60; // data is valid for 1 minute
13  }
14
15  TeamstuffCalendar.getEventState = function(startTime, nowTime, durationMs) {
16  	var state = "future";
17
18		var startTimeMs = startTime.valueOf();
19		var nowTimeMs = nowTime.valueOf();
20		var endTimeMs = startTimeMs + durationMs;
21  	if(nowTimeMs >= startTimeMs) {
22  	 if(nowTimeMs > endTimeMs) {
23  		 state = "past";
24  	 } else {
25  		 state = "current";
26  	 }
27  	}
28  	return state;
29  };
30
31  TeamstuffCalendar.createRow = function(template, rowData, locale, now) {
32  	var row = template.clone();
33
34  	if(rowData.bye) {
35  		// Add styling for a bye
36  		row.addClass('ts-calendar-row-bye');
37
38  		// Remove relevant contents
39  		row.find("#ts-calendar-time").parent().html('BYE');
40  		row.find("#ts-calendar-team-us").parent().html(rowData.team.name);
41  		row.find("#ts-calendar-location").parent().html('');
42  		row.find("#ts-calendar-score-win").parent().html('');
43  	}
44  	else {
45
46			// get times into UTC
47	  	var time = moment(rowData.whistle_time).utc();
48			var now = moment(now).utc();
49
50  		var eventState = TeamstuffCalendar.getEventState(time, now, rowData.duration_in_seconds * 1000);
51			var showTime = true;
52  		switch(eventState) {
53  			case "future":
54  				row.addClass('ts-calendar-row-future');
55  				break;
56  			case "current":
57					row.addClass('ts-calendar-row-current');
58					row.find("#ts-calendar-time-now").removeClass('hidden');
59					// remove the elements related to time
60					row.find("#ts-calendar-time").remove();
61					row.find("#ts-calendar-time-suffix").remove();
62					row.find("#ts-calendar-time-user").remove();
63					row.find("#ts-calendar-time-suffix-user").remove();
64  				break;
65  			case "past":
66  				row.addClass('ts-calendar-row-past');
67  				break;
68  		}
69
70			// game time in the timezone it's being played in (so display as UTC)
71			var timeStringSplit = time.format('LT').split(' ');
72			row.find("#ts-calendar-time").text(timeStringSplit[0]);
73			if(timeStringSplit.length > 1) {
74				row.find('#ts-calendar-time-suffix').text(timeStringSplit[1]);
75			}
76			row.find("#ts-calendar-date").text(time.format('D MMM	YYYY'));
77
78			// game time in the viewer's timezone -- if it's different
79			var userOffset = moment().utcOffset();
80			var gameOffset = rowData.timezone_offset / 60;
81			if(gameOffset != userOffset && eventState == "future") {
82				row.find('.ts-calendar-time-user-container').removeClass('hidden');
83
84				var effectiveOffset = userOffset - gameOffset;
85				var userTime = time.clone().utcOffset(effectiveOffset);
86
87				timeStringSplit = userTime.format('LT').split(' ');
88				row.find("#ts-calendar-time-user").text(timeStringSplit[0]);
89  			if(timeStringSplit.length > 1) {
90  				row.find('#ts-calendar-time-suffix-user').text(timeStringSplit[1]);
91  			}
92
93				// display the date as well if it is different
94				if(userTime.day() != time.day()) {
95					row.find("#ts-calendar-date-user").text(userTime.format('D MMM	YYYY'));
96				}
97			}
98
99  		// apply teams
100  		row.find("#ts-calendar-team-us").text(rowData.team.name);
101  		row.find("#ts-calendar-team-them").text(rowData.opposition);
102
103  		// apply location and home/away
104  		var locationText = rowData.location_name;
105  		if(locationText == null || locationText.length < 1) locationText = rowData.address;
106
107  		row.find("#ts-calendar-location").text(locationText);
108  		if(rowData.away_game) {
109  			row.find('#ts-calendar-homeaway').addClass('ts-calendar-away').text('A');
110  		} else {
111  			row.find('#ts-calendar-homeaway').addClass('ts-calendar-home').text('H');
112  		}
113
114  		// apply map link
115  		var mapLink = encodeURIComponent(rowData.address) + "/@" + encodeURIComponent(rowData.location_data);
116  		row.find('#ts-calendar-maplink').click(function(e) {
117				window.open("https://www.google.com.au/maps/place/" + mapLink);
118				e.preventDefault();
119			});
120
121  		// apply scores
122  		if(row.find('#ts-calendar-score-us').length > 0) { // if displaying scores is enabled in the plugin
123  			if(rowData.our_score === null || rowData.their_score === null) {
124  				row.find("#ts-calendar-score-us").parent().html(""); // clear the score column (to remove the colon)
125  			} else {
126  				row.find("#ts-calendar-score-us").text(rowData.our_score);
127  				row.find("#ts-calendar-score-them").text(rowData.their_score);
128  			}
129  		}
130
131  		// apply win indicator if relevant
132  		if(rowData.result == 'win') {
133  			row.find('#ts-calendar-score-win').removeClass('hidden');
134  		}
135  	}
136
137  	return row;
138  };
139
140  TeamstuffCalendar.getCacheKey = function(date, direction) {
141  	return moment(date).utc().format('DD/MM/YY') + direction;
142  };
143
144  TeamstuffCalendar.prototype.getTeamGames = function(startDate, endDate, teamName) {
145  	// perform request to load the data
146  	var params = { startDate: '0000-01-01' }; // workaround because endpoint without either parameters only gives future games
147  	if(startDate) {
148      startDate = moment(startDate);
149  		params['startDate'] = startDate.format('YYYY-MM-DD');
150  	}
151  	if(endDate) {
152      endDate = moment(endDate);
153  		params['endDate'] = endDate.format('YYYY-MM-DD');
154  	}
155  	var req = $.getJSON(this.url + '/events-range', params)
156  		.done(function(data) {
157  			// filter the games by the team
158  			data.games = data.games.filter(function(game) {
159  				return game.team.name == teamName;
160  			});
161
162  			// sort the games
163  			data.games.sort(function(a, b) {
164  				if(a.whistle_time == "") { return 1; }
165  				if(b.whistle_time == "") { return -1; }
166  				return Date.parse(a.whistle_time) - Date.parse(b.whistle_time);
167  			});
168  		});
169
170  	return req;
171  };
172
173  TeamstuffCalendar.prototype.getDateGames = function(date, direction) {
174  	// check the cache
175  	var cacheKey = TeamstuffCalendar.getCacheKey(date, direction);
176  	var cacheEntry = this.cache[cacheKey];
177  	var promise;
178  	if(cacheEntry && cacheEntry.retrieved + this.cacheRefreshMs > Date.now()) {
179  		// wrap cache data in a promise
180  		var deferred = $.Deferred()
181  		deferred.resolve(cacheEntry.data);
182  		promise = deferred.promise();
183  	} else {
184  		var self = this;
185  		// trigger request to retrieve data from API
186			var params = { date: moment(date).format('YYYY-MM-DD') };
187			if(direction) {
188				params.direction = direction;
189			}
190  		promise = jQuery.getJSON(this.url + '/events', params)
191  			.done(function(data) {
192  				// sort the games
193  				data.games.sort(function(a, b) {
194  					if(a.whistle_time == "") { return 1; }
195  					if(b.whistle_time == "") { return -1; }
196  					return Date.parse(a.whistle_time) - Date.parse(b.whistle_time);
197  				});
198
199  				// update the cache
200  				self.cache[cacheKey] = { retrieved: Date.now(), data: data };
201  			});
202  	}
203
204  	return promise;
205  };
206
207  TeamstuffCalendar.prototype.loadTeam = function(startDate, endDate) {
208  	// based on startDate and endDate, make one of the date range labels visible
209  	var dateRange;
210  	if(startDate && endDate) {
211  		dateRange = this.widget.find("#ts-calendar-date-range");
212  	} else if(startDate) {
213  		dateRange = this.widget.find("#ts-calendar-date-range-from");
214  	} else if(endDate) {
215  		dateRange = this.widget.find("#ts-calendar-date-range-to");
216  	} else {
217  		dateRange = this.widget.find("#ts-calendar-date-range-all");
218  	}
219  	dateRange.removeClass('hidden');
220
221  	// set the date range indicators
222  	if(startDate) {
223  		startDate = moment(startDate).utc().locale(this.locale);
224  		dateRange.find("#ts-calendar-date-from").text(startDate.format('D MMM YYYY'));
225  	}
226  	if(endDate) {
227  		endDate = moment(endDate).utc().locale(this.locale);
228  		dateRange.find("#ts-calendar-date-to").text(endDate.format('D MMM YYYY'));
229  	}
230
231  	// perform request to load the data
232  	var self = this;
233  	var req = this.getTeamGames(startDate, endDate, this.teamName)
234  		.done(function(data) {
235  			// hide the loading row
236  			self.widget.children('#ts-calendar-loading-row').addClass('hidden');
237
238  			// clear the old rows
239  			self.eventRows.empty();
240  			self.eventRows.removeClass('hidden');
241
242  			// update views with event data or display empty row
243  			if(data.games.length == 0) {
244  				self.widget.children('#ts-calendar-empty-row').removeClass('hidden');
245  			} else {
246  				self.populateRows(data);
247  			}
248  		})
249  		.fail(function(err) {
250  			self.widget.children('#ts-calendar-error-row').removeClass('hidden');
251  		})
252  		.always(function() {
253  			self.widget.children('#ts-calendar-loading-row').addClass('hidden');
254  		});
255  }
256
257  TeamstuffCalendar.prototype.preloadDate = function(date) {
258  	// create container for preload requests if need be
259  	this.requestPreload = this.requestPreload || {};
260
261  	var directions = [ 'next', 'previous'];
262  	var self = this;
263  	$.each(directions, function(i, direction) {
264  		// if we have a current preloading request for this direction, abort it
265  		if(self.requestPreload[direction] && self.requestPreload[direction].abort)
266  			self.requestPreload[direction].abort();
267
268  		self.requestPreload[direction] = self.getDateGames(date, direction)
269  			.always(function() {
270  				self.requestPreload[direction] = null;
271  			})
272  			.done(function(data) {
273  				// if we preload but get no games (no more events in that direction)
274  				if(data.games.length == 0) {
275  					// disable the appropriate arrow
276  					if(direction == 'previous')
277  						self.widget.find('#ts-calendar-date-prev').addClass('hidden');
278  					else if(direction == 'next')
279  						self.widget.find('#ts-calendar-date-next').addClass('hidden');
280  				}
281  			});
282  	});
283  };
284
285  TeamstuffCalendar.prototype.changeDate = function(currDate, direction) {
286  	// if a request exists (that is actually a request -- has .abort), abort it
287  	if(this.request && this.request.abort)
288  		this.request.abort();
289
290  	// hide the old events
291  	this.eventRows.addClass('hidden');
292
293  	// hide the error row
294  	this.widget.children('#ts-calendar-error-row').addClass('hidden');
295  	// hide the empty row
296  	this.widget.children('#ts-calendar-empty-row').addClass('hidden');
297
298  	// display the loading row and the direction buttons
299  	this.widget.children('#ts-calendar-loading-row').removeClass('hidden');
300  	this.widget.find('#ts-calendar-date-prev').removeClass('hidden');
301  	this.widget.find('#ts-calendar-date-next').removeClass('hidden');
302
303  	var self = this;
304  	this.request = this.getDateGames(currDate, direction)
305  		.fail(function(err) {
306  			// display the error row
307  			self.widget.children('#ts-calendar-error-row').removeClass('hidden');
308  		})
309  		.always(function() {
310  			self.widget.children('#ts-calendar-loading-row').addClass('hidden');
311  			self.request = null;
312  		})
313  		.done(function(data) {
314
315  			if(!data || !data.games) {
316  				// display the error row
317  				self.widget.children('#ts-calendar-error-row').removeClass('hidden');
318  			} else {
319
320  				// make sure the navigation arrows are visible
321  				self.widget.find('#ts-calendar-date-prev').removeClass('hidden');
322  				self.widget.find('#ts-calendar-date-next').removeClass('hidden');
323
324  				// extract the date from the data (data used by the calendar is UTC)
325  				var newDate = moment(data.current_date).utc().locale(self.locale);
326  				self.date = newDate;
327
328  				// trigger fetching of previous/next from this new date
329  				self.preloadDate(newDate);
330
331  				// update the header date and year
332  				self.widget.find('#ts-calendar-date').text(newDate.format('dddd D MMMM'));
333  				self.widget.find('#ts-calendar-year').text(newDate.format('YYYY'));
334
335  				// if we tried to change date but got no more games (no more events)
336  				if(direction != null && data.games.length == 0) {
337  					// disable the appropriate arrow
338  					if(direction == 'previous')
339  						self.widget.find('#ts-calendar-date-prev').addClass('hidden');
340  					else if(direction == 'next')
341  						self.widget.find('#ts-calendar-date-next').addClass('hidden');
342
343  					// re-display the existing events for this date
344  					self.eventRows.removeClass('hidden');
345  				} else {
346  					// clear the old rows
347  					self.eventRows.empty();
348  					self.eventRows.removeClass('hidden');
349
350  					// update views with event data or display empty row
351  					if(data.games.length == 0) {
352  						self.widget.children('#ts-calendar-empty-row').removeClass('hidden');
353  					} else {
354  						self.populateRows(data);
355  					}
356  				}
357  			}
358  		});
359  };
360
361  TeamstuffCalendar.prevDate = function(e) {
362  	this.changeDate(this.date, 'previous');
363		e.preventDefault();
364  };
365
366  TeamstuffCalendar.nextDate = function(e) {
367  	this.changeDate(this.date, 'next');
368		e.preventDefault();
369  };
370
371  TeamstuffCalendar.prototype.populateRows = function(events) {
372  	var self = this;
373  	var now = Date.now()
374  	$.each(events.games, function() {
375  		var newRow = TeamstuffCalendar.createRow(self.template, this, self.locale, now);
376  		self.eventRows.append(newRow);
377  	});
378  };
379
380  TeamstuffCalendar.initialise = function(widget) {
381  	var ts = new TeamstuffCalendar(widget);
382
383  	if(ts.teamName != "") {
384  		var fromDate = moment(widget.find("#ts-calendar-param-date-from").val());
385  		var toDate = moment(widget.find("#ts-calendar-param-date-to").val());
386  		ts.loadTeam(
387  			fromDate.isValid() ? fromDate : null,
388  			toDate.isValid() ? toDate : null
389  		);
390  	} else {
391  		// attach click handlers to prev/next
392  		widget.find('#ts-calendar-date-prev').click(TeamstuffCalendar.prevDate.bind(ts));
393  		widget.find('#ts-calendar-date-next').click(TeamstuffCalendar.nextDate.bind(ts));
394
395  		// initialise calendar with the current date
396  		var now = new Date();
397  		ts.changeDate(now);
398  	}
399  };
400
401  globals.TeamstuffCalendar = TeamstuffCalendar;
402})( jQuery, function() {return this;}.call() );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.