From 24e2bbde64529aebd4c06dde406fc26f17d29007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ca=C3=B1as=20Vargas?= Date: Wed, 22 May 2019 09:36:18 +0200 Subject: [PATCH] Version18.123 --- css/{swad18.122.5.css => swad18.123.css} | 146 +++++++++++------ js/{swad18.116.5.js => swad18.123.js} | 42 ++++- swad_action.c | 23 +-- swad_action.h | 198 +++++++++++------------ swad_changelog.h | 8 +- swad_config.h | 5 +- swad_game.c | 196 +++++++++++++--------- swad_game.h | 4 +- swad_global.h | 1 + swad_layout.c | 100 ++++++++---- swad_test.c | 68 +++++--- swad_test.h | 2 + 12 files changed, 491 insertions(+), 302 deletions(-) rename css/{swad18.122.5.css => swad18.123.css} (98%) rename js/{swad18.116.5.js => swad18.123.js} (97%) diff --git a/css/swad18.122.5.css b/css/swad18.123.css similarity index 98% rename from css/swad18.122.5.css rename to css/swad18.123.css index 762e0741b..7a415f0fe 100644 --- a/css/swad18.122.5.css +++ b/css/swad18.123.css @@ -6,7 +6,7 @@ and used to support university teaching. This file is part of SWAD core. - Copyright (C) 1999-2019 Antonio Cañas Vargas + Copyright (C) 1999-2019 Antonio Cañas Vargas This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General 3 License as @@ -1459,38 +1459,6 @@ a:hover /* Default ==> underlined */ background-image:linear-gradient(rgba(0,0,0,0),rgba(0,0,0,0.2)); } -.BT_A {background-color:#e21c3d; border-color:#a9152d;} /* red */ -.BT_B {background-color:#1369ce; border-color:#0e519c;} /* blue */ -.BT_C {background-color:#d89e00; border-color:#a27600;} /* yellow */ -.BT_D {background-color:#2b9010; border-color:#206c0c;} /* green */ -.BT_E {background-color:#e30087; border-color:#aa0064;} /* pink */ -.BT_F {background-color:#00b5e9; border-color:#0089b0;} /* light blue */ -.BT_G {background-color:#f58700; border-color:#b86400;} /* orange */ -.BT_H {background-color:#b3d00a; border-color:#869d07;} /* light green */ -.BT_I {background-color:#642075; border-color:#4b1858;} /* purple */ -.BT_J {background-color:#f5e800; border-color:#b8ad00;} /* light yellow */ -.BT_GAME - { - box-sizing:border-box; - width:64px; - margin:8px; - padding:8px; - border-radius:4px; - border-width:1px; - border-style:solid; - box-shadow:0 1px 0 rgba(255,255,255,0.15) inset; - color:white; - font-size:36px; - font-weight:bold; - line-height:normal; - white-space:nowrap; - } -.BT_GAME:hover - { - background-image:-webkit-linear-gradient(rgba(0,0,0,0),rgba(0,0,0,0.2)); /* Safari */ - background-image:linear-gradient(rgba(0,0,0,0),rgba(0,0,0,0.2)); - } - /********************************** Notice ***********************************/ .NOTICE_HIGHLIGHT { @@ -2133,13 +2101,13 @@ a:hover img.CENTRE_PHOTO_SHOW .NOWRAP {white-space:nowrap;} /****************************** Placing of objects ***************************/ -.LEFT_TOP {text-align:left; vertical-align:top;} +.LEFT_TOP {text-align:left; vertical-align:top;} .LEFT_MIDDLE {text-align:left; vertical-align:middle;} .LEFT_BOTTOM {text-align:left; vertical-align:bottom;} -.CENTER_TOP {text-align:center; vertical-align:top;} +.CENTER_TOP {text-align:center; vertical-align:top;} .CENTER_MIDDLE {text-align:center; vertical-align:middle;} .CENTER_BOTTOM {text-align:center; vertical-align:bottom;} -.RIGHT_TOP {text-align:right; vertical-align:top;} +.RIGHT_TOP {text-align:right; vertical-align:top;} .RIGHT_MIDDLE {text-align:right; vertical-align:middle;} .RIGHT_BOTTOM {text-align:right; vertical-align:bottom;} @@ -2596,54 +2564,132 @@ a:hover img.CENTRE_PHOTO_SHOW } /********************************** Games ************************************/ -.GAM_PLAY_CONTAINER +.GAM_PLAY_TCH_CONTAINER { box-sizing:border-box; display:table; margin:5%; width:90%; } -.GAM_PLAY_NUM_QST +.GAM_PLAY_TCH_NUM_QST { - width:10%; + width:15%; float:left; - /* position:relative; */ padding-bottom:24pt; color:#808080; font-size:48pt; font-weight:bold; } -.GAM_PLAY_QST_CONTAINER +.GAM_PLAY_TCH_QST_CONTAINER { - width:80%; + width:70%; float:left; - /* position:relative; */ } -.GAM_PLAY_NXT_CONTAINER +.GAM_PLAY_TCH_NXT_CONTAINER { - width:10%; + width:15%; float:left; - /* position:relative; */ } -.GAM_PLAY_QST +.GAM_PLAY_TCH_QST { color:#202020; font-size:24pt; } -.GAM_PLAY_CONTINUE_CONTAINER +.GAM_PLAY_TCH_CONTINUE_CONTAINER { clear:all; text-align:center; } -.GAM_PLAY_CONTINUE_CONTAINER a +.GAM_PLAY_TCH_CONTINUE_CONTAINER a { text-decoration:none; } -.GAM_PLAY_CONTINUE +.GAM_PLAY_TCH_CONTINUE { font-size:16pt; } +.GAM_PLAY_STD_CONTAINER + { + box-sizing:border-box; + display:table; + margin:5%; + width:90%; + } +.GAM_PLAY_STD_NUM_QST + { + width:15%; + float:left; + padding-bottom:24pt; + color:#808080; + font-size:48pt; + font-weight:bold; + } +.GAM_PLAY_STD_QST_CONTAINER + { + width:85%; + float:left; + } +.GAM_PLAY_STD_QST + { + color:#202020; + font-size:24pt; + } + +.GAM_PLAY_TCH_BUTTON + { + box-sizing:border-box; + width:64px; + margin:8px; + padding:8px; + border-radius:4px; + border-width:1px; + border-style:solid; + box-shadow:0 1px 0 rgba(255,255,255,0.15) inset; + color:white; + font-size:36pt; + font-weight:bold; + line-height:normal; + white-space:nowrap; + } +.GAM_PLAY_STD_CELL + { + text-align:center; + vertical-align:middle; + } +.GAM_PLAY_STD_BUTTON + { + box-sizing:border-box; + width:80%; + margin:10px auto; + padding:20px; + border-radius:4px; + border-width:1px; + border-style:solid; + box-shadow:0 1px 0 rgba(255,255,255,0.15) inset; + color:white; + font-size:44pt; + font-weight:bold; + line-height:normal; + white-space:nowrap; + } +.GAM_PLAY_TCH_BUTTON:hover, .GAM_PLAY_STD_BUTTON:hover + { + background-image:-webkit-linear-gradient(rgba(0,0,0,0),rgba(0,0,0,0.2)); /* Safari */ + background-image:linear-gradient(rgba(0,0,0,0),rgba(0,0,0,0.2)); + } + +.BT_A {background-color:#e21c3d; border-color:#a9152d;} /* red */ +.BT_B {background-color:#1369ce; border-color:#0e519c;} /* blue */ +.BT_C {background-color:#d89e00; border-color:#a27600;} /* yellow */ +.BT_D {background-color:#2b9010; border-color:#206c0c;} /* green */ +.BT_E {background-color:#e30087; border-color:#aa0064;} /* pink */ +.BT_F {background-color:#00b5e9; border-color:#0089b0;} /* light blue */ +.BT_G {background-color:#f58700; border-color:#b86400;} /* orange */ +.BT_H {background-color:#b3d00a; border-color:#869d07;} /* light green */ +.BT_I {background-color:#642075; border-color:#4b1858;} /* purple */ +.BT_J {background-color:#f5e800; border-color:#b8ad00;} /* light yellow */ + /******************************* Time table **********************************/ #timetable { diff --git a/js/swad18.116.5.js b/js/swad18.123.js similarity index 97% rename from js/swad18.116.5.js rename to js/swad18.123.js index 00c5b1796..1fb8a195a 100644 --- a/js/swad18.116.5.js +++ b/js/swad18.123.js @@ -4,7 +4,7 @@ SWAD (Shared Workspace At a Distance), is a web platform developed at the University of Granada (Spain), and used to support university teaching. - Copyright (C) 1999-2019 Antonio Cañas-Vargas + Copyright (C) 1999-2019 Antonio Ca�as-Vargas University of Granada (SPAIN) (acanas@ugr.es) This program is free software: you can redistribute it and/or modify @@ -512,6 +512,40 @@ function readConnUsrsData () { } } +/*****************************************************************************/ +/*********** Automatic refresh of current game question using AJAX ***********/ +/*****************************************************************************/ + +// This function must be called from time to time +var objXMLHttpReqGam = false; +function refreshGame () { + objXMLHttpReqGam = AJAXCreateObject(); + if (objXMLHttpReqGam) { + var RefreshParams = RefreshParamNxtActGam + '&' + + RefreshParamGamCod + '&' + + RefreshParamIdSes; + + objXMLHttpReqGam.onreadystatechange = readGameData; // onreadystatechange must be lowercase + objXMLHttpReqGam.open('POST',ActionAJAX,true); + objXMLHttpReqGam.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); + objXMLHttpReqGam.send(RefreshParams); + } +} + +function readGameData () { + if (objXMLHttpReqGam.readyState == 4) { // Check if data have been received + if (objXMLHttpReqGam.status == 200) { + var htmlGame = objXMLHttpReqGam.responseText; // Get HTML code for last clicks + + var divGame = document.getElementById('game'); // Access to game DIV + if (divGame) + divGame.innerHTML = htmlGame; // Update game DIV + // Global delay variable is set initially in swad-core + setTimeout('refreshGame()',delayGame); + } + } +} + /*****************************************************************************/ /**************** Automatic refresh of last clicks using AJAX ****************/ /*****************************************************************************/ @@ -521,13 +555,13 @@ var objXMLHttpReqLog = false; function refreshLastClicks () { objXMLHttpReqLog = AJAXCreateObject(); if (objXMLHttpReqLog) { - var RefreshParams = RefreshParamNxtActLog + '&' + + var RefreshParams = RefreshParamNxtActLstClk + '&' + RefreshParamIdSes + '&' + RefreshParamCrsCod; objXMLHttpReqLog.onreadystatechange = readLastClicksData; // onreadystatechange must be lowercase objXMLHttpReqLog.open('POST',ActionAJAX,true); - objXMLHttpReqLog.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + objXMLHttpReqLog.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); objXMLHttpReqLog.send(RefreshParams); } } @@ -564,7 +598,7 @@ function refreshNewTimeline () { objXMLHttpReqNewTL.onreadystatechange = readNewTimelineData; // onreadystatechange must be lowercase objXMLHttpReqNewTL.open('POST',ActionAJAX,true); - objXMLHttpReqNewTL.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + objXMLHttpReqNewTL.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); objXMLHttpReqNewTL.send(RefreshParams); } } diff --git a/swad_action.c b/swad_action.c index 09893a935..306545b5d 100644 --- a/swad_action.c +++ b/swad_action.c @@ -93,10 +93,6 @@ extern struct Globals Gbl; 1. ActUnk Unknown action 2. ActMnu Show menu of a tab 3. ActRefCon Refresh number of notifications and connected users via AJAX - 4. ActRefLstClk Refresh last clicks in log via AJAX - 5. ActRefNewSocPubGbl Refresh recent social timeline via AJAX - 6. ActRefOldSocPubGbl View old social timeline with users I follow via AJAX - 7. ActRefOldSocPubUsr View old social timeline of a user via AJAX 8. ActWebSvc Call plugin function Start: @@ -117,6 +113,8 @@ Start: 22. ActSch Search for courses, teachers, documents... + 5. ActRefNewSocPubGbl Refresh recent social timeline via AJAX + 6. ActRefOldSocPubGbl View old social timeline with users I follow via AJAX 23. ActRcvSocPstGbl Receive a public social post to be displayed in the timeline (global) 24. ActRcvSocComGbl Comment a social note in the timeline (global) 25. ActAllShaSocNotGbl Show all users who have shared a note in the timeline (global) @@ -135,6 +133,7 @@ Start: 38. ActReqOthPubPrf Request @nickname to show a public user's profile + 7. ActRefOldSocPubUsr View old social timeline of a user via AJAX 39. ActRcvSocPstUsr Receive a public social post to be displayed in the timeline (user) 40. ActRcvSocComUsr Comment a social note in the timeline (user) 41. ActAllShaSocNotUsr Show all users who have shared a note in the timeline (user) @@ -614,6 +613,7 @@ Assessment: NEW. ActPlyGamStd Play a game (by a student) NEW. ActGamStdCurQst Show current question when playing a game (by a student) + NEW. ActRefGamStd Refresh current question when playing a game (by a student) 459. ActAnsGam Answer a game 460. ActFrmNewGam Form to create a new game @@ -1504,7 +1504,8 @@ Statistics: 1279. ActSeeAccCrs Query clicks to current course 1280. ActSeeAllStaCrs Show statistics of courses - 1281. ActLstClk List last clicks in real time + 1281. ActLstClk List last clicks + 4. ActRefLstClk Refresh last clicks in real time via AJAX 1282. ActSeeMyUsgRep Show my usage report @@ -1618,10 +1619,6 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActUnk */{ 194,-1,TabUnk,ActUnk ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,NULL ,NULL}, /* ActMnu */{ 2,-1,TabUnk,ActMnu ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,NULL ,NULL}, /* ActRefCon */{ 845,-1,TabUnk,ActRefCon ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_AJAX_RFRESH,NULL ,Lay_RefreshNotifsAndConnected ,NULL}, - /* ActRefLstClk */{ 994,-1,TabUnk,ActRefLstClk ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_AJAX_RFRESH,NULL ,Lay_RefreshLastClicks ,NULL}, - /* ActRefNewSocPubGbl*/{1509,-1,TabUnk,ActRefNewSocPubGbl ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_AJAX_RFRESH,NULL ,TL_RefreshNewTimelineGbl ,NULL}, - /* ActRefOldSocPubGbl*/{1510,-1,TabUnk,ActRefOldSocPubGbl ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_AJAX_NORMAL,NULL ,TL_RefreshOldTimelineGbl ,NULL}, - /* ActRefOldSocPubUsr*/{1511,-1,TabUnk,ActRefOldSocPubUsr ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_AJAX_NORMAL,NULL ,TL_RefreshOldTimelineUsr ,NULL}, /* ActWebSvc */{ 892,-1,TabUnk,ActWebSvc ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_WEB_SERVICE,NULL ,API_WebService ,NULL}, // TabStr ****************************************************************** @@ -1642,6 +1639,8 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActSch */{ 628,-1,TabUnk,ActReqSch ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_BRW_1ST_TAB,Sch_GetParamsSearch ,Sch_SysSearch ,NULL}, + /* ActRefNewSocPubGbl*/{1509,-1,TabUnk,ActSeeSocTmlGbl ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_AJAX_RFRESH,NULL ,TL_RefreshNewTimelineGbl ,NULL}, + /* ActRefOldSocPubGbl*/{1510,-1,TabUnk,ActSeeSocTmlGbl ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_AJAX_NORMAL,NULL ,TL_RefreshOldTimelineGbl ,NULL}, /* ActRcvSocPstGbl */{1492,-1,TabUnk,ActSeeSocTmlGbl ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_DATA,Act_BRW_1ST_TAB,TL_ShowTimelineGbl1 ,TL_ReceivePostGbl ,NULL}, /* ActRcvSocComGbl */{1503,-1,TabUnk,ActSeeSocTmlGbl ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_DATA,Act_BRW_1ST_TAB,TL_ShowTimelineGbl1 ,TL_ReceiveCommentGbl ,NULL}, /* ActAllShaSocNotGbl*/{1766,-1,TabUnk,ActSeeSocTmlGbl ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_AJAX_NORMAL,NULL ,TL_ShowAllSharersNoteGbl ,NULL}, @@ -1660,6 +1659,7 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActReqOthPubPrf */{1401,-1,TabUnk,ActSeeSocPrf ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Prf_RequestUserProfile ,NULL}, + /* ActRefOldSocPubUsr*/{1511,-1,TabUnk,ActSeeSocPrf ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_AJAX_NORMAL,NULL ,TL_RefreshOldTimelineUsr ,NULL}, /* ActRcvSocPstUsr */{1498,-1,TabUnk,ActSeeSocPrf ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_DATA,Act_BRW_1ST_TAB,NULL ,TL_ReceivePostUsr ,NULL}, /* ActRcvSocComUsr */{1504,-1,TabUnk,ActSeeSocPrf ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_DATA,Act_BRW_1ST_TAB,NULL ,TL_ReceiveCommentUsr ,NULL}, /* ActAllShaSocNotUsr*/{1769,-1,TabUnk,ActSeeSocPrf ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_AJAX_NORMAL,NULL ,TL_ShowAllSharersNoteUsr ,NULL}, @@ -2148,7 +2148,8 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActGamTchEnd */{1781,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_GameTchEnd ,NULL}, /* ActPlyGamStd */{1779,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_PlayGameStd ,NULL}, - /* ActGamStdCurQst */{1780,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Gam_GameStdCurrentQuestion ,NULL}, + /* ActGamStdCurQst */{1780,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,Gam_GetGameBeingPlayed ,Gam_ShowNewGameToMeAsStd ,NULL}, + /* ActRefGamStd */{1782,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_AJAX_RFRESH,Gam_GetGameBeingPlayed ,Gam_RefreshCurrentGameStd ,NULL}, /* ActAnsGam */{1651,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_ReceiveGameAnswers ,NULL}, /* ActFrmNewGam */{1652,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RequestCreatOrEditGame ,NULL}, @@ -3107,6 +3108,7 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActSeeAllStaCrs */{ 768,-1,TabUnk,ActReqAccGbl ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Ind_ShowIndicatorsCourses ,NULL}, /* ActLstClk */{ 989,-1,TabUnk,ActReqAccGbl ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Sta_ShowLastClicks ,NULL}, + /* ActRefLstClk */{ 994,-1,TabUnk,ActRefLstClk ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_AJAX_RFRESH,NULL ,Lay_RefreshLastClicks ,NULL}, /* ActSeeMyUsgRep */{1582,-1,TabUnk,ActReqMyUsgRep ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Rep_ShowMyUsageReport ,NULL}, @@ -4981,6 +4983,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActPlyGamStd, // #1779 ActGamStdCurQst, // #1780 ActGamTchEnd, // #1781 + ActRefGamStd, // #1782 }; /*****************************************************************************/ diff --git a/swad_action.h b/swad_action.h index cf0df921a..118b7f439 100644 --- a/swad_action.h +++ b/swad_action.h @@ -64,9 +64,9 @@ typedef enum typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to indicate obsolete action -#define Act_NUM_ACTIONS (1 + 8 + 61 + 38 + 12 + 42 + 36 + 19 + 110 + 166 + 437 + 176 + 169 + 15 + 67) +#define Act_NUM_ACTIONS (1 + 4 + 64 + 38 + 12 + 42 + 36 + 19 + 110 + 167 + 437 + 176 + 169 + 16 + 67) -#define Act_MAX_ACTION_COD 1781 +#define Act_MAX_ACTION_COD 1782 #define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13 @@ -78,14 +78,9 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to #define ActUnk 1 #define ActMnu 2 -// The following 5 actions use AJAX to refresh only a part of the page #define ActRefCon 3 -#define ActRefLstClk 4 -#define ActRefNewSocPubGbl 5 -#define ActRefOldSocPubGbl 6 -#define ActRefOldSocPubUsr 7 -#define ActWebSvc 8 +#define ActWebSvc 4 /*****************************************************************************/ /********************************* Start tab *********************************/ @@ -109,59 +104,62 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to #define ActSch (ActWebSvc + 14) -#define ActRcvSocPstGbl (ActWebSvc + 15) -#define ActRcvSocComGbl (ActWebSvc + 16) -#define ActAllShaSocNotGbl (ActWebSvc + 17) -#define ActAllFavSocNotGbl (ActWebSvc + 18) -#define ActAllFavSocComGbl (ActWebSvc + 19) -#define ActShaSocNotGbl (ActWebSvc + 20) -#define ActUnsSocNotGbl (ActWebSvc + 21) -#define ActFavSocNotGbl (ActWebSvc + 22) -#define ActUnfSocNotGbl (ActWebSvc + 23) -#define ActFavSocComGbl (ActWebSvc + 24) -#define ActUnfSocComGbl (ActWebSvc + 25) -#define ActReqRemSocPubGbl (ActWebSvc + 26) -#define ActRemSocPubGbl (ActWebSvc + 27) -#define ActReqRemSocComGbl (ActWebSvc + 28) -#define ActRemSocComGbl (ActWebSvc + 29) +#define ActRefNewSocPubGbl (ActWebSvc + 15) +#define ActRefOldSocPubGbl (ActWebSvc + 16) +#define ActRcvSocPstGbl (ActWebSvc + 17) +#define ActRcvSocComGbl (ActWebSvc + 18) +#define ActAllShaSocNotGbl (ActWebSvc + 19) +#define ActAllFavSocNotGbl (ActWebSvc + 20) +#define ActAllFavSocComGbl (ActWebSvc + 21) +#define ActShaSocNotGbl (ActWebSvc + 22) +#define ActUnsSocNotGbl (ActWebSvc + 23) +#define ActFavSocNotGbl (ActWebSvc + 24) +#define ActUnfSocNotGbl (ActWebSvc + 25) +#define ActFavSocComGbl (ActWebSvc + 26) +#define ActUnfSocComGbl (ActWebSvc + 27) +#define ActReqRemSocPubGbl (ActWebSvc + 28) +#define ActRemSocPubGbl (ActWebSvc + 29) +#define ActReqRemSocComGbl (ActWebSvc + 30) +#define ActRemSocComGbl (ActWebSvc + 31) -#define ActReqOthPubPrf (ActWebSvc + 30) +#define ActReqOthPubPrf (ActWebSvc + 32) -#define ActRcvSocPstUsr (ActWebSvc + 31) -#define ActRcvSocComUsr (ActWebSvc + 32) -#define ActAllShaSocNotUsr (ActWebSvc + 33) -#define ActAllFavSocNotUsr (ActWebSvc + 34) -#define ActAllFavSocComUsr (ActWebSvc + 35) -#define ActShaSocNotUsr (ActWebSvc + 36) -#define ActUnsSocNotUsr (ActWebSvc + 37) -#define ActFavSocNotUsr (ActWebSvc + 38) -#define ActUnfSocNotUsr (ActWebSvc + 39) -#define ActFavSocComUsr (ActWebSvc + 40) -#define ActUnfSocComUsr (ActWebSvc + 41) -#define ActReqRemSocPubUsr (ActWebSvc + 42) -#define ActRemSocPubUsr (ActWebSvc + 43) -#define ActReqRemSocComUsr (ActWebSvc + 44) -#define ActRemSocComUsr (ActWebSvc + 45) +#define ActRefOldSocPubUsr (ActWebSvc + 33) +#define ActRcvSocPstUsr (ActWebSvc + 34) +#define ActRcvSocComUsr (ActWebSvc + 35) +#define ActAllShaSocNotUsr (ActWebSvc + 36) +#define ActAllFavSocNotUsr (ActWebSvc + 37) +#define ActAllFavSocComUsr (ActWebSvc + 38) +#define ActShaSocNotUsr (ActWebSvc + 39) +#define ActUnsSocNotUsr (ActWebSvc + 40) +#define ActFavSocNotUsr (ActWebSvc + 41) +#define ActUnfSocNotUsr (ActWebSvc + 42) +#define ActFavSocComUsr (ActWebSvc + 43) +#define ActUnfSocComUsr (ActWebSvc + 44) +#define ActReqRemSocPubUsr (ActWebSvc + 45) +#define ActRemSocPubUsr (ActWebSvc + 46) +#define ActReqRemSocComUsr (ActWebSvc + 47) +#define ActRemSocComUsr (ActWebSvc + 48) -#define ActSeeOthPubPrf (ActWebSvc + 46) -#define ActCalFig (ActWebSvc + 47) +#define ActSeeOthPubPrf (ActWebSvc + 49) +#define ActCalFig (ActWebSvc + 50) -#define ActFolUsr (ActWebSvc + 48) -#define ActUnfUsr (ActWebSvc + 49) -#define ActSeeFlg (ActWebSvc + 50) -#define ActSeeFlr (ActWebSvc + 51) +#define ActFolUsr (ActWebSvc + 51) +#define ActUnfUsr (ActWebSvc + 52) +#define ActSeeFlg (ActWebSvc + 53) +#define ActSeeFlr (ActWebSvc + 54) -#define ActPrnCal (ActWebSvc + 52) -#define ActChgCal1stDay (ActWebSvc + 53) +#define ActPrnCal (ActWebSvc + 55) +#define ActChgCal1stDay (ActWebSvc + 56) -#define ActSeeNewNtf (ActWebSvc + 54) -#define ActMrkNtfSee (ActWebSvc + 55) -#define ActSeeMai (ActWebSvc + 56) -#define ActEdiMai (ActWebSvc + 57) -#define ActNewMai (ActWebSvc + 58) -#define ActRemMai (ActWebSvc + 59) -#define ActRenMaiSho (ActWebSvc + 60) -#define ActRenMaiFul (ActWebSvc + 61) +#define ActSeeNewNtf (ActWebSvc + 57) +#define ActMrkNtfSee (ActWebSvc + 58) +#define ActSeeMai (ActWebSvc + 59) +#define ActEdiMai (ActWebSvc + 60) +#define ActNewMai (ActWebSvc + 61) +#define ActRemMai (ActWebSvc + 62) +#define ActRenMaiSho (ActWebSvc + 63) +#define ActRenMaiFul (ActWebSvc + 64) /*****************************************************************************/ /******************************** System tab *********************************/ @@ -616,51 +614,52 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to #define ActGamTchAns (ActChgCrsTT1stDay + 121) #define ActPlyGamStd (ActChgCrsTT1stDay + 122) #define ActGamStdCurQst (ActChgCrsTT1stDay + 123) -#define ActAnsGam (ActChgCrsTT1stDay + 124) -#define ActFrmNewGam (ActChgCrsTT1stDay + 125) -#define ActEdiOneGam (ActChgCrsTT1stDay + 126) -#define ActNewGam (ActChgCrsTT1stDay + 127) -#define ActChgGam (ActChgCrsTT1stDay + 128) -#define ActReqRemGam (ActChgCrsTT1stDay + 129) -#define ActRemGam (ActChgCrsTT1stDay + 130) -#define ActReqRstGam (ActChgCrsTT1stDay + 131) -#define ActRstGam (ActChgCrsTT1stDay + 132) -#define ActHidGam (ActChgCrsTT1stDay + 133) -#define ActShoGam (ActChgCrsTT1stDay + 134) -#define ActAddOneGamQst (ActChgCrsTT1stDay + 135) -#define ActGamLstTstQst (ActChgCrsTT1stDay + 136) -#define ActAddTstQstToGam (ActChgCrsTT1stDay + 137) -#define ActReqRemGamQst (ActChgCrsTT1stDay + 138) -#define ActRemGamQst (ActChgCrsTT1stDay + 139) -#define ActUp_GamQst (ActChgCrsTT1stDay + 140) -#define ActDwnGamQst (ActChgCrsTT1stDay + 141) +#define ActRefGamStd (ActChgCrsTT1stDay + 124) +#define ActAnsGam (ActChgCrsTT1stDay + 125) +#define ActFrmNewGam (ActChgCrsTT1stDay + 126) +#define ActEdiOneGam (ActChgCrsTT1stDay + 127) +#define ActNewGam (ActChgCrsTT1stDay + 128) +#define ActChgGam (ActChgCrsTT1stDay + 129) +#define ActReqRemGam (ActChgCrsTT1stDay + 130) +#define ActRemGam (ActChgCrsTT1stDay + 131) +#define ActReqRstGam (ActChgCrsTT1stDay + 132) +#define ActRstGam (ActChgCrsTT1stDay + 133) +#define ActHidGam (ActChgCrsTT1stDay + 134) +#define ActShoGam (ActChgCrsTT1stDay + 135) +#define ActAddOneGamQst (ActChgCrsTT1stDay + 136) +#define ActGamLstTstQst (ActChgCrsTT1stDay + 137) +#define ActAddTstQstToGam (ActChgCrsTT1stDay + 138) +#define ActReqRemGamQst (ActChgCrsTT1stDay + 139) +#define ActRemGamQst (ActChgCrsTT1stDay + 140) +#define ActUp_GamQst (ActChgCrsTT1stDay + 141) +#define ActDwnGamQst (ActChgCrsTT1stDay + 142) -#define ActSeeSvy (ActChgCrsTT1stDay + 142) -#define ActAnsSvy (ActChgCrsTT1stDay + 143) -#define ActFrmNewSvy (ActChgCrsTT1stDay + 144) -#define ActEdiOneSvy (ActChgCrsTT1stDay + 145) -#define ActNewSvy (ActChgCrsTT1stDay + 146) -#define ActChgSvy (ActChgCrsTT1stDay + 147) -#define ActReqRemSvy (ActChgCrsTT1stDay + 148) -#define ActRemSvy (ActChgCrsTT1stDay + 149) -#define ActReqRstSvy (ActChgCrsTT1stDay + 150) -#define ActRstSvy (ActChgCrsTT1stDay + 151) -#define ActHidSvy (ActChgCrsTT1stDay + 152) -#define ActShoSvy (ActChgCrsTT1stDay + 153) -#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 154) -#define ActRcvSvyQst (ActChgCrsTT1stDay + 155) -#define ActReqRemSvyQst (ActChgCrsTT1stDay + 156) -#define ActRemSvyQst (ActChgCrsTT1stDay + 157) +#define ActSeeSvy (ActChgCrsTT1stDay + 143) +#define ActAnsSvy (ActChgCrsTT1stDay + 144) +#define ActFrmNewSvy (ActChgCrsTT1stDay + 145) +#define ActEdiOneSvy (ActChgCrsTT1stDay + 146) +#define ActNewSvy (ActChgCrsTT1stDay + 147) +#define ActChgSvy (ActChgCrsTT1stDay + 148) +#define ActReqRemSvy (ActChgCrsTT1stDay + 149) +#define ActRemSvy (ActChgCrsTT1stDay + 150) +#define ActReqRstSvy (ActChgCrsTT1stDay + 151) +#define ActRstSvy (ActChgCrsTT1stDay + 152) +#define ActHidSvy (ActChgCrsTT1stDay + 153) +#define ActShoSvy (ActChgCrsTT1stDay + 154) +#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 155) +#define ActRcvSvyQst (ActChgCrsTT1stDay + 156) +#define ActReqRemSvyQst (ActChgCrsTT1stDay + 157) +#define ActRemSvyQst (ActChgCrsTT1stDay + 158) -#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 158) -#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 159) -#define ActEdiExaAnn (ActChgCrsTT1stDay + 160) -#define ActRcvExaAnn (ActChgCrsTT1stDay + 161) -#define ActPrnExaAnn (ActChgCrsTT1stDay + 162) -#define ActReqRemExaAnn (ActChgCrsTT1stDay + 163) -#define ActRemExaAnn (ActChgCrsTT1stDay + 164) -#define ActHidExaAnn (ActChgCrsTT1stDay + 165) -#define ActShoExaAnn (ActChgCrsTT1stDay + 166) +#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 159) +#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 160) +#define ActEdiExaAnn (ActChgCrsTT1stDay + 161) +#define ActRcvExaAnn (ActChgCrsTT1stDay + 162) +#define ActPrnExaAnn (ActChgCrsTT1stDay + 163) +#define ActReqRemExaAnn (ActChgCrsTT1stDay + 164) +#define ActRemExaAnn (ActChgCrsTT1stDay + 165) +#define ActHidExaAnn (ActChgCrsTT1stDay + 166) +#define ActShoExaAnn (ActChgCrsTT1stDay + 167) /*****************************************************************************/ /******************************** Files tab **********************************/ @@ -1537,8 +1536,9 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to #define ActSeeAllStaCrs (ActMaiUsr + 13) #define ActLstClk (ActMaiUsr + 14) +#define ActRefLstClk (ActMaiUsr + 15) -#define ActSeeMyUsgRep (ActMaiUsr + 15) +#define ActSeeMyUsgRep (ActMaiUsr + 16) /*****************************************************************************/ /******************************** Profile tab ********************************/ diff --git a/swad_changelog.h b/swad_changelog.h index 5515810e5..954e8d376 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -448,10 +448,12 @@ En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 18.122.5 (2019-05-20)" -#define CSS_FILE "swad18.122.5.css" -#define JS_FILE "swad18.116.5.js" +#define Log_PLATFORM_VERSION "SWAD 18.123 (2019-05-22)" +#define CSS_FILE "swad18.123.css" +#define JS_FILE "swad18.123.js" /* + Version 18.123: May 22, 2019 Game is refreshed automatically. + Code refactoring in actions related to AJAX refreshing. (242770 lines) Version 18.122.5: May 20, 2019 Buttons for options in games. (242596 lines) Version 18.122.4: May 20, 2019 Changes in buttons. (242563 lines) Version 18.122.3: May 20, 2019 Changes in games. (242558 lines) diff --git a/swad_config.h b/swad_config.h index 1aeecba91..fde4f2881 100644 --- a/swad_config.h +++ b/swad_config.h @@ -492,10 +492,11 @@ #define Cfg_TIME_TO_CLOSE_SESSION_FROM_LAST_REFRESH ((time_t)(Cfg_MAX_TIME_TO_REFRESH_CONNECTED * 4)) // After these seconds without refresh of connected users, session is closed #define Cfg_TIME_TO_CLOSE_SESSION_FROM_LAST_CLICK ((time_t)( 8 * 60UL * 60UL)) // After these seconds without user's clicks, session is closed -#define Cfg_TIME_TO_REFRESH_LAST_CLICKS ((time_t)( 1UL * 1000UL)) // Refresh period of last clicks in miliseconds - #define Cfg_TIME_TO_REFRESH_TIMELINE ((time_t)( 2UL * 1000UL)) // Initial refresh period of social timeline in miliseconds // This delay is increased 1 second on each refresh +#define Cfg_TIME_TO_REFRESH_GAME ((time_t)( 1UL * 1000UL)) // Refresh period of game being played in miliseconds + +#define Cfg_TIME_TO_REFRESH_LAST_CLICKS ((time_t)( 1UL * 1000UL)) // Refresh period of last clicks in miliseconds #define Cfg_TIME_TO_CHANGE_BANNER ((time_t)( 2UL * 60UL)) // After these seconds, change banner #define Cfg_NUMBER_OF_BANNERS 1 // Number of banners to show simultaneously diff --git a/swad_game.c b/swad_game.c index 27f5581b9..9abdddc8e 100644 --- a/swad_game.c +++ b/swad_game.c @@ -167,6 +167,8 @@ static void Gam_PutBigButtonToContinue (Act_Action_t NextAction, long GamCod,unsigned QstInd); static void Gam_PutBigButtonToEnd (long GamCod); +static void Gam_ShowQuestionBeingPlayed (void); + static void Gam_ReceiveAndStoreUserAnswersToAGame (long GamCod); static void Gam_IncreaseAnswerInDB (long QstCod,unsigned AnsInd); static void Gam_RegisterIHaveAnsweredGame (long GamCod); @@ -3169,20 +3171,20 @@ static void Gam_PlayGameShowQuestionAndAnswers (long GamCod, /***** Show question *****/ /* Start container for number and question */ - fprintf (Gbl.F.Out,"
"); + fprintf (Gbl.F.Out,"
"); /* Write number of question */ - fprintf (Gbl.F.Out,"
%u
", + fprintf (Gbl.F.Out,"
%u
", QstInd + 1); - fprintf (Gbl.F.Out,"
"); + fprintf (Gbl.F.Out,"
"); /* Get question code (row[0]) */ if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) <= 0) Lay_ShowErrorAndExit ("Error: wrong question code."); /* Write stem (row[2]) */ - Tst_WriteQstStem (row[2],"GAM_PLAY_QST"); + Tst_WriteQstStem (row[2],"GAM_PLAY_TCH_QST"); /* Get media (row[3]) */ Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[3]); @@ -3201,15 +3203,13 @@ static void Gam_PlayGameShowQuestionAndAnswers (long GamCod, /* Write answers */ Tst_WriteAnswersGameResult (&Game,QstInd,QstCod, - "GAM_PLAY_QST",false); // Don't show result + "GAM_PLAY_TCH_QST",false); // Don't show result } - else - fprintf (Gbl.F.Out," "); fprintf (Gbl.F.Out,"
"); /***** Put button to continue *****/ - fprintf (Gbl.F.Out,"
"); + fprintf (Gbl.F.Out,"
"); if (ShowAnswers) { /* Get index of the next question */ @@ -3243,7 +3243,7 @@ static void Gam_PutBigButtonToContinue (Act_Action_t NextAction, extern const char *Txt_Continue; /***** Start container *****/ - fprintf (Gbl.F.Out,"
"); + fprintf (Gbl.F.Out,"
"); /***** Start form *****/ Frm_StartForm (NextAction); @@ -3251,7 +3251,7 @@ static void Gam_PutBigButtonToContinue (Act_Action_t NextAction, Gam_PutParamQstInd (QstInd); /***** Put icon with link *****/ - Frm_LinkFormSubmit (Txt_Continue,"GAM_PLAY_CONTINUE ICO_HIGHLIGHT",NULL); + Frm_LinkFormSubmit (Txt_Continue,"GAM_PLAY_TCH_CONTINUE ICO_HIGHLIGHT",NULL); fprintf (Gbl.F.Out,"\"%s\"" "
" @@ -3326,83 +3326,133 @@ void Gam_GameTchEnd (void) } /*****************************************************************************/ -/***** Show current question to a student when he/she is playing a game ******/ +/********************** Get code of game being played ************************/ /*****************************************************************************/ -void Gam_GameStdCurrentQuestion (void) +void Gam_GetGameBeingPlayed (void) + { + /***** Get game code ****/ + if ((Gbl.Games.GamCodBeingPlayed = Gam_GetParamGameCod ()) == -1L) + Lay_ShowErrorAndExit ("Code of game is missing."); + } + +/*****************************************************************************/ +/********* Show game being played to me as student in a new window ***********/ +/*****************************************************************************/ + +void Gam_ShowNewGameToMeAsStd (void) + { + fprintf (Gbl.F.Out,"
"); + Gam_ShowQuestionBeingPlayed (); + fprintf (Gbl.F.Out,"
"); + } + +/*****************************************************************************/ +/*************** Refresh current game for a student via AJAX *****************/ +/*****************************************************************************/ + +void Gam_RefreshCurrentGameStd (void) + { + if (Gbl.Session.IsOpen) // If session has been closed, do not write anything + /***** Get and show current question *****/ + Gam_ShowQuestionBeingPlayed (); + } + +/*****************************************************************************/ +/************ Show current question being played for a student ***************/ +/*****************************************************************************/ + +static void Gam_ShowQuestionBeingPlayed (void) { MYSQL_RES *mysql_res; MYSQL_ROW row; - struct Game Game; + // struct Game Game; unsigned QstInd; long QstCod; - bool ShowAnswers = true; // TODO: Get whether to show answers from a database table + bool GameIsPlaying; + bool ShowAnswers; + unsigned NumOptions; + unsigned NumOpt; - /***** Get parameters *****/ - /* Get game code */ - if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) - Lay_ShowErrorAndExit ("Code of game is missing."); - - /* Get question index */ - QstInd = Gam_GetParamQstInd (); // TODO: Get current question from a database table - - /***** Get data of question from database *****/ - if (!DB_QuerySELECT (&mysql_res,"can not get data of a question", - "SELECT tst_questions.QstCod," // row[0] - "tst_questions.AnsType," // row[1] - "tst_questions.Stem," // row[2] - "tst_questions.MedCod" // row[3] - " FROM gam_questions,tst_questions" - " WHERE gam_questions.GamCod=%ld" - " AND gam_questions.QstInd=%u" - " AND gam_questions.QstCod=tst_questions.QstCod", - Game.GamCod,QstInd)) - Ale_ShowAlert (Ale_ERROR,"Question doesn't exist."); - row = mysql_fetch_row (mysql_res); - - /***** Show question *****/ - /* Start container for number and question */ - fprintf (Gbl.F.Out,"
"); - - /* Write number of question */ - fprintf (Gbl.F.Out,"
%u
", - QstInd + 1); - - fprintf (Gbl.F.Out,"
"); - - /* Write stem (row[2]) */ - Tst_WriteQstStem (row[2],"GAM_PLAY_QST"); - - /* Get media (row[3]) */ - Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[3]); - Med_GetMediaDataByCod (&Gbl.Test.Media); - - /* Show media */ - Med_ShowMedia (&Gbl.Test.Media, - "TEST_MED_EDIT_LIST_STEM_CONTAINER", - "TEST_MED_EDIT_LIST_STEM"); - - /* Write answers? */ - if (ShowAnswers) + /***** Get question being played from database *****/ + GameIsPlaying = (DB_QuerySELECT (&mysql_res,"can not get question being played", + "SELECT QstInd," // row[0] + "QstCod," // row[1] + "ShowingAnswers," // row[2] + "GamStart," // row[3] + "QstStart" // row[4] + " FROM gam_playing" + " WHERE GamCod=%ld", + Gbl.Games.GamCodBeingPlayed) != 0); + if (GameIsPlaying) { - /* Get question code (row[0]) */ - if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) <= 0) + /* Get row */ + row = mysql_fetch_row (mysql_res); + + /* Get question index (row[0]) */ + if (sscanf (row[0],"%d",&QstInd) != 1) + Lay_ShowErrorAndExit ("Error when getting question index."); + + /* Get question code (row[1]) */ + if ((QstCod = Str_ConvertStrCodToLongCod (row[1])) <= 0) Lay_ShowErrorAndExit ("Error: wrong question code."); - /* Get answer type (row[1]) */ - Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]); - - /* Write answers */ - Tst_WriteAnswersGameResult (&Game,QstInd,QstCod, - "GAM_PLAY_QST",false); // Don't show result + /* Get whether the answers are being shown (row[2]) */ + ShowAnswers = (row[2][0] == 'Y'); } - else - fprintf (Gbl.F.Out," "); - fprintf (Gbl.F.Out,"
"); + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); - /***** End container for question *****/ - fprintf (Gbl.F.Out,"
"); + /***** Show question *****/ + if (GameIsPlaying) + { + /***** Show question *****/ + /* Write number of question */ + fprintf (Gbl.F.Out,"
%u
", + QstInd + 1); + + fprintf (Gbl.F.Out,"
"); + + /* Write answers? */ + if (ShowAnswers) + { + if (Tst_CheckIfQuestionIsValidForGame (QstCod)) + { + /***** Start table *****/ + Tbl_StartTableWide (8); + + /***** Write answers *****/ + NumOptions = Tst_GetNumAnswersQst (QstCod); + for (NumOpt = 0; + NumOpt < NumOptions; + NumOpt++) + { + // if (NumOpt % 2 == 0) + fprintf (Gbl.F.Out,""); + + /***** Write letter for this option *****/ + fprintf (Gbl.F.Out,"" + "
" + "%c" + "
" + "", + 'A' + (char) NumOpt, + 'a' + (char) NumOpt); + + // if (NumOpt % 2 == 1) + fprintf (Gbl.F.Out,""); + } + + /***** End table *****/ + Tbl_EndTable (); + } + else + Ale_ShowAlert (Ale_ERROR,"Type of answer not valid in a game."); + } + + fprintf (Gbl.F.Out,"
"); + } } /*****************************************************************************/ diff --git a/swad_game.h b/swad_game.h index 7ad318252..dad72c12b 100644 --- a/swad_game.h +++ b/swad_game.h @@ -127,7 +127,9 @@ void Gam_GameTchNextQuestion (void); void Gam_GameTchShowAnswers (void); void Gam_GameTchEnd (void); -void Gam_GameStdCurrentQuestion (void); +void Gam_GetGameBeingPlayed (void); +void Gam_ShowNewGameToMeAsStd (void); +void Gam_RefreshCurrentGameStd (void); unsigned Gam_GetNumCoursesWithGames (Hie_Level_t Scope); unsigned Gam_GetNumGames (Hie_Level_t Scope); diff --git a/swad_global.h b/swad_global.h index c2d3555cd..40c3ecff6 100644 --- a/swad_global.h +++ b/swad_global.h @@ -704,6 +704,7 @@ struct Globals Gam_Order_t SelectedOrder; unsigned CurrentPage; char *ListQuestions; + long GamCodBeingPlayed; // Used to refresh game via AJAX } Games; struct { diff --git a/swad_layout.c b/swad_layout.c index 08ec8eb33..18c241662 100644 --- a/swad_layout.c +++ b/swad_layout.c @@ -117,6 +117,7 @@ void Lay_WriteStartOfPage (void) "main_horizontal", // Mnu_MENU_HORIZONTAL "main_vertical", // Mnu_MENU_VERTICAL }; + Act_BrowserTab_t BrowserTab; /***** If, when this function is called, the head is being written or the head is already written ==> don't do anything *****/ @@ -252,23 +253,32 @@ void Lay_WriteStartOfPage (void) fprintf (Gbl.F.Out,"\n"); /***** HTML body *****/ - if (Act_GetBrowserTab (Gbl.Action.Act) == Act_BRW_1ST_TAB) - fprintf (Gbl.F.Out,"\n" - "
" - "\"\"" - "
" - "
" - "
", - Cfg_URL_ICON_PUBLIC); - else + BrowserTab = Act_GetBrowserTab (Gbl.Action.Act); + switch (BrowserTab) { - fprintf (Gbl.F.Out,"\n"); - Gbl.Layout.WritingHTMLStart = false; - Gbl.Layout.HTMLStartWritten = - Gbl.Layout.DivsEndWritten = true; - return; + case Act_BRW_1ST_TAB: + fprintf (Gbl.F.Out,"\n" + "
" + "\"\"" + "
" + "
" + "
", + Cfg_URL_ICON_PUBLIC); + break; + case Act_BRW_NEW_TAB: + fprintf (Gbl.F.Out,"\n"); + Gbl.Layout.WritingHTMLStart = false; + Gbl.Layout.HTMLStartWritten = + Gbl.Layout.DivsEndWritten = true; + return; + default: + fprintf (Gbl.F.Out,"\n"); + Gbl.Layout.WritingHTMLStart = false; + Gbl.Layout.HTMLStartWritten = + Gbl.Layout.DivsEndWritten = true; + return; } /***** Start box that contains the whole page except the foot *****/ @@ -652,14 +662,12 @@ static void Lay_WriteScriptMathJax (void) static void Lay_WriteScriptInit (void) { extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES]; - bool RefreshLastClicks = false; bool RefreshNewTimeline = false; + bool RefreshGame = false; + bool RefreshLastClicks = false; switch (Gbl.Action.Act) { - case ActLstClk: - RefreshLastClicks = true; - break; case ActSeeSocTmlGbl: case ActRcvSocPstGbl: case ActRcvSocComGbl: @@ -669,6 +677,12 @@ static void Lay_WriteScriptInit (void) case ActRemSocComGbl: RefreshNewTimeline = true; break; + case ActGamStdCurQst: + RefreshGame = true; + break; + case ActLstClk: + RefreshLastClicks = true; + break; default: break; } @@ -680,6 +694,9 @@ static void Lay_WriteScriptInit (void) if (RefreshNewTimeline) fprintf (Gbl.F.Out,"var delayNewTimeline = %lu;\n", Cfg_TIME_TO_REFRESH_TIMELINE); + else if (RefreshGame) // Refresh game via AJAX + fprintf (Gbl.F.Out,"var delayGame = %lu;\n", + Cfg_TIME_TO_REFRESH_GAME); fprintf (Gbl.F.Out,"function init(){\n"); @@ -694,6 +711,8 @@ static void Lay_WriteScriptInit (void) if (RefreshLastClicks) // Refresh last clicks via AJAX fprintf (Gbl.F.Out," setTimeout(\"refreshLastClicks()\",%lu);\n", Cfg_TIME_TO_REFRESH_LAST_CLICKS); + else if (RefreshGame) // Refresh game via AJAX + fprintf (Gbl.F.Out," setTimeout(\"refreshGame()\",delayGame);\n"); else if (RefreshNewTimeline) // Refresh timeline via AJAX fprintf (Gbl.F.Out," setTimeout(\"refreshNewTimeline()\",delayNewTimeline);\n"); @@ -710,13 +729,16 @@ static void Lay_WriteScriptParamsAJAX (void) /***** Start script *****/ fprintf (Gbl.F.Out,"\n", - Gbl.Session.Id, - Gbl.Hierarchy.Crs.CrsCod); + /***** End script *****/ + fprintf (Gbl.F.Out,"\n"); } /*****************************************************************************/ diff --git a/swad_test.c b/swad_test.c index 33f9021d3..dc5447f09 100644 --- a/swad_test.c +++ b/swad_test.c @@ -3268,6 +3268,15 @@ void Tst_WriteParamEditQst (void) /*************** Get answers of a test question from database ****************/ /*****************************************************************************/ +unsigned Tst_GetNumAnswersQst (long QstCod) + { + return (unsigned) DB_QueryCOUNT ("can not get number of answers of a question", + "SELECT COUNT(*)" + " FROM tst_answers" + " WHERE QstCod=%ld", + QstCod); + } + unsigned Tst_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res,bool Shuffle) { unsigned long NumRows; @@ -3522,26 +3531,26 @@ static void Tst_WriteAnswersTestResult (struct UsrData *UsrDat, void Tst_WriteAnswersGameResult (struct Game *Game,unsigned NumQst,long QstCod, const char *Class,bool ShowResult) { - /***** Write parameter with question code *****/ - // Tst_WriteParamQstCod (NumQst,QstCod); - /***** Write answer depending on type *****/ - switch (Gbl.Test.AnswerType) - { - case Tst_ANS_INT: - case Tst_ANS_FLOAT: - case Tst_ANS_TRUE_FALSE: - case Tst_ANS_TEXT: - Ale_ShowAlert (Ale_ERROR,"Type of answer not valid in a game."); - break; - case Tst_ANS_UNIQUE_CHOICE: - case Tst_ANS_MULTIPLE_CHOICE: - Tst_WriteChoiceAnsViewGame (Game,NumQst,QstCod, - Class,ShowResult); - break; - default: - break; - } + if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE) + Tst_WriteChoiceAnsViewGame (Game,NumQst,QstCod, + Class,ShowResult); + else + Ale_ShowAlert (Ale_ERROR,"Type of answer not valid in a game."); + } + +/*****************************************************************************/ +/***************** Check if a question is valid for a game *******************/ +/*****************************************************************************/ + +bool Tst_CheckIfQuestionIsValidForGame (long QstCod) + { + /***** Check if a question is valid for a game from database *****/ + return DB_QueryCOUNT ("can not check type of a question", + "SELECT COUNT(*)" + " FROM tst_questions" + " WHERE QstCod=%ld AND AnsType='%s'", + QstCod,Tst_StrAnswerTypesDB[Tst_ANS_UNIQUE_CHOICE]) != 0; } /*****************************************************************************/ @@ -4098,15 +4107,22 @@ static void Tst_WriteChoiceAnsViewGame (struct Game *Game, Gbl.Test.Answer.Options[NumOpt].Media.MedCod = Str_ConvertStrCodToLongCod (row[3]); Med_GetMediaDataByCod (&Gbl.Test.Answer.Options[NumOpt].Media); - /***** Write letter of this option *****/ + /***** Write letter for this option *****/ fprintf (Gbl.F.Out,"" "" - "" - "", - 'A' + (char) NumOpt, - 'a' + (char) NumOpt); + "
" + "%c) ", + Class, + 'a' + (char) NumOpt); + else + fprintf (Gbl.F.Out,"GAM_PLAY_TCH_BUTTON BT_%c\">" + "%c", + 'A' + (char) NumOpt, + 'a' + (char) NumOpt); + fprintf (Gbl.F.Out,"
" + ""); /***** Write the option text *****/ fprintf (Gbl.F.Out,"" diff --git a/swad_test.h b/swad_test.h index 0becb7b62..92e8f74e2 100644 --- a/swad_test.h +++ b/swad_test.h @@ -152,9 +152,11 @@ void Tst_ListQuestionsToEdit (void); void Tst_ListQuestionsToSelect (void); bool Tst_GetOneQuestionByCod (long QstCod,MYSQL_RES **mysql_res); void Tst_WriteParamEditQst (void); +unsigned Tst_GetNumAnswersQst (long QstCod); unsigned Tst_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res,bool Shuffle); void Tst_WriteAnswersGameResult (struct Game *Game,unsigned NumQst,long QstCod, const char *Class,bool ShowResult); +bool Tst_CheckIfQuestionIsValidForGame (long QstCod); void Tst_WriteAnsTF (char AnsTF); void Tst_CheckIfNumberOfAnswersIsOne (void);