Version19.90

This commit is contained in:
Antonio Cañas Vargas 2019-12-12 18:24:23 +01:00
parent d24b2039f1
commit dfb91731a6
10 changed files with 297 additions and 103 deletions

View File

@ -2718,7 +2718,7 @@ a:hover img.CENTRE_PHOTO_SHOW
text-align:center;
vertical-align:top;
}
.MCH_SHOW_RESULTS
.MCH_SHOW_HOURGLASS, .MCH_SHOW_ANSWERED, .MCH_REM_MY_ANS, .MCH_SHOW_RESULTS
{
text-align:center;
padding:16pt 0;
@ -2770,6 +2770,17 @@ a:hover img.CENTRE_PHOTO_SHOW
width:100%;
height:64px;
font-size:28pt;
font-weight:bold;
padding:2px;
text-align:center;
vertical-align:middle;
}
.MCH_SMALLBUTTON_CONTAINER
{
box-sizing:border-box;
display:table-cell;
width:100%;
font-size:18pt;
padding:2px;
text-align:center;
vertical-align:middle;

View File

@ -572,9 +572,9 @@ function readMatchStdData () {
if (objXMLHttpReqMchStd.status == 200) {
var htmlMatch = objXMLHttpReqMchStd.responseText; // Get HTML code
var divMatch = document.getElementById('match'); // Access to game DIV
var divMatch = document.getElementById('match'); // Access to refreshable DIV
if (divMatch)
divMatch.innerHTML = htmlMatch; // Update game DIV
divMatch.innerHTML = htmlMatch; // Update refreshable DIV
// Global delay variable is set initially in swad-core
setTimeout('refreshMatchStd()',delayMatch);
}
@ -604,11 +604,13 @@ function refreshMatchTch () {
function readMatchTchData () {
if (objXMLHttpReqMchTch.readyState == 4) { // Check if data have been received
if (objXMLHttpReqMchTch.status == 200) {
var htmlMatch = objXMLHttpReqMchTch.responseText; // Get HTML code
var endOfId = objXMLHttpReqMchTch.responseText.indexOf('|',0); // Get separator position
var Id = objXMLHttpReqMchTch.responseText.substring(0,endOfId); // Get Id
var htmlMatch = objXMLHttpReqMchTch.responseText.substring(endOfId + 1); // Get HTML code
var divMatch = document.getElementById('match_left'); // Access to game DIV
var divMatch = document.getElementById(Id); // Access to refreshable DIV
if (divMatch)
divMatch.innerHTML = htmlMatch; // Update game DIV
divMatch.innerHTML = htmlMatch; // Update refreshable DIV
// Global delay variable is set initially in swad-core
setTimeout('refreshMatchTch()',delayMatch);
}

View File

@ -640,6 +640,7 @@ CREATE TABLE IF NOT EXISTS mch_matches (
QstInd INT NOT NULL DEFAULT 0,
QstCod INT NOT NULL DEFAULT -1,
Showing ENUM('start','stem','answers','results','end') NOT NULL DEFAULT 'start',
Countdown INT NOT NULL DEFAULT -1,
NumCols INT NOT NULL DEFAULT 1,
ShowQstResults ENUM('N','Y') NOT NULL DEFAULT 'N',
ShowUsrResults ENUM('N','Y') NOT NULL DEFAULT 'N',

View File

@ -89,7 +89,7 @@ extern struct Globals Gbl;
/************************* Private global variables **************************/
/*****************************************************************************/
/*
1397 actions in one CGI:
1380 actions in one CGI:
0. ActAll Any action (used for statistics)
1. ActUnk Unknown action
2. ActMnu Show menu of a tab
@ -618,6 +618,7 @@ Assessment:
468. ActReqNewMch Put form to create a new match
469. ActNewMch Create a new match showing first question in a new browser tab
470. ActResMch Resume an unfinished match showing current question in a new browser tab
NEW. ActMchCntDwn Start match countdown
471. ActBckMch Go back when playing a match
472. ActPlyPauMch Play/pause current match
473. ActFwdMch Go forward when playing a match
@ -2157,6 +2158,7 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] =
[ActReqNewMch ] = {1670,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RequestNewMatch ,NULL},
[ActNewMch ] = {1671,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,Mch_CreateNewMatchTch ,Mch_ResumeMatch ,NULL},
[ActResMch ] = {1785,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,Mch_GetMatchBeingPlayed ,Mch_ResumeMatch ,NULL},
[ActMchCntDwn ] = {1814,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_StartCountdown ,NULL},
[ActBckMch ] = {1790,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_BackMatch ,NULL},
[ActPlyPauMch ] = {1789,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_PlayPauseMatch ,NULL},
[ActFwdMch ] = {1672,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_ForwardMatch ,NULL},
@ -5045,6 +5047,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un
ActSeeAllMchResGam, // #1811
ActSeeMyMchResMch, // #1812
ActSeeAllMchResMch, // #1813
ActMchCntDwn, // #1814
};
/*****************************************************************************/

View File

@ -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 + 4 + 66 + 38 + 12 + 42 + 36 + 19 + 110 + 185 + 437 + 176 + 169 + 16 + 68)
#define Act_NUM_ACTIONS (1 + 4 + 66 + 38 + 12 + 42 + 36 + 19 + 110 + 186 + 437 + 176 + 169 + 16 + 68)
#define Act_MAX_ACTION_COD 1813
#define Act_MAX_ACTION_COD 1814
#define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13
@ -617,74 +617,75 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to
#define ActReqNewMch (ActChgCrsTT1stDay + 122)
#define ActNewMch (ActChgCrsTT1stDay + 123)
#define ActResMch (ActChgCrsTT1stDay + 124)
#define ActBckMch (ActChgCrsTT1stDay + 125)
#define ActPlyPauMch (ActChgCrsTT1stDay + 126)
#define ActFwdMch (ActChgCrsTT1stDay + 127)
#define ActChgNumColMch (ActChgCrsTT1stDay + 128)
#define ActChgVisResMchQst (ActChgCrsTT1stDay + 129)
#define ActRefMchTch (ActChgCrsTT1stDay + 130)
#define ActMchCntDwn (ActChgCrsTT1stDay + 125)
#define ActBckMch (ActChgCrsTT1stDay + 126)
#define ActPlyPauMch (ActChgCrsTT1stDay + 127)
#define ActFwdMch (ActChgCrsTT1stDay + 128)
#define ActChgNumColMch (ActChgCrsTT1stDay + 129)
#define ActChgVisResMchQst (ActChgCrsTT1stDay + 130)
#define ActRefMchTch (ActChgCrsTT1stDay + 131)
#define ActJoiMch (ActChgCrsTT1stDay + 131)
#define ActSeeMchAnsQstStd (ActChgCrsTT1stDay + 132)
#define ActRemMchAnsQstStd (ActChgCrsTT1stDay + 133)
#define ActAnsMchQstStd (ActChgCrsTT1stDay + 134)
#define ActRefMchStd (ActChgCrsTT1stDay + 135)
#define ActJoiMch (ActChgCrsTT1stDay + 132)
#define ActSeeMchAnsQstStd (ActChgCrsTT1stDay + 133)
#define ActRemMchAnsQstStd (ActChgCrsTT1stDay + 134)
#define ActAnsMchQstStd (ActChgCrsTT1stDay + 135)
#define ActRefMchStd (ActChgCrsTT1stDay + 136)
#define ActSeeMyMchResCrs (ActChgCrsTT1stDay + 136)
#define ActSeeMyMchResGam (ActChgCrsTT1stDay + 137)
#define ActSeeMyMchResMch (ActChgCrsTT1stDay + 138)
#define ActSeeOneMchResMe (ActChgCrsTT1stDay + 139)
#define ActSeeMyMchResCrs (ActChgCrsTT1stDay + 137)
#define ActSeeMyMchResGam (ActChgCrsTT1stDay + 138)
#define ActSeeMyMchResMch (ActChgCrsTT1stDay + 139)
#define ActSeeOneMchResMe (ActChgCrsTT1stDay + 140)
#define ActReqSeeAllMchRes (ActChgCrsTT1stDay + 140)
#define ActSeeAllMchResCrs (ActChgCrsTT1stDay + 141)
#define ActSeeAllMchResGam (ActChgCrsTT1stDay + 142)
#define ActSeeAllMchResMch (ActChgCrsTT1stDay + 143)
#define ActSeeOneMchResOth (ActChgCrsTT1stDay + 144)
#define ActReqSeeAllMchRes (ActChgCrsTT1stDay + 141)
#define ActSeeAllMchResCrs (ActChgCrsTT1stDay + 142)
#define ActSeeAllMchResGam (ActChgCrsTT1stDay + 143)
#define ActSeeAllMchResMch (ActChgCrsTT1stDay + 144)
#define ActSeeOneMchResOth (ActChgCrsTT1stDay + 145)
#define ActChgVisResMchUsr (ActChgCrsTT1stDay + 145)
#define ActChgVisResMchUsr (ActChgCrsTT1stDay + 146)
#define ActFrmNewGam (ActChgCrsTT1stDay + 146)
#define ActEdiOneGam (ActChgCrsTT1stDay + 147)
#define ActNewGam (ActChgCrsTT1stDay + 148)
#define ActChgGam (ActChgCrsTT1stDay + 149)
#define ActReqRemGam (ActChgCrsTT1stDay + 150)
#define ActRemGam (ActChgCrsTT1stDay + 151)
#define ActHidGam (ActChgCrsTT1stDay + 152)
#define ActShoGam (ActChgCrsTT1stDay + 153)
#define ActAddOneGamQst (ActChgCrsTT1stDay + 154)
#define ActGamLstTstQst (ActChgCrsTT1stDay + 155)
#define ActAddTstQstToGam (ActChgCrsTT1stDay + 156)
#define ActReqRemGamQst (ActChgCrsTT1stDay + 157)
#define ActRemGamQst (ActChgCrsTT1stDay + 158)
#define ActUp_GamQst (ActChgCrsTT1stDay + 159)
#define ActDwnGamQst (ActChgCrsTT1stDay + 160)
#define ActFrmNewGam (ActChgCrsTT1stDay + 147)
#define ActEdiOneGam (ActChgCrsTT1stDay + 148)
#define ActNewGam (ActChgCrsTT1stDay + 149)
#define ActChgGam (ActChgCrsTT1stDay + 150)
#define ActReqRemGam (ActChgCrsTT1stDay + 151)
#define ActRemGam (ActChgCrsTT1stDay + 152)
#define ActHidGam (ActChgCrsTT1stDay + 153)
#define ActShoGam (ActChgCrsTT1stDay + 154)
#define ActAddOneGamQst (ActChgCrsTT1stDay + 155)
#define ActGamLstTstQst (ActChgCrsTT1stDay + 156)
#define ActAddTstQstToGam (ActChgCrsTT1stDay + 157)
#define ActReqRemGamQst (ActChgCrsTT1stDay + 158)
#define ActRemGamQst (ActChgCrsTT1stDay + 159)
#define ActUp_GamQst (ActChgCrsTT1stDay + 160)
#define ActDwnGamQst (ActChgCrsTT1stDay + 161)
#define ActSeeSvy (ActChgCrsTT1stDay + 161)
#define ActAnsSvy (ActChgCrsTT1stDay + 162)
#define ActFrmNewSvy (ActChgCrsTT1stDay + 163)
#define ActEdiOneSvy (ActChgCrsTT1stDay + 164)
#define ActNewSvy (ActChgCrsTT1stDay + 165)
#define ActChgSvy (ActChgCrsTT1stDay + 166)
#define ActReqRemSvy (ActChgCrsTT1stDay + 167)
#define ActRemSvy (ActChgCrsTT1stDay + 168)
#define ActReqRstSvy (ActChgCrsTT1stDay + 169)
#define ActRstSvy (ActChgCrsTT1stDay + 170)
#define ActHidSvy (ActChgCrsTT1stDay + 171)
#define ActShoSvy (ActChgCrsTT1stDay + 172)
#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 173)
#define ActRcvSvyQst (ActChgCrsTT1stDay + 174)
#define ActReqRemSvyQst (ActChgCrsTT1stDay + 175)
#define ActRemSvyQst (ActChgCrsTT1stDay + 176)
#define ActSeeSvy (ActChgCrsTT1stDay + 162)
#define ActAnsSvy (ActChgCrsTT1stDay + 163)
#define ActFrmNewSvy (ActChgCrsTT1stDay + 164)
#define ActEdiOneSvy (ActChgCrsTT1stDay + 165)
#define ActNewSvy (ActChgCrsTT1stDay + 166)
#define ActChgSvy (ActChgCrsTT1stDay + 167)
#define ActReqRemSvy (ActChgCrsTT1stDay + 168)
#define ActRemSvy (ActChgCrsTT1stDay + 169)
#define ActReqRstSvy (ActChgCrsTT1stDay + 170)
#define ActRstSvy (ActChgCrsTT1stDay + 171)
#define ActHidSvy (ActChgCrsTT1stDay + 172)
#define ActShoSvy (ActChgCrsTT1stDay + 173)
#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 174)
#define ActRcvSvyQst (ActChgCrsTT1stDay + 175)
#define ActReqRemSvyQst (ActChgCrsTT1stDay + 176)
#define ActRemSvyQst (ActChgCrsTT1stDay + 177)
#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 177)
#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 178)
#define ActEdiExaAnn (ActChgCrsTT1stDay + 179)
#define ActRcvExaAnn (ActChgCrsTT1stDay + 180)
#define ActPrnExaAnn (ActChgCrsTT1stDay + 181)
#define ActReqRemExaAnn (ActChgCrsTT1stDay + 182)
#define ActRemExaAnn (ActChgCrsTT1stDay + 183)
#define ActHidExaAnn (ActChgCrsTT1stDay + 184)
#define ActShoExaAnn (ActChgCrsTT1stDay + 185)
#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 178)
#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 179)
#define ActEdiExaAnn (ActChgCrsTT1stDay + 180)
#define ActRcvExaAnn (ActChgCrsTT1stDay + 181)
#define ActPrnExaAnn (ActChgCrsTT1stDay + 182)
#define ActReqRemExaAnn (ActChgCrsTT1stDay + 183)
#define ActRemExaAnn (ActChgCrsTT1stDay + 184)
#define ActHidExaAnn (ActChgCrsTT1stDay + 185)
#define ActShoExaAnn (ActChgCrsTT1stDay + 186)
/*****************************************************************************/
/******************************** Files tab **********************************/

View File

@ -490,14 +490,19 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
En OpenSWAD:
ps2pdf source.ps destination.pdf
*/
#define Log_PLATFORM_VERSION "SWAD 19.89.2 (2019-12-11)"
#define CSS_FILE "swad19.88.5.css"
#define Log_PLATFORM_VERSION "SWAD 19.90 (2019-12-12)"
#define CSS_FILE "swad19.90.css"
#define JS_FILE "swad19.70.js"
/*
// TODO: Hacer un nuevo rol en los TFG: tutor externo (profesor de áreas no vinculadas con el centro, profesionales de empresas, etc.)
// TODO: Impedir la creación y edición de proyectos si no son editables.
Version 19.89.2: Dec 11, 2019 Code refactoring in matches. (248207 lines)
Version 19.90: Dec 12, 2019 Hourglass to start countdown. (248373 lines)
2 changes necessary in database:
ALTER TABLE mch_matches ADD COLUMN Countdown INT NOT NULL DEFAULT -1 AFTER Showing;
INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1814','es','N','Comenzar cuenta atrás en partida');
Version 19.89.2: Dec 12, 2019 Code refactoring in matches. (248207 lines)
Version 19.89.1: Dec 11, 2019 Code refactoring in pagination. (248171 lines)
Version 19.89: Dec 10, 2019 Game dates are in red colour if all their matches are finished or ot don't have matches. (248186 lines)
4 changes necessary in database:

View File

@ -1384,11 +1384,12 @@ mysql> DESCRIBE mch_matches;
| QstInd | int(11) | NO | | 0 | |
| QstCod | int(11) | NO | | -1 | |
| Showing | enum('start','stem','answers','results','end') | NO | | start | |
| Countdown | int(11) | NO | | -1 | |
| NumCols | int(11) | NO | | 1 | |
| ShowQstResults | enum('N','Y') | NO | | N | |
| ShowUsrResults | enum('N','Y') | NO | | N | |
+----------------+------------------------------------------------+------+-----+---------+----------------+
12 rows in set (0.00 sec)
13 rows in set (0.00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS mch_matches ("
"MchCod INT NOT NULL AUTO_INCREMENT,"
@ -1400,6 +1401,7 @@ mysql> DESCRIBE mch_matches;
"QstInd INT NOT NULL DEFAULT 0,"
"QstCod INT NOT NULL DEFAULT -1,"
"Showing ENUM('start','stem','answers','results','end') NOT NULL DEFAULT 'start',"
"Countdown INT NOT NULL DEFAULT -1,"
"NumCols INT NOT NULL DEFAULT 1,"
"ShowQstResults ENUM('N','Y') NOT NULL DEFAULT 'N',"
"ShowUsrResults ENUM('N','Y') NOT NULL DEFAULT 'N',"

View File

@ -685,6 +685,7 @@ static void Lay_WriteScriptInit (void)
break;
case ActNewMch:
case ActResMch:
case ActMchCntDwn:
case ActBckMch:
case ActPlyPauMch:
case ActFwdMch:
@ -822,6 +823,7 @@ static void Lay_WriteScriptParamsAJAX (void)
/* Parameters related with match refreshing (for teachers) */
case ActNewMch:
case ActResMch:
case ActMchCntDwn:
case ActBckMch:
case ActPlyPauMch:
case ActFwdMch:

View File

@ -163,6 +163,7 @@ static void Mch_ShowLeftColumnTch (struct Match *Match);
static void Mch_ShowRefreshablePartTch (struct Match *Match);
static void Mch_WriteElapsedTimeInMch (struct Match *Match);
static void Mch_WriteElapsedTimeInQst (struct Match *Match);
static void Mch_WriteHourglass (struct Match *Match);
static void Mch_WriteNumRespondersQst (struct Match *Match);
static void Mch_ShowRightColumnTch (const struct Match *Match);
@ -263,9 +264,10 @@ void Mch_ListMatches (struct Game *Game,bool PutFormNewMatch)
"QstInd," // row[ 6]
"QstCod," // row[ 7]
"Showing," // row[ 8]
"NumCols," // row[ 9]
"ShowQstResults," // row[10]
"ShowUsrResults" // row[11]
"Countdown," // row[ 9]
"NumCols," // row[10]
"ShowQstResults," // row[11]
"ShowUsrResults" // row[12]
" FROM mch_matches"
" WHERE GamCod=%ld%s"
" ORDER BY MchCod",
@ -335,9 +337,10 @@ void Mch_GetDataOfMatchByCod (struct Match *Match)
"QstInd," // row[ 6]
"QstCod," // row[ 7]
"Showing," // row[ 8]
"NumCols," // row[ 9]
"ShowQstResults," // row[10]
"ShowUsrResults" // row[11]
"Countdown," // row[ 9]
"NumCols," // row[10]
"ShowQstResults," // row[11]
"ShowUsrResults" // row[12]
" FROM mch_matches"
" WHERE MchCod=%ld"
" AND GamCod IN" // Extra check
@ -363,6 +366,7 @@ void Mch_GetDataOfMatchByCod (struct Match *Match)
Match->Status.QstCod = -1L;
Match->Status.QstStartTimeUTC = (time_t) 0;
Match->Status.Showing = Mch_START;
Match->Status.Countdown = -1L;
Match->Status.Playing = false;
Match->Status.NumPlayers = 0;
Match->Status.NumCols = Mch_NUM_COLS_DEFAULT;
@ -894,9 +898,10 @@ static void Mch_GetMatchDataFromRow (MYSQL_RES *mysql_res,
row[ 6] QstInd
row[ 7] QstCod
row[ 8] Showing
row[ 9] NumCols
row[10] ShowQstResults
row[11] ShowUsrResults
row[ 9] Countdown
row[10] NumCols
row[11] ShowQstResults
row[12] ShowUsrResults
*/
/* Current question index (row[6]) */
Match->Status.QstInd = Gam_GetQstIndFromStr (row[6]);
@ -907,17 +912,20 @@ static void Mch_GetMatchDataFromRow (MYSQL_RES *mysql_res,
/* Get what to show (stem, answers, results) (row(8)) */
Match->Status.Showing = Mch_GetShowingFromStr (row[8]);
/* Get number of columns (row[9]) */
LongNum = Str_ConvertStrCodToLongCod (row[9]);
/* Get countdown (row[9]) */
Match->Status.Countdown = Str_ConvertStrCodToLongCod (row[9]);
/* Get number of columns (row[10]) */
LongNum = Str_ConvertStrCodToLongCod (row[10]);
Match->Status.NumCols = (LongNum <= 1 ) ? 1 :
((LongNum >= Mch_MAX_COLS) ? Mch_MAX_COLS :
(unsigned) LongNum);
/* Get whether to show question results or not (row(10)) */
Match->Status.ShowQstResults = (row[10][0] == 'Y');
/* Get whether to show question results or not (row(11)) */
Match->Status.ShowQstResults = (row[11][0] == 'Y');
/* Get whether to show user results or not (row(11)) */
Match->Status.ShowUsrResults = (row[11][0] == 'Y');
/* Get whether to show user results or not (row(12)) */
Match->Status.ShowUsrResults = (row[12][0] == 'Y');
/***** Get whether the match is being played or not *****/
if (Match->Status.Showing == Mch_END) // Match over
@ -934,7 +942,7 @@ static Mch_Showing_t Mch_GetShowingFromStr (const char *Str)
{
Mch_Showing_t Showing;
for (Showing = (Mch_Showing_t) 0;
for (Showing = (Mch_Showing_t) 0;
Showing <= (Mch_Showing_t) (Mch_NUM_SHOWING - 1);
Showing++)
if (!strcmp (Str,Mch_ShowingStringsDB[Showing]))
@ -1391,8 +1399,8 @@ static long Mch_CreateMatch (long GamCod,char Title[Gam_MAX_BYTES_TITLE + 1])
MchCod = DB_QueryINSERTandReturnCode ("can not create match",
"INSERT mch_matches "
"(GamCod,UsrCod,StartTime,EndTime,Title,"
"QstInd,QstCod,Showing,NumCols,"
"ShowQstResults,ShowUsrResults)"
"QstInd,QstCod,Showing,Countdown,"
"NumCols,ShowQstResults,ShowUsrResults)"
" VALUES "
"(%ld," // GamCod
"%ld," // UsrCod
@ -1402,6 +1410,7 @@ static long Mch_CreateMatch (long GamCod,char Title[Gam_MAX_BYTES_TITLE + 1])
"0," // QstInd: Match has not started, so not the first question yet
"-1," // QstCod: Non-existent question
"'%s'," // Showing: What is being shown
"-1," // Countdown: No countdown
"%u," // NumCols: Number of columns in answers
"'N'," // ShowQstResults: Don't show question results initially
"'N')", // ShowUsrResults: Don't show user results initially
@ -1637,18 +1646,21 @@ void Mch_RemoveGroupsOfType (long GrpTypCod)
/***************** Insert/update a game match being played *******************/
/*****************************************************************************/
#define Mch_MAX_BYTES_SUBQUERY 128
static void Mch_UpdateMatchStatusInDB (const struct Match *Match)
{
char MchSubQuery[Mch_MAX_BYTES_SUBQUERY];
char *MchSubQuery;
/***** Update end time only if match is currently being played *****/
if (Match->Status.Playing) // Match is being played
Str_Copy (MchSubQuery,"mch_matches.EndTime=NOW(),",
Mch_MAX_BYTES_SUBQUERY);
{
if (asprintf (&MchSubQuery,"mch_matches.EndTime=NOW(),") < 0) // Background
Lay_NotEnoughMemoryExit ();
}
else // Match is paused, not being played
MchSubQuery[0] = '\0';
{
if (asprintf (&MchSubQuery,"%s","") < 0)
Lay_NotEnoughMemoryExit ();
}
/***** Update match status in database *****/
DB_QueryUPDATE ("can not update match being played",
@ -1657,6 +1669,7 @@ static void Mch_UpdateMatchStatusInDB (const struct Match *Match)
"mch_matches.QstInd=%u,"
"mch_matches.QstCod=%ld,"
"mch_matches.Showing='%s',"
"mch_matches.Countdown=%ld,"
"mch_matches.NumCols=%u,"
"mch_matches.ShowQstResults='%c'"
" WHERE mch_matches.MchCod=%ld"
@ -1665,9 +1678,11 @@ static void Mch_UpdateMatchStatusInDB (const struct Match *Match)
MchSubQuery,
Match->Status.QstInd,Match->Status.QstCod,
Mch_ShowingStringsDB[Match->Status.Showing],
Match->Status.Countdown,
Match->Status.NumCols,
Match->Status.ShowQstResults ? 'Y' : 'N',
Match->MchCod,Gbl.Hierarchy.Crs.CrsCod);
free (MchSubQuery);
if (Match->Status.Playing) // Match is being played
/* Update match as being played */
@ -1871,6 +1886,40 @@ void Mch_ToggleVisibilResultsMchQst (void)
HTM_DIV_End ();
}
/*****************************************************************************/
/******************** Start match countdown (by a teacher) *******************/
/*****************************************************************************/
void Mch_StartCountdown (void)
{
struct Match Match;
long NewCountdown;
/***** Get countdown parameter ****/
NewCountdown = Par_GetParToLong ("Countdown");
/***** Remove old players.
This function must be called by a teacher
before getting match status. *****/
Mch_RemoveOldPlayers ();
/***** Get data of the match from database *****/
Match.MchCod = Gbl.Games.MchCodBeingPlayed;
Mch_GetDataOfMatchByCod (&Match);
/***** Start countdown *****/
if (NewCountdown >= 0)
Match.Status.Countdown = NewCountdown;
/***** Update match status in database *****/
Mch_UpdateMatchStatusInDB (&Match);
/***** Show current match status *****/
HTM_DIV_Begin ("id=\"match\" class=\"MCH_CONT\"");
Mch_ShowMatchStatusForTch (&Match);
HTM_DIV_End ();
}
/*****************************************************************************/
/************* Show previous question in a match (by a teacher) **************/
/*****************************************************************************/
@ -1952,6 +2001,7 @@ static void Mch_SetMatchStatusToPrev (struct Match *Match)
Match->Status.Showing = Mch_ANSWERS;
break;
}
Match->Status.Countdown = -1L; // No countdown
}
static void Mch_SetMatchStatusToPrevQst (struct Match *Match)
@ -2006,6 +2056,7 @@ static void Mch_SetMatchStatusToNext (struct Match *Match)
Mch_SetMatchStatusToEnd (Match);
break;
}
Match->Status.Countdown = -1L; // No countdown
}
static void Mch_SetMatchStatusToNextQst (struct Match *Match)
@ -2186,6 +2237,9 @@ static void Mch_ShowRefreshablePartTch (struct Match *Match)
/***** Write elapsed time in question *****/
Mch_WriteElapsedTimeInQst (Match);
/***** Write hourglass *****/
Mch_WriteHourglass (Match);
/***** Number of users who have responded this question *****/
Mch_WriteNumRespondersQst (Match);
}
@ -2226,6 +2280,87 @@ static void Mch_WriteElapsedTimeInQst (struct Match *Match)
HTM_DIV_End ();
}
static void Mch_WriteHourglass (struct Match *Match)
{
/***** Start container *****/
HTM_DIV_Begin ("class=\"MCH_SHOW_HOURGLASS\"");
/***** Start form *****/
Frm_StartForm (ActMchCntDwn);
Mch_PutParamMchCod (Match->MchCod); // Current match being played
/***** Put icon with link *****/
HTM_DIV_Begin ("class=\"MCH_BUTTON_CONTAINER\"");
HTM_BUTTON_OnMouseDown_Begin ("Cuenta atr&aacute;s","BT_LINK MCH_BUTTON_ON ICO_BLACK"); // TODO: Need translation!!!!
HTM_TxtF ("<i class=\"fas %s\"></i>",
Match->Status.Countdown < 0 ? "fa-hourglass-start" : // No countdown
(Match->Status.Countdown > Cfg_SECONDS_TO_REFRESH_MATCH_TCH) ? "fa-hourglass-half" : // Countdown in progress
"fa-hourglass-end"); // Countdown about to end
HTM_BR ();
if (Match->Status.Countdown > 0)
HTM_TxtF ("%ld&quot;",Match->Status.Countdown);
else
HTM_NBSP ();
HTM_BUTTON_End ();
HTM_DIV_End ();
/***** End form *****/
Frm_EndForm ();
HTM_BR ();
/***** Start form *****/
Frm_StartForm (ActMchCntDwn);
Mch_PutParamMchCod (Match->MchCod); // Current match being played
Par_PutHiddenParamLong (NULL,"Countdown",60L);
/***** Put icon with link *****/
HTM_DIV_Begin ("class=\"MCH_SMALLBUTTON_CONTAINER\"");
HTM_BUTTON_OnMouseDown_Begin ("Cuenta atr&aacute;s","BT_LINK MCH_BUTTON_ON ICO_BLACK"); // TODO: Need translation!!!!
HTM_Txt ("60&quot;");
HTM_BUTTON_End ();
HTM_DIV_End ();
/***** End form *****/
Frm_EndForm ();
HTM_NBSP ();
/***** Start form *****/
Frm_StartForm (ActMchCntDwn);
Mch_PutParamMchCod (Match->MchCod); // Current match being played
Par_PutHiddenParamLong (NULL,"Countdown",30L);
/***** Put icon with link *****/
HTM_DIV_Begin ("class=\"MCH_SMALLBUTTON_CONTAINER\"");
HTM_BUTTON_OnMouseDown_Begin ("Cuenta atr&aacute;s","BT_LINK MCH_BUTTON_ON ICO_BLACK"); // TODO: Need translation!!!!
HTM_Txt ("30&quot;");
HTM_BUTTON_End ();
HTM_DIV_End ();
/***** End form *****/
Frm_EndForm ();
HTM_NBSP ();
/***** Start form *****/
Frm_StartForm (ActMchCntDwn);
Mch_PutParamMchCod (Match->MchCod); // Current match being played
Par_PutHiddenParamLong (NULL,"Countdown",10L);
/***** Put icon with link *****/
HTM_DIV_Begin ("class=\"MCH_SMALLBUTTON_CONTAINER\"");
HTM_BUTTON_OnMouseDown_Begin ("Cuenta atr&aacute;s","BT_LINK MCH_BUTTON_ON ICO_BLACK"); // TODO: Need translation!!!!
HTM_Txt ("10&quot;");
HTM_BUTTON_End ();
HTM_DIV_End ();
/***** End form *****/
Frm_EndForm ();
/***** End container *****/
HTM_DIV_End ();
}
static void Mch_WriteNumRespondersQst (struct Match *Match)
{
extern const char *Txt_MATCH_respond;
@ -2538,10 +2673,10 @@ static void Mch_PutCheckboxResult (const struct Match *Match)
{
extern const char *Txt_View_results;
/***** Start container *****/
/***** Begin container *****/
HTM_DIV_Begin ("class=\"MCH_SHOW_RESULTS\"");
/***** Start form *****/
/***** Begin form *****/
Frm_StartForm (ActChgVisResMchQst);
Mch_PutParamMchCod (Match->MchCod); // Current match being played
@ -2571,7 +2706,7 @@ static void Mch_PutIfAnswered (const struct Match *Match,bool Answered)
extern const char *Txt_MATCH_QUESTION_Unanswered;
/***** Start container *****/
HTM_DIV_Begin ("class=\"MCH_SHOW_RESULTS\"");
HTM_DIV_Begin ("class=\"MCH_SHOW_ANSWERED\"");
/***** Put icon with link *****/
if (Match->Status.Playing && // Match is being played
@ -2617,7 +2752,7 @@ static void Mch_PutIconToRemoveMyAnswer (const struct Match *Match)
extern const char *Txt_Delete_my_answer;
/***** Start container *****/
HTM_DIV_Begin ("class=\"MCH_SHOW_RESULTS\"");
HTM_DIV_Begin ("class=\"MCH_REM_MY_ANS\"");
/***** Start form *****/
Frm_StartForm (ActRemMchAnsQstStd);
@ -3275,6 +3410,7 @@ void Mch_RemoveMyQuestionAnswer (void)
void Mch_RefreshMatchTch (void)
{
struct Match Match;
enum {REFRESH_LEFT,REFRESH_ALL} WhatToRefresh;
if (!Gbl.Session.IsOpen) // If session has been closed, do not write anything
return;
@ -3288,6 +3424,23 @@ void Mch_RefreshMatchTch (void)
Match.MchCod = Gbl.Games.MchCodBeingPlayed;
Mch_GetDataOfMatchByCod (&Match);
/***** Update countdown *****/
// If current countdown is < 0 ==> no countdown in progress
WhatToRefresh = REFRESH_LEFT;
if (Match.Status.Playing && // Match is being played
Match.Status.Countdown >= 0) // Countdown in progress
{
/* Decrease countdown */
Match.Status.Countdown -= Cfg_SECONDS_TO_REFRESH_MATCH_TCH;
/* On countdown reached, set match status to next (forward) status */
if (Match.Status.Countdown <= 0) // End of countdown reached
{
Mch_SetMatchStatusToNext (&Match);
WhatToRefresh = REFRESH_ALL; // Refresh the whole page
}
}
/***** Update match status in database *****/
Mch_UpdateMatchStatusInDB (&Match);
@ -3295,7 +3448,17 @@ void Mch_RefreshMatchTch (void)
Mch_UpdateElapsedTimeInQuestion (&Match);
/***** Show current match status *****/
Mch_ShowRefreshablePartTch (&Match);
switch (WhatToRefresh)
{
case REFRESH_LEFT: // Refresh only left part
HTM_TxtF ("match_left|",Cfg_TIME_TO_REFRESH_LAST_CLICKS);
Mch_ShowRefreshablePartTch (&Match);
break;
case REFRESH_ALL: // Refresh the whole page
HTM_TxtF ("match|",Cfg_TIME_TO_REFRESH_LAST_CLICKS);
Mch_ShowMatchStatusForTch (&Match);
break;
}
}
/*****************************************************************************/

View File

@ -61,6 +61,9 @@ struct Match
long QstCod;
time_t QstStartTimeUTC;
Mch_Showing_t Showing; // What is shown on teacher's screen
long Countdown; // > 0 ==> countdown in progress
// = 0 ==> countdown over ==> go to next step
// < 0 ==> no countdown at this time
unsigned NumCols; // Number of columns for answers on teacher's screen
bool ShowQstResults; // Show global results of current question while playing
bool ShowUsrResults; // Show exam with results of all questions for the student
@ -106,6 +109,7 @@ void Mch_RemoveGroupsOfType (long GrpTypCod);
void Mch_PlayPauseMatch (void);
void Mch_ChangeNumColsMch (void);
void Mch_ToggleVisibilResultsMchQst (void);
void Mch_StartCountdown (void);
void Mch_BackMatch (void);
void Mch_ForwardMatch (void);