www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

pticlic.js (14561B)


      1 // ==== Code métier général
      2 function init(fn) {
      3 	$(window).queue('init', function(next) {fn(); next();});
      4 }
      5 
      6 $.ajaj = function(url, data, dfd, retryCheck, callback) {
      7 	dfd = dfd || $.Deferred();
      8 	var user = '' + UI().getPreference("user");
      9 	var passwd = '' + UI().getPreference("passwd");
     10 	user = runstate.user || user;
     11 	passwd = runstate.passwd || passwd;
     12 	if (user && passwd) {
     13 		if (!data.user) data.user = user;
     14 		if (!data.passwd) data.passwd = passwd;
     15 	}
     16 	var fromScreen = state.screen;
     17 	if (callback) return $.getJSON(url, data, callback);
     18 	return $.getJSON(url, data, function(data) {
     19 		if (data.isError) {
     20 			isConnected(false);
     21 			dfd.reject(data);
     22 			message("Erreur", data.msg);
     23 			if ((data.error == 10 || data.error == 3) && state.screen == fromScreen && (!retryCheck || retryCheck())) {
     24 				$.screen('connection').trigger('goto');
     25 			} else if (runstate.screen == fromScreen) {
     26 				$.screen('frontpage').trigger('goto');
     27 			}
     28 		} else {
     29 			isConnected(true);
     30 			dfd.resolve(data);
     31 		}
     32 	}).fail(function(data) {
     33 		isConnected(false);
     34 		dfd.reject(data);
     35 		$("#frontpage").trigger('goto');
     36 		message("Erreur", "Une erreur est survenue, veuillez nous en excuser.");
     37 	});
     38 };
     39 
     40 $(function() {
     41 	var lastWinSize = $(window).wh();
     42 	$(window).dequeue('init');
     43 	$(window).resize($.debounce(function resizeJSS() {
     44 		if (lastWinSize.width != $(window).width() || lastWinSize.height != $(window).height()) {
     45 			lastWinSize = $(window).wh();
     46 			hashchange();
     47 		}
     48 	}));
     49 	$(window).hashchange(hashchange);
     50 	hashchange();
     51 	runstate.loaded = true;
     52 });
     53 
     54 // ==== URL persistantes et passage d'un écran à l'autre
     55 var runstate = { screen: 'none' };
     56 var state = decodeHash("");
     57 var oldstate = decodeHash("");
     58 
     59 init(function() {
     60 	$('.screen').live('goto', function() {
     61 		var screen = this.id;
     62 		if (screen == '') return;
     63 		// Afficher "Chargement…"
     64 		/* location.hash = "#" + screen; */
     65 		$.screen(runstate.screen).trigger('leave').hide();
     66 		runstate.screen = screen;
     67 		UI().setScreen(screen);
     68 		$(this).trigger('pre-enter');
     69 	});
     70 	
     71 	$('.screen').live('pre-enter', function() {
     72 		$(this).trigger('enter');
     73 	});
     74 	
     75 	$('.screen').live('enter', function() {
     76 		$(this).show();
     77 		$(this).trigger('update');
     78 	});
     79 
     80 	$('.screen').live('update', function() {
     81 		jss();
     82 	});
     83 	
     84 	$('.screen').live('leave', function() {
     85 		$(this).hide();
     86 	});
     87 });
     88 
     89 $.screen = function (name) {
     90 	return $(document.getElementById(name)).filter('.screen');
     91 }
     92 
     93 function hashchange() {
     94 	oldstate = state;
     95 	state = decodeHash(location.hash);
     96 	$.screen(state.screen).trigger(state.screen != runstate.screen ? "goto" : "update");
     97 }
     98 
     99 // ==== Interface Android™
    100 function UI () {
    101 	if (typeof(PtiClicAndroid) != "undefined") {
    102 		return PtiClicAndroid;
    103 	} else {
    104 		return {
    105 			isAndroid: function() { return false; },
    106 			setPreference: function() {},
    107 			getPreference: function() {return "";},
    108 			setScreen: function() {}
    109 		};
    110 	}
    111 }
    112 
    113 // ==== Nouveau jss
    114 function jss() {
    115 	var iconSize = 0;
    116 	if (jss.running) return;
    117 	jss.running = true;
    118 	$('body').removeClass().addClass(runstate.prefs.theme);
    119 	if ($("#splash img").is(':visible')) {
    120 		var ratio = Math.min($('#splash').width() / 320, $('#splash').height() / 480);
    121 		$('#splash.screen img')
    122 			.wh(320 * ratio, 480 * ratio);
    123 	}
    124 	if ($('#game.screen').is(':visible')) {
    125 		var rb = $('#game.screen .relationBox');
    126 		var screenHeight = $('#game.screen').height();
    127 		var nbRb = rb.size();
    128 		
    129 		var calcFreeSpace = function (iconSize) {
    130 			var rbHeight = (iconSize || 20) + 2*({72:3,48:2,36:1,0:1})[iconSize] + Math.ceil(2*10/72*iconSize); // = iconSize + border + padding
    131 			return screenHeight - rbHeight*nbRb;
    132 		};
    133 		$.each([72,48,36,0], function(i,is) {
    134 			iconSize = is;
    135 			return (calcFreeSpace(is) - (nbRb+1)*5 < Math.max(/*Hauteur min du header :*/70, screenHeight*0.2));
    136 		});
    137 		var freeSpace = calcFreeSpace(iconSize);
    138 		var headerHeight = Math.min(screenHeight * 0.35, freeSpace - (nbRb+1)*5);
    139 		var interRbSpace = (freeSpace - headerHeight) / (nbRb+1);
    140 
    141 		$('#game .header').height(headerHeight);
    142 		$('#game .relations').height(screenHeight - headerHeight).css('top', headerHeight);
    143 		(rb)
    144 			.css({
    145 				borderWidth: ({72:3,48:2,36:1,0:1})[iconSize],
    146 				padding: 10/72*iconSize,
    147 				borderRadius: 20/72*iconSize,
    148 				marginTop: interRbSpace
    149 			})
    150 			.height(iconSize)
    151 			.find('img.icon').wh(iconSize).css({paddingRight: 10/72*iconSize});
    152 	}
    153 	$('#frontpage:visible a.fpButton').$each(function(i,e) {
    154 		var img = e.find('img');
    155 		var size = Math.min($('#frontpage').width() * 0.3, $('#frontpage').height() * 0.32 * 0.5);
    156 		if (size >= 36) iconSize = 36;
    157 		if (size >= 48) iconSize = 48;
    158 		if (size >= 72) iconSize = 72;
    159 		e.find('.icon-label').height($('#frontpage').height() * 0.32 * 0.3);
    160 		img.css('padding-top', $('#frontpage').height() * 0.32 * 0.06);
    161 	});
    162 	$('.fitFont:visible').$each(function(i,e) { e.fitFont(); });
    163 	$('.fitFontGroup:visible').each(function(i,e) { $(e).find('.subFitFont').fitFont(); });
    164 	$('.center:visible').$each(function(i,e) { e.center(e.parent().center()); });
    165 	$('img.icon:visible').$each(function(i,e){ if(e.data('image') && iconSize) e.attr('src', 'ressources/img/'+iconSize+'/'+e.data('image')+'.png'); e.wh(iconSize); });
    166 	if ($('#game.screen').is(':visible')) {
    167 		$('#game.screen').trigger('update');
    168 	}
    169 	jss.running = false;
    170 }
    171 
    172 // ==== Bulle pour les messages
    173 init(function() {
    174 	$('#message').hide();
    175 });
    176 
    177 function message(title, msg) {
    178 	$('#message')
    179 		.qCss('opacity',0).qShow()
    180 		.queue(function(next){ $('#message .text').text(msg || 'Une erreur est survenue, veuillez nous en excuser.'); jss(); next(); })
    181 		.fadeTo(700, 0.9).delay(5000).fadeOut(700);
    182 }
    183 
    184 // ==== Écran splash
    185 init(function() {
    186 	$('#splash.screen').click(function(){ $('#frontpage').trigger('goto'); return false; });
    187 	window.setTimeout(function() {
    188 		if (runstate.screen == 'splash') $('#frontpage').trigger('goto');
    189 	}, 5000);
    190 	$('#splash.screen').bind('goto', function(e){
    191 		if (runstate.loaded) {
    192 			$('#frontpage').trigger('goto');
    193 			return false;
    194 		}
    195 	});
    196 	
    197 });
    198 
    199 // ==== Écran d'accueil
    200 init(function() {
    201 	$.screen('frontpage').bind('enter', function() {
    202 		window.document.title = "PtiClic pre-alpha 0.2";
    203 		if (runstate.pendingSetPrefs) runstate.pendingSetPrefs();
    204 	});
    205 	$.screen('frontpage').bind('update', function() {
    206 		$('.dis-connect').text(isConnected() ? "Déconnexion" : "Connexion");
    207 	});
    208 	if (UI().isAndroid()) $('#back2site').hide();
    209 	$('#frontpage a.fpButton').$each(function(i,e) {
    210 		e.find('img.icon').data('image', e.attr('href').substring(1));
    211 	});
    212 });
    213 
    214 // ==== Écran connexion
    215 function isConnected(arg) {
    216 	if (typeof arg == 'undefined') {
    217 		return !!runstate.connected;
    218 	} else {
    219 		runstate.connected = !!arg;
    220 		if (runstate.screen == 'frontpage') $.screen('frontpage').trigger('update');
    221 	}
    222 }
    223 
    224 init(function() {
    225 	$('#connection.screen form').submit(function() {
    226 		runstate.user = $('#user').val();
    227 		runstate.passwd = $('#passwd').val();
    228 		UI().setPreference('user', runstate.user);
    229 		UI().setPreference('passwd', runstate.passwd);
    230 		if (!runstate.pendingSetPrefs) {
    231 			runstate.pendingGetPrefs();
    232 		}
    233 		if (state.screen == 'game') {
    234 			$('#game').trigger('goto');
    235 		} else if (state.screen == 'score') {
    236 			$('#score').trigger('goto');
    237 		} else if (state.screen == "frontpage") {
    238 			$.screen('frontpage').trigger('goto'); // Ne devrait jamais être appellé.
    239 		} else {
    240 			location.hash = "#frontpage";
    241 		}
    242 		return false;
    243 	});
    244 
    245 	$('#connection.screen .back').click(function() {
    246 		if (runstate.pendingSetPrefs)
    247 			runstate.cancelPendingSetPrefs();
    248 		if (state.screen == 'frontpage') $.screen('frontpage').trigger('goto');
    249 	});
    250 	
    251 	$('a[href="#connection"]').click(function() {
    252 		if (isConnected()) {
    253 			UI().setPreference("user", '');
    254 			UI().setPreference("passwd", '');
    255 			runstate.user = '';
    256 			runstate.passwd = '';
    257 			$.ajaj("server.php?callback=?", { action: 9 }, null, null, function(data) {
    258 				isConnected(false);
    259 				message("Succès", "Vous êtes déconnecté.");
    260 				loadPrefs({theme:"green"});
    261 			});
    262 			return false;
    263 		}
    264 	});
    265 });
    266 
    267 // ==== Écran game
    268 runstate.gameCache = new Cache(function getGame(k, dfd) {
    269 	$.ajaj("getGame.php?callback=?", {pgid:k}, dfd, function() { return state.pgid == k; });
    270 });
    271 
    272 init(function() {
    273 	var game = $('#game.screen');
    274 	$('a[href="#game"]').click(function() {
    275 		location.hash = '#game/' + $.now();
    276 		return false;
    277 	});
    278 
    279 	game.bind('pre-enter', function() {
    280 		runstate.gameCache.get(state.pgid).done(function(data) {
    281 			runstate.game = data;
    282 			game.trigger('enter');
    283 		});
    284 		return false;
    285 	});
    286 
    287 	game.bind('enter', function() {
    288 		$("#game .relations").empty();
    289 		var game = runstate.game;
    290 		runstate.relationBox = [];
    291 		$.each(game.relations, function(i, relation) {
    292 			runstate.relationBox[relation.id] = $('#templates .relationBox')
    293 				.clone()
    294 				.find(".text").html(relation.name.replace(/%(m[cn])/g, '<span class="$1"/>')).end()
    295 				.find(".icon").data("image",relation.id).end()
    296 				.click(function(e) {
    297 					var h = appendAnswer(state, relation.id);
    298 					if (state.answers.length + 1 >= runstate.game.cloud.length) {
    299 						location.hash = encodeHash($.extend(h, {screen:'score'}));
    300 					} else {
    301 						location.hash = encodeHash(h);
    302 						$(this).addClass("hot");
    303 					}
    304 					return false;
    305 				})
    306 				.appendTo("#game .relations");
    307 		});
    308 		$("#game .mc").text(game.center.name);
    309 	});
    310 
    311 	var updating = false;
    312 	game.bind('update', function() {
    313 		if (updating) return false;
    314 		updating = true;
    315 		if (!runstate.game || state.pgid != runstate.game.pgid) {
    316 			updating = false;
    317 			$('#game').trigger('goto');
    318 			return;
    319 		}
    320 
    321 		window.document.title = "PtiClic "+(state.answers.length + 1)+' / '+runstate.game.cloud.length;
    322 		$('.mn').text(runstate.game.cloud[state.answers.length].name);
    323 		jss();
    324 		
    325 		var isForward = (state.answers.length - oldstate.answers.length) >= 0;
    326 		var rb = runstate.relationBox[(isForward ? state : oldstate).answers[(isForward ? state : oldstate).answers.length - 1]];
    327 
    328 		if (runstate.currentMNCaption && oldstate.screen != 'game')
    329 			runstate.currentMNCaption.remove();
    330 		if (!runstate.currentMNCaption)
    331 			runstate.currentMNCaption = $('<span class="mn-caption"/>').attr('id', Math.random());
    332 		var tmp = runstate.game.cloud[oldstate.answers.length];
    333 		var a = runstate.currentMNCaption.text(tmp ? tmp.name : '…');
    334 		var b = $('<span class="mn-caption"/>').attr('id', Math.random()).text(runstate.game.cloud[state.answers.length].name);
    335 		if (!rb || (isForward && (oldstate.screen != 'game' || state.answers.length == oldstate.answers.length))) {
    336 			isForward = true;
    337 			a.remove();
    338 			a = $();
    339 		}
    340 		if (!isForward) { var c = b; b = a; a = c; }
    341 		runstate.currentMNCaption = isForward ? b : a;
    342 		
    343 		a.zoom(rb, '#mn-caption-box', isForward); // De ou vers la relationBox
    344 		b.zoom('#mn-caption-box', '#mn-caption-box', !isForward); // De ou vers le #mn-caption
    345 		
    346 		window.setTimeout(function() {
    347 			$('.relationBox.hot').addClass('transition-bg').removeClass('hot').delay(700).qRemoveClass('transition-bg');
    348 		}, 0);
    349 		
    350 		updating = false;
    351 		return false;
    352 	});
    353 	
    354 	game.bind('leave', function() {
    355 		if (runstate.currentMNCaption) runstate.currentMNCaption.remove();
    356 	});
    357 });
    358 
    359 // ==== Écran score
    360 runstate.scoreCache = new Cache(function getScore(k, dfd, arg) {
    361 	$.ajaj("server.php?callback=?", {
    362 		action: 1,
    363 		pgid: k,
    364 		answers: arg,
    365 	}, dfd, function() { return state.pgid == k; });
    366 });
    367 
    368 function jAime(aime) {
    369 	$.ajaj('server.php?callback=?', {
    370 		pgid: state.pgid,
    371 		action: 10,
    372 		value: (aime ? 1 : -1)
    373 	});
    374 }
    375 
    376 init(function() {
    377 	var score = $.screen('score');
    378 	score.bind('pre-enter', function() {
    379 		runstate.scoreCache.get(state.pgid, state.answers).done(function(data) {
    380 			runstate.score = data;
    381 			score.trigger('enter');
    382 		});
    383 		return false;
    384 	});
    385 	score.bind('enter', function() {
    386 		var s = runstate.score;
    387 		$("#score .scores").empty();
    388 		$("#score .scoreTotal")
    389 			.text(s.scoreTotal)
    390 			.goodBad(s.minScore*s.scores.length, s.maxScore*s.scores.length, {r:255,g:0,b:0}, {r:0,g:192,b:0});
    391 		$.each(s.scores, function(i,e) {
    392 			$("#templates .scoreLine")
    393 				.clone()
    394 				.find(".word").text(e.name).end()
    395 				.find(".score").text(e.score).goodBad(s.minScore, s.maxScore, {r:255,g:0,b:0}, {r:0,g:192,b:0}).end()
    396 				.appendTo("#score .scores");
    397 		});
    398 	});
    399 	$('#jaime').click(function() { jAime(true); });
    400 	$('#jaimepas').click(function() { jAime(false); });
    401 });
    402 
    403 // ==== Écran Préférences
    404 runstate.prefs = { theme: "green" };
    405 runstate.serverPrefs = $.extend({}, runstate.prefs);
    406 
    407 function loadPrefs(prefs) {
    408 	var previousTheme = runstate.prefs ? runstate.prefs.theme : 'green';
    409 	if (prefs && prefs.theme) {
    410 		isConnected(prefs.connected);
    411 		runstate.prefs = prefs;
    412 		runstate.serverPrefs = $.extend({}, runstate.prefs);
    413 		if (runstate.loaded && previousTheme != runstate.prefs.theme) jss();
    414 	}
    415 }
    416 
    417 function setPrefs(prefs, callback) {
    418 	var dfd = $.Deferred();
    419 	$.ajaj("server.php?callback=?", {
    420 		action: 8,
    421 		key: 'theme',
    422 		value: prefs.theme
    423 	}, dfd);
    424 	return dfd;
    425 }
    426 
    427 runstate.pendingGetPrefs = function() {
    428 	$.ajaj("server.php?callback=?", { action: 7 }, null, null, function(data) {
    429 		if (data.theme) { isConnected(true); message("Succès", "Vous êtes connecté."); loadPrefs(data); }
    430 		if (data.isError) { isConnected(false); message("Erreur", data.msg); }
    431 	});
    432 };
    433 
    434 runstate.cancelPendingSetPrefs = function() {
    435 	runstate.pendingSetPrefs = false;
    436 	message("Préférences", "Les préférences n'ont pas pu être enregistrées.");
    437 };
    438 
    439 init(function() {
    440 	$("#prefs").bind('enter', function() {
    441 		$("#prefs-form input:radio[name=theme]").attr('checked', function(i,val) {
    442 			return $(this).val() == runstate.prefs.theme;
    443 		});
    444 	});
    445 
    446 	var readPrefs = function() {
    447 		var newtheme = $("#prefs form input:radio[name=theme]:checked").eq(0).val();
    448 		if (runstate.prefs.theme != newtheme) {
    449 			runstate.prefs.theme = newtheme;
    450 			jss();
    451 		}
    452 	};
    453 	
    454 	$("#prefs form").submit(function() {
    455 		readPrefs();
    456 		var p = $.extend({}, runstate.prefs);
    457 		runstate.pendingSetPrefs = function() {
    458 			setPrefs(p)
    459 				.fail(function(data) {
    460 					if (!data || (data.error != 10 && data.error != 3)) {
    461 						message("Erreur", data.msg);
    462 						runstate.cancelPendingSetPrefs();
    463 					}
    464 				})
    465 				.done(function(data) {
    466 					runstate.pendingSetPrefs = false;
    467 					loadPrefs(data);
    468 					message("Préférences", "Les préférences ont été enregistrées.");
    469 				});
    470 		};
    471 		location.href = "#frontpage";
    472 		return false;
    473 	});
    474 	$("#prefs form").bind('reset', function() {
    475 		runstate.prefs = $.extend({}, runstate.serverPrefs);
    476 		location.hash = "#frontpage";
    477 	});
    478 	$("#prefs form input:radio[name=theme]").bind('change click', readPrefs);
    479 });