diff --git a/swad_ID.c b/swad_ID.c index 43ddb629..8a046fa4 100644 --- a/swad_ID.c +++ b/swad_ID.c @@ -1012,9 +1012,7 @@ void ID_ConfirmOtherUsrID (void) check if he/she has accepted */ if (Gbl.CurrentCrs.Crs.CrsCod > 0) if (Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role == Rol_STD) - Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrBelongsToCrs (Gbl.Usrs.Other.UsrDat.UsrCod, - Gbl.CurrentCrs.Crs.CrsCod, - true); + Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); if (ID_ICanSeeOtherUsrIDs (&Gbl.Usrs.Other.UsrDat)) ICanConfirm = true; diff --git a/swad_action.c b/swad_action.c index 2a6dea9c..55a31187 100644 --- a/swad_action.c +++ b/swad_action.c @@ -1287,6 +1287,15 @@ Users: 1085. ActLstSimUsr List users similar to a given one (possible duplicates) 1086. ActRemDupUsr Remove user from list of possible duplicate users + NEW. ActReqFolSevStd Request follow several students + NEW. ActReqFolSevTch Request follow several teachers + NEW. ActReqUnfSevStd Request unfollow several students + NEW. ActReqUnfSevTch Request unfollow several teachers + NEW. ActFolSevStd Follow several students + NEW. ActFolSevTch Follow several teachers + NEW. ActUnfSevStd Unfollow several students + NEW. ActUnfSevTch Unfollow several teachers + Messages: 1087. ActSeeAnn Show global announcements 1088. ActSeeAllNot Show all notices @@ -2836,6 +2845,15 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActLstSimUsr */{1579,-1,TabUnk,ActLstOth ,0x200,0x200,0x200,0x200,0x200,0x200,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Dup_GetUsrCodAndListSimilarUsrs,NULL}, /* ActRemDupUsr */{1580,-1,TabUnk,ActLstOth ,0x200,0x200,0x200,0x200,0x200,0x200,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Dup_RemoveUsrFromListDupUsrs ,NULL}, + /* ActReqFolSevStd */{1756,-1,TabUnk,ActLstStd ,0x3F8,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Fol_RequestFollowStds ,NULL}, + /* ActReqFolSevTch */{1757,-1,TabUnk,ActLstTch ,0x3F8,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Fol_RequestFollowTchs ,NULL}, + /* ActReqUnfSevStd */{1758,-1,TabUnk,ActLstStd ,0x3F8,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Fol_RequestUnfollowStds ,NULL}, + /* ActReqUnfSevTch */{1759,-1,TabUnk,ActLstTch ,0x3F8,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Fol_RequestUnfollowTchs ,NULL}, + /* ActFolSevStd */{1760,-1,TabUnk,ActLstStd ,0x3F8,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Fol_FollowUsrs ,NULL}, + /* ActFolSevTch */{1761,-1,TabUnk,ActLstTch ,0x3F8,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Fol_FollowUsrs ,NULL}, + /* ActUnfSevStd */{1762,-1,TabUnk,ActLstStd ,0x3F8,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Fol_UnfollowUsrs ,NULL}, + /* ActUnfSevTch */{1763,-1,TabUnk,ActLstTch ,0x3F8,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Fol_UnfollowUsrs ,NULL}, + // TabMsg ****************************************************************** // Actions in menu: /* ActSeeAnn */{1235, 0,TabMsg,ActSeeAnn ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Ann_ShowAllAnnouncements ,"bullhorn" }, @@ -4892,6 +4910,14 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActDoActOnSevGst, // #1753 ActDoActOnSevStd, // #1754 ActDoActOnSevTch, // #1755 + ActReqFolSevStd, // #1756 + ActReqFolSevTch, // #1757 + ActReqUnfSevStd, // #1758 + ActReqUnfSevTch, // #1759 + ActFolSevStd, // #1760 + ActFolSevTch, // #1761 + ActUnfSevStd, // #1762 + ActUnfSevTch, // #1763 }; /*****************************************************************************/ diff --git a/swad_action.h b/swad_action.h index e6693bc4..1428d7d5 100644 --- a/swad_action.h +++ b/swad_action.h @@ -61,9 +61,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 + 55 + 38 + 12 + 42 + 36 + 19 + 110 + 157 + 437 + 168 + 168 + 15 + 65) +#define Act_NUM_ACTIONS (1 + 8 + 55 + 38 + 12 + 42 + 36 + 19 + 110 + 157 + 437 + 176 + 168 + 15 + 65) -#define Act_MAX_ACTION_COD 1755 +#define Act_MAX_ACTION_COD 1763 #define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13 @@ -1310,182 +1310,191 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to #define ActLstSimUsr (ActRemOldBrf + 167) #define ActRemDupUsr (ActRemOldBrf + 168) +#define ActReqFolSevStd (ActRemOldBrf + 169) +#define ActReqFolSevTch (ActRemOldBrf + 170) +#define ActReqUnfSevStd (ActRemOldBrf + 171) +#define ActReqUnfSevTch (ActRemOldBrf + 172) +#define ActFolSevStd (ActRemOldBrf + 173) +#define ActFolSevTch (ActRemOldBrf + 174) +#define ActUnfSevStd (ActRemOldBrf + 175) +#define ActUnfSevTch (ActRemOldBrf + 176) + /*****************************************************************************/ /******************************* Messages tab ********************************/ /*****************************************************************************/ // Actions in menu -#define ActSeeAnn (ActRemDupUsr + 1) -#define ActSeeAllNot (ActRemDupUsr + 2) -#define ActSeeFor (ActRemDupUsr + 3) -#define ActSeeChtRms (ActRemDupUsr + 4) -#define ActReqMsgUsr (ActRemDupUsr + 5) -#define ActSeeRcvMsg (ActRemDupUsr + 6) -#define ActSeeSntMsg (ActRemDupUsr + 7) -#define ActMaiStd (ActRemDupUsr + 8) +#define ActSeeAnn (ActUnfSevTch + 1) +#define ActSeeAllNot (ActUnfSevTch + 2) +#define ActSeeFor (ActUnfSevTch + 3) +#define ActSeeChtRms (ActUnfSevTch + 4) +#define ActReqMsgUsr (ActUnfSevTch + 5) +#define ActSeeRcvMsg (ActUnfSevTch + 6) +#define ActSeeSntMsg (ActUnfSevTch + 7) +#define ActMaiStd (ActUnfSevTch + 8) // Secondary actions -#define ActWriAnn (ActRemDupUsr + 9) -#define ActRcvAnn (ActRemDupUsr + 10) -#define ActHidAnn (ActRemDupUsr + 11) -#define ActRevAnn (ActRemDupUsr + 12) -#define ActRemAnn (ActRemDupUsr + 13) -#define ActSeeOneNot (ActRemDupUsr + 14) -#define ActWriNot (ActRemDupUsr + 15) -#define ActRcvNot (ActRemDupUsr + 16) -#define ActHidNot (ActRemDupUsr + 17) -#define ActRevNot (ActRemDupUsr + 18) -#define ActReqRemNot (ActRemDupUsr + 19) -#define ActRemNot (ActRemDupUsr + 20) +#define ActWriAnn (ActUnfSevTch + 9) +#define ActRcvAnn (ActUnfSevTch + 10) +#define ActHidAnn (ActUnfSevTch + 11) +#define ActRevAnn (ActUnfSevTch + 12) +#define ActRemAnn (ActUnfSevTch + 13) +#define ActSeeOneNot (ActUnfSevTch + 14) +#define ActWriNot (ActUnfSevTch + 15) +#define ActRcvNot (ActUnfSevTch + 16) +#define ActHidNot (ActUnfSevTch + 17) +#define ActRevNot (ActUnfSevTch + 18) +#define ActReqRemNot (ActUnfSevTch + 19) +#define ActRemNot (ActUnfSevTch + 20) -#define ActSeeForCrsUsr (ActRemDupUsr + 21) -#define ActSeeForCrsTch (ActRemDupUsr + 22) -#define ActSeeForDegUsr (ActRemDupUsr + 23) -#define ActSeeForDegTch (ActRemDupUsr + 24) -#define ActSeeForCtrUsr (ActRemDupUsr + 25) -#define ActSeeForCtrTch (ActRemDupUsr + 26) -#define ActSeeForInsUsr (ActRemDupUsr + 27) -#define ActSeeForInsTch (ActRemDupUsr + 28) -#define ActSeeForGenUsr (ActRemDupUsr + 29) -#define ActSeeForGenTch (ActRemDupUsr + 30) -#define ActSeeForSWAUsr (ActRemDupUsr + 31) -#define ActSeeForSWATch (ActRemDupUsr + 32) -#define ActSeePstForCrsUsr (ActRemDupUsr + 33) -#define ActSeePstForCrsTch (ActRemDupUsr + 34) -#define ActSeePstForDegUsr (ActRemDupUsr + 35) -#define ActSeePstForDegTch (ActRemDupUsr + 36) -#define ActSeePstForCtrUsr (ActRemDupUsr + 37) -#define ActSeePstForCtrTch (ActRemDupUsr + 38) -#define ActSeePstForInsUsr (ActRemDupUsr + 39) -#define ActSeePstForInsTch (ActRemDupUsr + 40) -#define ActSeePstForGenUsr (ActRemDupUsr + 41) -#define ActSeePstForGenTch (ActRemDupUsr + 42) -#define ActSeePstForSWAUsr (ActRemDupUsr + 43) -#define ActSeePstForSWATch (ActRemDupUsr + 44) -#define ActRcvThrForCrsUsr (ActRemDupUsr + 45) -#define ActRcvThrForCrsTch (ActRemDupUsr + 46) -#define ActRcvThrForDegUsr (ActRemDupUsr + 47) -#define ActRcvThrForDegTch (ActRemDupUsr + 48) -#define ActRcvThrForCtrUsr (ActRemDupUsr + 49) -#define ActRcvThrForCtrTch (ActRemDupUsr + 50) -#define ActRcvThrForInsUsr (ActRemDupUsr + 51) -#define ActRcvThrForInsTch (ActRemDupUsr + 52) -#define ActRcvThrForGenUsr (ActRemDupUsr + 53) -#define ActRcvThrForGenTch (ActRemDupUsr + 54) -#define ActRcvThrForSWAUsr (ActRemDupUsr + 55) -#define ActRcvThrForSWATch (ActRemDupUsr + 56) -#define ActRcvRepForCrsUsr (ActRemDupUsr + 57) -#define ActRcvRepForCrsTch (ActRemDupUsr + 58) -#define ActRcvRepForDegUsr (ActRemDupUsr + 59) -#define ActRcvRepForDegTch (ActRemDupUsr + 60) -#define ActRcvRepForCtrUsr (ActRemDupUsr + 61) -#define ActRcvRepForCtrTch (ActRemDupUsr + 62) -#define ActRcvRepForInsUsr (ActRemDupUsr + 63) -#define ActRcvRepForInsTch (ActRemDupUsr + 64) -#define ActRcvRepForGenUsr (ActRemDupUsr + 65) -#define ActRcvRepForGenTch (ActRemDupUsr + 66) -#define ActRcvRepForSWAUsr (ActRemDupUsr + 67) -#define ActRcvRepForSWATch (ActRemDupUsr + 68) -#define ActReqDelThrCrsUsr (ActRemDupUsr + 69) -#define ActReqDelThrCrsTch (ActRemDupUsr + 70) -#define ActReqDelThrDegUsr (ActRemDupUsr + 71) -#define ActReqDelThrDegTch (ActRemDupUsr + 72) -#define ActReqDelThrCtrUsr (ActRemDupUsr + 73) -#define ActReqDelThrCtrTch (ActRemDupUsr + 74) -#define ActReqDelThrInsUsr (ActRemDupUsr + 75) -#define ActReqDelThrInsTch (ActRemDupUsr + 76) -#define ActReqDelThrGenUsr (ActRemDupUsr + 77) -#define ActReqDelThrGenTch (ActRemDupUsr + 78) -#define ActReqDelThrSWAUsr (ActRemDupUsr + 79) -#define ActReqDelThrSWATch (ActRemDupUsr + 80) -#define ActDelThrForCrsUsr (ActRemDupUsr + 81) -#define ActDelThrForCrsTch (ActRemDupUsr + 82) -#define ActDelThrForDegUsr (ActRemDupUsr + 83) -#define ActDelThrForDegTch (ActRemDupUsr + 84) -#define ActDelThrForCtrUsr (ActRemDupUsr + 85) -#define ActDelThrForCtrTch (ActRemDupUsr + 86) -#define ActDelThrForInsUsr (ActRemDupUsr + 87) -#define ActDelThrForInsTch (ActRemDupUsr + 88) -#define ActDelThrForGenUsr (ActRemDupUsr + 89) -#define ActDelThrForGenTch (ActRemDupUsr + 90) -#define ActDelThrForSWAUsr (ActRemDupUsr + 91) -#define ActDelThrForSWATch (ActRemDupUsr + 92) -#define ActCutThrForCrsUsr (ActRemDupUsr + 93) -#define ActCutThrForCrsTch (ActRemDupUsr + 94) -#define ActCutThrForDegUsr (ActRemDupUsr + 95) -#define ActCutThrForDegTch (ActRemDupUsr + 96) -#define ActCutThrForCtrUsr (ActRemDupUsr + 97) -#define ActCutThrForCtrTch (ActRemDupUsr + 98) -#define ActCutThrForInsUsr (ActRemDupUsr + 99) -#define ActCutThrForInsTch (ActRemDupUsr + 100) -#define ActCutThrForGenUsr (ActRemDupUsr + 101) -#define ActCutThrForGenTch (ActRemDupUsr + 102) -#define ActCutThrForSWAUsr (ActRemDupUsr + 103) -#define ActCutThrForSWATch (ActRemDupUsr + 104) -#define ActPasThrForCrsUsr (ActRemDupUsr + 105) -#define ActPasThrForCrsTch (ActRemDupUsr + 106) -#define ActPasThrForDegUsr (ActRemDupUsr + 107) -#define ActPasThrForDegTch (ActRemDupUsr + 108) -#define ActPasThrForCtrUsr (ActRemDupUsr + 109) -#define ActPasThrForCtrTch (ActRemDupUsr + 110) -#define ActPasThrForInsUsr (ActRemDupUsr + 111) -#define ActPasThrForInsTch (ActRemDupUsr + 112) -#define ActPasThrForGenUsr (ActRemDupUsr + 113) -#define ActPasThrForGenTch (ActRemDupUsr + 114) -#define ActPasThrForSWAUsr (ActRemDupUsr + 115) -#define ActPasThrForSWATch (ActRemDupUsr + 116) -#define ActDelPstForCrsUsr (ActRemDupUsr + 117) -#define ActDelPstForCrsTch (ActRemDupUsr + 118) -#define ActDelPstForDegUsr (ActRemDupUsr + 119) -#define ActDelPstForDegTch (ActRemDupUsr + 120) -#define ActDelPstForCtrUsr (ActRemDupUsr + 121) -#define ActDelPstForCtrTch (ActRemDupUsr + 122) -#define ActDelPstForInsUsr (ActRemDupUsr + 123) -#define ActDelPstForInsTch (ActRemDupUsr + 124) -#define ActDelPstForGenUsr (ActRemDupUsr + 125) -#define ActDelPstForGenTch (ActRemDupUsr + 126) -#define ActDelPstForSWAUsr (ActRemDupUsr + 127) -#define ActDelPstForSWATch (ActRemDupUsr + 128) -#define ActEnbPstForCrsUsr (ActRemDupUsr + 129) -#define ActEnbPstForCrsTch (ActRemDupUsr + 130) -#define ActEnbPstForDegUsr (ActRemDupUsr + 131) -#define ActEnbPstForDegTch (ActRemDupUsr + 132) -#define ActEnbPstForCtrUsr (ActRemDupUsr + 133) -#define ActEnbPstForCtrTch (ActRemDupUsr + 134) -#define ActEnbPstForInsUsr (ActRemDupUsr + 135) -#define ActEnbPstForInsTch (ActRemDupUsr + 136) -#define ActEnbPstForGenUsr (ActRemDupUsr + 137) -#define ActEnbPstForGenTch (ActRemDupUsr + 138) -#define ActEnbPstForSWAUsr (ActRemDupUsr + 139) -#define ActEnbPstForSWATch (ActRemDupUsr + 140) -#define ActDisPstForCrsUsr (ActRemDupUsr + 141) -#define ActDisPstForCrsTch (ActRemDupUsr + 142) -#define ActDisPstForDegUsr (ActRemDupUsr + 143) -#define ActDisPstForDegTch (ActRemDupUsr + 144) -#define ActDisPstForCtrUsr (ActRemDupUsr + 145) -#define ActDisPstForCtrTch (ActRemDupUsr + 146) -#define ActDisPstForInsUsr (ActRemDupUsr + 147) -#define ActDisPstForInsTch (ActRemDupUsr + 148) -#define ActDisPstForGenUsr (ActRemDupUsr + 149) -#define ActDisPstForGenTch (ActRemDupUsr + 150) -#define ActDisPstForSWAUsr (ActRemDupUsr + 151) -#define ActDisPstForSWATch (ActRemDupUsr + 152) +#define ActSeeForCrsUsr (ActUnfSevTch + 21) +#define ActSeeForCrsTch (ActUnfSevTch + 22) +#define ActSeeForDegUsr (ActUnfSevTch + 23) +#define ActSeeForDegTch (ActUnfSevTch + 24) +#define ActSeeForCtrUsr (ActUnfSevTch + 25) +#define ActSeeForCtrTch (ActUnfSevTch + 26) +#define ActSeeForInsUsr (ActUnfSevTch + 27) +#define ActSeeForInsTch (ActUnfSevTch + 28) +#define ActSeeForGenUsr (ActUnfSevTch + 29) +#define ActSeeForGenTch (ActUnfSevTch + 30) +#define ActSeeForSWAUsr (ActUnfSevTch + 31) +#define ActSeeForSWATch (ActUnfSevTch + 32) +#define ActSeePstForCrsUsr (ActUnfSevTch + 33) +#define ActSeePstForCrsTch (ActUnfSevTch + 34) +#define ActSeePstForDegUsr (ActUnfSevTch + 35) +#define ActSeePstForDegTch (ActUnfSevTch + 36) +#define ActSeePstForCtrUsr (ActUnfSevTch + 37) +#define ActSeePstForCtrTch (ActUnfSevTch + 38) +#define ActSeePstForInsUsr (ActUnfSevTch + 39) +#define ActSeePstForInsTch (ActUnfSevTch + 40) +#define ActSeePstForGenUsr (ActUnfSevTch + 41) +#define ActSeePstForGenTch (ActUnfSevTch + 42) +#define ActSeePstForSWAUsr (ActUnfSevTch + 43) +#define ActSeePstForSWATch (ActUnfSevTch + 44) +#define ActRcvThrForCrsUsr (ActUnfSevTch + 45) +#define ActRcvThrForCrsTch (ActUnfSevTch + 46) +#define ActRcvThrForDegUsr (ActUnfSevTch + 47) +#define ActRcvThrForDegTch (ActUnfSevTch + 48) +#define ActRcvThrForCtrUsr (ActUnfSevTch + 49) +#define ActRcvThrForCtrTch (ActUnfSevTch + 50) +#define ActRcvThrForInsUsr (ActUnfSevTch + 51) +#define ActRcvThrForInsTch (ActUnfSevTch + 52) +#define ActRcvThrForGenUsr (ActUnfSevTch + 53) +#define ActRcvThrForGenTch (ActUnfSevTch + 54) +#define ActRcvThrForSWAUsr (ActUnfSevTch + 55) +#define ActRcvThrForSWATch (ActUnfSevTch + 56) +#define ActRcvRepForCrsUsr (ActUnfSevTch + 57) +#define ActRcvRepForCrsTch (ActUnfSevTch + 58) +#define ActRcvRepForDegUsr (ActUnfSevTch + 59) +#define ActRcvRepForDegTch (ActUnfSevTch + 60) +#define ActRcvRepForCtrUsr (ActUnfSevTch + 61) +#define ActRcvRepForCtrTch (ActUnfSevTch + 62) +#define ActRcvRepForInsUsr (ActUnfSevTch + 63) +#define ActRcvRepForInsTch (ActUnfSevTch + 64) +#define ActRcvRepForGenUsr (ActUnfSevTch + 65) +#define ActRcvRepForGenTch (ActUnfSevTch + 66) +#define ActRcvRepForSWAUsr (ActUnfSevTch + 67) +#define ActRcvRepForSWATch (ActUnfSevTch + 68) +#define ActReqDelThrCrsUsr (ActUnfSevTch + 69) +#define ActReqDelThrCrsTch (ActUnfSevTch + 70) +#define ActReqDelThrDegUsr (ActUnfSevTch + 71) +#define ActReqDelThrDegTch (ActUnfSevTch + 72) +#define ActReqDelThrCtrUsr (ActUnfSevTch + 73) +#define ActReqDelThrCtrTch (ActUnfSevTch + 74) +#define ActReqDelThrInsUsr (ActUnfSevTch + 75) +#define ActReqDelThrInsTch (ActUnfSevTch + 76) +#define ActReqDelThrGenUsr (ActUnfSevTch + 77) +#define ActReqDelThrGenTch (ActUnfSevTch + 78) +#define ActReqDelThrSWAUsr (ActUnfSevTch + 79) +#define ActReqDelThrSWATch (ActUnfSevTch + 80) +#define ActDelThrForCrsUsr (ActUnfSevTch + 81) +#define ActDelThrForCrsTch (ActUnfSevTch + 82) +#define ActDelThrForDegUsr (ActUnfSevTch + 83) +#define ActDelThrForDegTch (ActUnfSevTch + 84) +#define ActDelThrForCtrUsr (ActUnfSevTch + 85) +#define ActDelThrForCtrTch (ActUnfSevTch + 86) +#define ActDelThrForInsUsr (ActUnfSevTch + 87) +#define ActDelThrForInsTch (ActUnfSevTch + 88) +#define ActDelThrForGenUsr (ActUnfSevTch + 89) +#define ActDelThrForGenTch (ActUnfSevTch + 90) +#define ActDelThrForSWAUsr (ActUnfSevTch + 91) +#define ActDelThrForSWATch (ActUnfSevTch + 92) +#define ActCutThrForCrsUsr (ActUnfSevTch + 93) +#define ActCutThrForCrsTch (ActUnfSevTch + 94) +#define ActCutThrForDegUsr (ActUnfSevTch + 95) +#define ActCutThrForDegTch (ActUnfSevTch + 96) +#define ActCutThrForCtrUsr (ActUnfSevTch + 97) +#define ActCutThrForCtrTch (ActUnfSevTch + 98) +#define ActCutThrForInsUsr (ActUnfSevTch + 99) +#define ActCutThrForInsTch (ActUnfSevTch + 100) +#define ActCutThrForGenUsr (ActUnfSevTch + 101) +#define ActCutThrForGenTch (ActUnfSevTch + 102) +#define ActCutThrForSWAUsr (ActUnfSevTch + 103) +#define ActCutThrForSWATch (ActUnfSevTch + 104) +#define ActPasThrForCrsUsr (ActUnfSevTch + 105) +#define ActPasThrForCrsTch (ActUnfSevTch + 106) +#define ActPasThrForDegUsr (ActUnfSevTch + 107) +#define ActPasThrForDegTch (ActUnfSevTch + 108) +#define ActPasThrForCtrUsr (ActUnfSevTch + 109) +#define ActPasThrForCtrTch (ActUnfSevTch + 110) +#define ActPasThrForInsUsr (ActUnfSevTch + 111) +#define ActPasThrForInsTch (ActUnfSevTch + 112) +#define ActPasThrForGenUsr (ActUnfSevTch + 113) +#define ActPasThrForGenTch (ActUnfSevTch + 114) +#define ActPasThrForSWAUsr (ActUnfSevTch + 115) +#define ActPasThrForSWATch (ActUnfSevTch + 116) +#define ActDelPstForCrsUsr (ActUnfSevTch + 117) +#define ActDelPstForCrsTch (ActUnfSevTch + 118) +#define ActDelPstForDegUsr (ActUnfSevTch + 119) +#define ActDelPstForDegTch (ActUnfSevTch + 120) +#define ActDelPstForCtrUsr (ActUnfSevTch + 121) +#define ActDelPstForCtrTch (ActUnfSevTch + 122) +#define ActDelPstForInsUsr (ActUnfSevTch + 123) +#define ActDelPstForInsTch (ActUnfSevTch + 124) +#define ActDelPstForGenUsr (ActUnfSevTch + 125) +#define ActDelPstForGenTch (ActUnfSevTch + 126) +#define ActDelPstForSWAUsr (ActUnfSevTch + 127) +#define ActDelPstForSWATch (ActUnfSevTch + 128) +#define ActEnbPstForCrsUsr (ActUnfSevTch + 129) +#define ActEnbPstForCrsTch (ActUnfSevTch + 130) +#define ActEnbPstForDegUsr (ActUnfSevTch + 131) +#define ActEnbPstForDegTch (ActUnfSevTch + 132) +#define ActEnbPstForCtrUsr (ActUnfSevTch + 133) +#define ActEnbPstForCtrTch (ActUnfSevTch + 134) +#define ActEnbPstForInsUsr (ActUnfSevTch + 135) +#define ActEnbPstForInsTch (ActUnfSevTch + 136) +#define ActEnbPstForGenUsr (ActUnfSevTch + 137) +#define ActEnbPstForGenTch (ActUnfSevTch + 138) +#define ActEnbPstForSWAUsr (ActUnfSevTch + 139) +#define ActEnbPstForSWATch (ActUnfSevTch + 140) +#define ActDisPstForCrsUsr (ActUnfSevTch + 141) +#define ActDisPstForCrsTch (ActUnfSevTch + 142) +#define ActDisPstForDegUsr (ActUnfSevTch + 143) +#define ActDisPstForDegTch (ActUnfSevTch + 144) +#define ActDisPstForCtrUsr (ActUnfSevTch + 145) +#define ActDisPstForCtrTch (ActUnfSevTch + 146) +#define ActDisPstForInsUsr (ActUnfSevTch + 147) +#define ActDisPstForInsTch (ActUnfSevTch + 148) +#define ActDisPstForGenUsr (ActUnfSevTch + 149) +#define ActDisPstForGenTch (ActUnfSevTch + 150) +#define ActDisPstForSWAUsr (ActUnfSevTch + 151) +#define ActDisPstForSWATch (ActUnfSevTch + 152) -#define ActCht (ActRemDupUsr + 153) +#define ActCht (ActUnfSevTch + 153) -#define ActRcvMsgUsr (ActRemDupUsr + 154) -#define ActReqDelAllSntMsg (ActRemDupUsr + 155) -#define ActReqDelAllRcvMsg (ActRemDupUsr + 156) -#define ActDelAllSntMsg (ActRemDupUsr + 157) -#define ActDelAllRcvMsg (ActRemDupUsr + 158) -#define ActDelSntMsg (ActRemDupUsr + 159) -#define ActDelRcvMsg (ActRemDupUsr + 160) -#define ActExpSntMsg (ActRemDupUsr + 161) -#define ActExpRcvMsg (ActRemDupUsr + 162) -#define ActConSntMsg (ActRemDupUsr + 163) -#define ActConRcvMsg (ActRemDupUsr + 164) -#define ActLstBanUsr (ActRemDupUsr + 165) -#define ActBanUsrMsg (ActRemDupUsr + 166) -#define ActUnbUsrMsg (ActRemDupUsr + 167) -#define ActUnbUsrLst (ActRemDupUsr + 168) +#define ActRcvMsgUsr (ActUnfSevTch + 154) +#define ActReqDelAllSntMsg (ActUnfSevTch + 155) +#define ActReqDelAllRcvMsg (ActUnfSevTch + 156) +#define ActDelAllSntMsg (ActUnfSevTch + 157) +#define ActDelAllRcvMsg (ActUnfSevTch + 158) +#define ActDelSntMsg (ActUnfSevTch + 159) +#define ActDelRcvMsg (ActUnfSevTch + 160) +#define ActExpSntMsg (ActUnfSevTch + 161) +#define ActExpRcvMsg (ActUnfSevTch + 162) +#define ActConSntMsg (ActUnfSevTch + 163) +#define ActConRcvMsg (ActUnfSevTch + 164) +#define ActLstBanUsr (ActUnfSevTch + 165) +#define ActBanUsrMsg (ActUnfSevTch + 166) +#define ActUnbUsrMsg (ActUnfSevTch + 167) +#define ActUnbUsrLst (ActUnfSevTch + 168) /*****************************************************************************/ /****************************** Statistics tab *******************************/ diff --git a/swad_changelog.h b/swad_changelog.h index d3dd72f0..c3fb006b 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -453,10 +453,30 @@ En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 18.72.2 (2019-03-11)" +#define Log_PLATFORM_VERSION "SWAD 18.73 (2019-03-12)" #define CSS_FILE "swad18.68.3.css" #define JS_FILE "swad18.64.js" /* +Arreglar BUG: RMS no debería poder seleccionar todos los grupos al redactar mensajes +Arreglar BUG: A RMS le sale ACV al listar profesores, pero no al redactar mensajes + + Version 18.73: Mar 12, 2019 New actions to follow/unfollow several users. (239658 lines) + 14 changes necessary in database: +UPDATE actions SET Txt='Ver fichas profesores' WHERE ActCod='22' AND Language='es'; +UPDATE actions SET Txt='Ver fichas estudiantes' WHERE ActCod='89' AND Language='es'; +UPDATE actions SET Txt='Ver fichas invitados' WHERE ActCod='1187' AND Language='es'; +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1753','es','N','Realizar acción invitados'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1754','es','N','Realizar acción estudiantes'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1755','es','N','Realizar acción profesores'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1756','es','N','Solicitar seguir a estudiantes'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1757','es','N','Solicitar seguir a profesores'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1758','es','N','Solicitar dejar de seguir a estudiantes'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1759','es','N','Solicitar dejar de seguir a profesores'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1760','es','N','Seguir a estudiantes'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1761','es','N','Seguir a profesores'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1762','es','N','Dejar de seguir a estudiantes'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1763','es','N','Dejar de seguir a profesores'); + Version 18.72.2: Mar 11, 2019 Create new message from list of users. (239114 lines) Version 18.72.1: Mar 11, 2019 Show attendance list from list of users. (239075 lines) Version 18.72: Mar 11, 2019 Show homework from list of students and teachers. (239043 lines) diff --git a/swad_follow.c b/swad_follow.c index c31d0ac0..a1c2ce2f 100644 --- a/swad_follow.c +++ b/swad_follow.c @@ -89,6 +89,18 @@ static void Fol_PutInactiveIconToFollowUnfollow (void); static void Fol_PutIconToFollow (struct UsrData *UsrDat); static void Fol_PutIconToUnfollow (struct UsrData *UsrDat); +static void Fol_RequestFollowUsrs (Act_Action_t NextAction,void (*FuncParams) ()); +static void Fol_RequestUnfollowUsrs (Act_Action_t NextAction,void (*FuncParams) ()); +static void Fol_GetFollowedFromSelectedUsrs (unsigned *NumFollowed, + unsigned *NumNotFollowed); +static void Fol_PutParamsFollowSelectedStds (void); +static void Fol_PutParamsFollowSelectedTchs (void); +static void Fol_PutParamsUnfollowSelectedStds (void); +static void Fol_PutParamsUnfollowSelectedTchs (void); + +static void Fol_FollowUsr (struct UsrData *UsrDat); +static void Fol_UnfollowUsr (struct UsrData *UsrDat); + /*****************************************************************************/ /********************** Put link to show users to follow **********************/ /*****************************************************************************/ @@ -1009,42 +1021,14 @@ static void Fol_PutIconToUnfollow (struct UsrData *UsrDat) void Fol_FollowUsr1 (void) { - bool CreateNotif; - bool NotifyByEmail; - /***** Get user to be followed *****/ if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ()) { - // Follow only if I can view his/her public profile - if (Pri_ShowingIsAllowed (Gbl.Usrs.Other.UsrDat.ProfileVisibility,&Gbl.Usrs.Other.UsrDat)) - // Follow only if I do not follow him/her - if (!Fol_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod, - Gbl.Usrs.Other.UsrDat.UsrCod)) - { - /***** Follow user in database *****/ - DB_QueryREPLACE ("can not follow user", - "REPLACE INTO usr_follow" - " (FollowerCod,FollowedCod,FollowTime)" - " VALUES" - " (%ld,%ld,NOW())", - Gbl.Usrs.Me.UsrDat.UsrCod, - Gbl.Usrs.Other.UsrDat.UsrCod); + // Follow only if I do not follow him/her + if (!Fol_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Usrs.Other.UsrDat.UsrCod)) + Fol_FollowUsr (&Gbl.Usrs.Other.UsrDat); - /***** Flush cache *****/ - Fol_FlushCacheFollow (); - - /***** This follow must be notified by email? *****/ - CreateNotif = (Gbl.Usrs.Other.UsrDat.Prefs.NotifNtfEvents & (1 << Ntf_EVENT_FOLLOWER)); - NotifyByEmail = CreateNotif && - (Gbl.Usrs.Other.UsrDat.Prefs.EmailNtfEvents & (1 << Ntf_EVENT_FOLLOWER)); - - /***** Create notification for this followed. - If this followed wants to receive notifications by email, activate the sending of a notification *****/ - if (CreateNotif) - Ntf_StoreNotifyEventToOneUser (Ntf_EVENT_FOLLOWER,&Gbl.Usrs.Other.UsrDat,Gbl.Usrs.Me.UsrDat.UsrCod, - (Ntf_Status_t) (NotifyByEmail ? Ntf_STATUS_BIT_EMAIL : - 0)); - } Ale_CreateAlert (Ale_SUCCESS,NULL,""); // Txt not used } else @@ -1078,17 +1062,8 @@ void Fol_UnfollowUsr1 (void) // Unfollow only if I follow him/her if (Fol_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Other.UsrDat.UsrCod)) - { - /***** Unfollow user in database *****/ - DB_QueryREPLACE ("can not unfollow user", - "DELETE FROM usr_follow" - " WHERE FollowerCod=%ld AND FollowedCod=%ld", - Gbl.Usrs.Me.UsrDat.UsrCod, - Gbl.Usrs.Other.UsrDat.UsrCod); + Fol_UnfollowUsr (&Gbl.Usrs.Other.UsrDat); - /***** Flush cache *****/ - Fol_FlushCacheFollow (); - } Ale_CreateAlert (Ale_SUCCESS,NULL,""); // Txt not used } else @@ -1111,6 +1086,336 @@ void Fol_UnfollowUsr2 (void) Ale_ShowAlerts (NULL); } +/*****************************************************************************/ +/***************** Request follow/unfollow several users *********************/ +/*****************************************************************************/ + +void Fol_RequestFollowStds (void) + { + Fol_RequestFollowUsrs (ActFolSevStd,Fol_PutParamsFollowSelectedStds); + } + +void Fol_RequestFollowTchs (void) + { + Fol_RequestFollowUsrs (ActFolSevTch,Fol_PutParamsFollowSelectedTchs); + } + +static void Fol_RequestFollowUsrs (Act_Action_t NextAction,void (*FuncParams) ()) + { + extern const char *Txt_Follow; + extern const char *Txt_Do_you_want_to_follow_the_selected_user_whom_you_do_not_follow_yet; + extern const char *Txt_Do_you_want_to_follow_the_X_selected_users_whom_you_do_not_follow_yet; + unsigned NumFollowed; + unsigned NumNotFollowed; + + // List of selected users is already got + + /***** Go through list of selected users + getting the number of followed and not followed ****/ + Fol_GetFollowedFromSelectedUsrs (&NumFollowed,&NumNotFollowed); + + /***** Show question to confirm ****/ + if (NumNotFollowed) + { + if (NumNotFollowed == 1) + Ale_ShowAlertAndButton (NextAction,NULL,NULL, + FuncParams, + Btn_CREATE_BUTTON,Txt_Follow, + Ale_QUESTION,Txt_Do_you_want_to_follow_the_selected_user_whom_you_do_not_follow_yet); + else + Ale_ShowAlertAndButton (NextAction,NULL,NULL, + FuncParams, + Btn_CREATE_BUTTON,Txt_Follow, + Ale_QUESTION,Txt_Do_you_want_to_follow_the_X_selected_users_whom_you_do_not_follow_yet, + NumNotFollowed); + } + + /***** Free memory used by list of selected users' codes *****/ + Usr_FreeListsSelectedUsrsCods (); + } + +void Fol_RequestUnfollowStds (void) + { + Fol_RequestUnfollowUsrs (ActUnfSevStd,Fol_PutParamsUnfollowSelectedStds); + } + +void Fol_RequestUnfollowTchs (void) + { + Fol_RequestUnfollowUsrs (ActUnfSevTch,Fol_PutParamsUnfollowSelectedTchs); + } + +static void Fol_RequestUnfollowUsrs (Act_Action_t NextAction,void (*FuncParams) ()) + { + extern const char *Txt_Do_you_want_to_stop_following_the_selected_user_whom_you_follow; + extern const char *Txt_Do_you_want_to_stop_following_the_X_selected_users_whom_you_follow; + extern const char *Txt_Unfollow; + unsigned NumFollowed; + unsigned NumNotFollowed; + + // List of selected users is already got + + /***** Go through list of selected users + getting the number of followed and not followed ****/ + Fol_GetFollowedFromSelectedUsrs (&NumFollowed,&NumNotFollowed); + + /***** Show question to confirm ****/ + if (NumFollowed) + { + if (NumFollowed == 1) + Ale_ShowAlertAndButton (NextAction,NULL,NULL, + FuncParams, + Btn_CREATE_BUTTON,Txt_Unfollow, + Ale_QUESTION,Txt_Do_you_want_to_stop_following_the_selected_user_whom_you_follow); + else + Ale_ShowAlertAndButton (NextAction,NULL,NULL, + FuncParams, + Btn_CREATE_BUTTON,Txt_Unfollow, + Ale_QUESTION,Txt_Do_you_want_to_stop_following_the_X_selected_users_whom_you_follow, + NumFollowed); + } + + /***** Free memory used by list of selected users' codes *****/ + Usr_FreeListsSelectedUsrsCods (); + } + +/*****************************************************************************/ +/**** Go through the list getting the number of followed and not followed ****/ +/*****************************************************************************/ + +static void Fol_GetFollowedFromSelectedUsrs (unsigned *NumFollowed, + unsigned *NumNotFollowed) + { + extern const char *Txt_Select_users_X_Followed_Y_Not_followed_Z; + struct UsrData UsrDat; + const char *Ptr; + bool IFollowUsr; + unsigned NumUsrs = 0; + + /***** Initialize structure with user's data *****/ + Usr_UsrDataConstructor (&UsrDat); + + /***** Check users to know if I follow them *****/ + *NumFollowed = 0; + Ptr = Gbl.Usrs.Selected.List[Rol_UNK]; + while (*Ptr) + { + Par_GetNextStrUntilSeparParamMult (&Ptr,UsrDat.EncryptedUsrCod, + Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64); + Usr_GetUsrCodFromEncryptedUsrCod (&UsrDat); + if (Gbl.Usrs.Me.UsrDat.UsrCod != UsrDat.UsrCod) // Skip me + if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat)) // Get from the database the data of the student + if (Usr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) + { + /* Check if I follow this user */ + IFollowUsr = Fol_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod, + UsrDat.UsrCod); + + /* Update number of users */ + if (IFollowUsr) + (*NumFollowed)++; + NumUsrs++; + } + } + + /***** Free memory used for user's data *****/ + Usr_UsrDataDestructor (&UsrDat); + + /***** Show alert ****/ + *NumNotFollowed = NumUsrs - *NumFollowed; + Ale_ShowAlert (Ale_INFO,Txt_Select_users_X_Followed_Y_Not_followed_Z, + NumUsrs,*NumFollowed,*NumNotFollowed); + } + +/*****************************************************************************/ +/********************** Follow/unfollow several users ************************/ +/*****************************************************************************/ + +void Fol_FollowUsrs () + { + extern const char *Txt_You_have_followed_one_user; + extern const char *Txt_You_have_followed_X_users; + const char *Ptr; + struct UsrData UsrDat; + unsigned NumFollowed = 0; + + /***** Get list of selected users if not already got *****/ + Usr_GetListsSelectedUsrsCods (); + + /***** Initialize structure with user's data *****/ + Usr_UsrDataConstructor (&UsrDat); + + /***** Check users to know if I follow them *****/ + Ptr = Gbl.Usrs.Selected.List[Rol_UNK]; + while (*Ptr) + { + Par_GetNextStrUntilSeparParamMult (&Ptr,UsrDat.EncryptedUsrCod, + Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64); + Usr_GetUsrCodFromEncryptedUsrCod (&UsrDat); + if (Gbl.Usrs.Me.UsrDat.UsrCod != UsrDat.UsrCod) // Skip me + if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat)) // Get from the database the data of the student + if (Usr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) + /* If I don't follow this user ==> follow him/her */ + if (!Fol_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod, + UsrDat.UsrCod)) + { + Fol_FollowUsr (&UsrDat); + NumFollowed++; + } + } + + /***** Free memory used for user's data *****/ + Usr_UsrDataDestructor (&UsrDat); + + /***** Free memory used by list of selected users' codes *****/ + Usr_FreeListsSelectedUsrsCods (); + + /***** Show alert *****/ + if (NumFollowed == 1) + Ale_ShowAlert (Ale_SUCCESS,Txt_You_have_followed_one_user); + else + Ale_ShowAlert (Ale_SUCCESS,Txt_You_have_followed_X_users, + NumFollowed); + } + +void Fol_UnfollowUsrs (void) + { + extern const char *Txt_You_have_stopped_following_one_user; + extern const char *Txt_You_have_stopped_following_X_users; + const char *Ptr; + struct UsrData UsrDat; + unsigned NumUnfollowed = 0; + + /***** Get list of selected users if not already got *****/ + Usr_GetListsSelectedUsrsCods (); + + /***** Initialize structure with user's data *****/ + Usr_UsrDataConstructor (&UsrDat); + + /***** Check users to know if I follow them *****/ + Ptr = Gbl.Usrs.Selected.List[Rol_UNK]; + while (*Ptr) + { + Par_GetNextStrUntilSeparParamMult (&Ptr,UsrDat.EncryptedUsrCod, + Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64); + Usr_GetUsrCodFromEncryptedUsrCod (&UsrDat); + if (Gbl.Usrs.Me.UsrDat.UsrCod != UsrDat.UsrCod) // Skip me + if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat)) // Get from the database the data of the student + if (Usr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) + /* If I follow this user ==> unfollow him/her */ + if (Fol_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod, + UsrDat.UsrCod)) + { + Fol_UnfollowUsr (&UsrDat); + NumUnfollowed++; + } + } + + /***** Free memory used for user's data *****/ + Usr_UsrDataDestructor (&UsrDat); + + /***** Free memory used by list of selected users' codes *****/ + Usr_FreeListsSelectedUsrsCods (); + + /***** Show alert *****/ + if (NumUnfollowed == 1) + Ale_ShowAlert (Ale_SUCCESS,Txt_You_have_stopped_following_one_user); + else + Ale_ShowAlert (Ale_SUCCESS,Txt_You_have_stopped_following_X_users, + NumUnfollowed); + } + +/*****************************************************************************/ +/**************** Put parameter with list of selected users ******************/ +/*****************************************************************************/ + +static void Fol_PutParamsFollowSelectedStds (void) + { + /***** Hidden parameter with the encrypted codes of users selected *****/ + Usr_PutHiddenParUsrCodAll (ActFolSevStd,Gbl.Usrs.Selected.List[Rol_UNK]); + } + +static void Fol_PutParamsFollowSelectedTchs (void) + { + /***** Hidden parameter with the encrypted codes of users selected *****/ + Usr_PutHiddenParUsrCodAll (ActFolSevTch,Gbl.Usrs.Selected.List[Rol_UNK]); + } + +static void Fol_PutParamsUnfollowSelectedStds (void) + { + /***** Hidden parameter with the encrypted codes of users selected *****/ + Usr_PutHiddenParUsrCodAll (ActUnfSevStd,Gbl.Usrs.Selected.List[Rol_UNK]); + } + +static void Fol_PutParamsUnfollowSelectedTchs (void) + { + /***** Hidden parameter with the encrypted codes of users selected *****/ + Usr_PutHiddenParUsrCodAll (ActUnfSevTch,Gbl.Usrs.Selected.List[Rol_UNK]); + } + +/*****************************************************************************/ +/******************************** Follow user ********************************/ +/*****************************************************************************/ + +static void Fol_FollowUsr (struct UsrData *UsrDat) + { + bool CreateNotif; + bool NotifyByEmail; + + /***** Avoid wrong cases *****/ + if (Gbl.Usrs.Me.UsrDat.UsrCod <= 0 || + UsrDat->UsrCod <= 0 || + Gbl.Usrs.Me.UsrDat.UsrCod == UsrDat->UsrCod) // Skip me + return; + + /***** Follow user in database *****/ + DB_QueryREPLACE ("can not follow user", + "REPLACE INTO usr_follow" + " (FollowerCod,FollowedCod,FollowTime)" + " VALUES" + " (%ld,%ld,NOW())", + Gbl.Usrs.Me.UsrDat.UsrCod, + UsrDat->UsrCod); + + /***** Flush cache *****/ + Fol_FlushCacheFollow (); + + /***** This follow must be notified by email? *****/ + CreateNotif = (UsrDat->Prefs.NotifNtfEvents & (1 << Ntf_EVENT_FOLLOWER)); + NotifyByEmail = CreateNotif && + (UsrDat->Prefs.EmailNtfEvents & (1 << Ntf_EVENT_FOLLOWER)); + + /***** Create notification for this followed. + If this followed wants to receive notifications by email, + activate the sending of a notification *****/ + if (CreateNotif) + Ntf_StoreNotifyEventToOneUser (Ntf_EVENT_FOLLOWER,UsrDat,Gbl.Usrs.Me.UsrDat.UsrCod, + (Ntf_Status_t) (NotifyByEmail ? Ntf_STATUS_BIT_EMAIL : + 0)); + } + +/*****************************************************************************/ +/******************************* Unfollow user *******************************/ +/*****************************************************************************/ + +static void Fol_UnfollowUsr (struct UsrData *UsrDat) + { + /***** Avoid wrong cases *****/ + if (Gbl.Usrs.Me.UsrDat.UsrCod <= 0 || + UsrDat->UsrCod <= 0 || + Gbl.Usrs.Me.UsrDat.UsrCod == UsrDat->UsrCod) // Skip me + return; + + /***** Unfollow user in database *****/ + DB_QueryDELETE ("can not unfollow user", + "DELETE FROM usr_follow" + " WHERE FollowerCod=%ld AND FollowedCod=%ld", + Gbl.Usrs.Me.UsrDat.UsrCod, + UsrDat->UsrCod); + + /***** Flush cache *****/ + Fol_FlushCacheFollow (); + } + /*****************************************************************************/ /****** Get and show ranking of users attending to number of followers *******/ /*****************************************************************************/ diff --git a/swad_follow.h b/swad_follow.h index 80ce762f..e8e68785 100644 --- a/swad_follow.h +++ b/swad_follow.h @@ -64,6 +64,13 @@ void Fol_FollowUsr2 (void); void Fol_UnfollowUsr1 (void); void Fol_UnfollowUsr2 (void); +void Fol_RequestFollowStds (void); +void Fol_RequestFollowTchs (void); +void Fol_RequestUnfollowStds (void); +void Fol_RequestUnfollowTchs (void); +void Fol_FollowUsrs (void); +void Fol_UnfollowUsrs (void); + void Fol_GetAndShowRankingFollowers (void); void Fol_GetNotifFollower (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1], diff --git a/swad_text.c b/swad_text.c index 57709f34..8d34ef7a 100644 --- a/swad_text.c +++ b/swad_text.c @@ -9129,6 +9129,90 @@ const char *Txt_Do_you_think_you_are_this_user = "Você acha que você é deste usuário?"; #endif +const char *Txt_Do_you_want_to_follow_the_selected_user_whom_you_do_not_follow_yet = +#if L==1 // ca + "Voleu seguir a l'usuari seleccionat a qui encara no segueix?"; +#elif L==2 // de + "Möchten Sie dem ausgewählten Benutzer folgen, dem Sie noch nicht folgen?"; +#elif L==3 // en + "Do you want to follow the selected user whom you do not follow yet?"; +#elif L==4 // es + "¿Desea seguir al usuario seleccionado que aún no sigue?"; +#elif L==5 // fr + "Voulez-vous suivre l'utilisateur sélectionné que vous ne suivez pas encore?"; +#elif L==6 // gn + "¿Desea seguir al usuario seleccionado que aún no sigue?"; // Okoteve traducción +#elif L==7 // it + "Vuoi seguire l'utente selezionato che non segui ancora?"; +#elif L==8 // pl + "Czy chcesz śledzić wybranego użytkownika, którego jeszcze nie śledzisz?"; +#elif L==9 // pt + "Você quer seguir o usuário selecionado que você não segue ainda?"; +#endif + +const char *Txt_Do_you_want_to_follow_the_X_selected_users_whom_you_do_not_follow_yet = // Warning: it is very important to include %u in the following sentences +#if L==1 // ca + "Voleu seguir als %u usuaris seleccionats als que encara no segueix?"; +#elif L==2 // de + "Möchten Sie den %u ausgewählten Benutzern folgen, denen Sie noch nicht folgen?"; +#elif L==3 // en + "Do you want to follow the %u selected users whom you do not follow yet?"; +#elif L==4 // es + "¿Desea seguir a los %u usuarios seleccionados que aún no sigue?"; +#elif L==5 // fr + "Voulez-vous suivre les %u utilisateurs sélectionnés que vous ne suivez pas encore?"; +#elif L==6 // gn + "¿Desea seguir a los %u usuarios seleccionados que aún no sigue?"; // Okoteve traducción +#elif L==7 // it + "Vuoi seguire i %u utenti selezionati che non segui ancora?"; +#elif L==8 // pl + "Czy chcesz śledzić %u wybranych użytkowników, których jeszcze nie śledzisz?"; +#elif L==9 // pt + "Você quer seguir os %u usuários selecionados que você não segue ainda?"; +#endif + +const char *Txt_Do_you_want_to_stop_following_the_selected_user_whom_you_follow = +#if L==1 // ca + "Voleu deixar de seguir a l'usuari seleccionat a qui segueix?"; +#elif L==2 // de + "Möchten Sie dem ausgewählten Benutzer, dem Sie folgen, nicht mehr folgen?"; +#elif L==3 // en + "Do you want to stop following the selected user whom you follow?"; +#elif L==4 // es + "¿Desea dejar de seguir al usuario seleccionado que sigue?"; +#elif L==5 // fr + "Voulez-vous arrêter de suivre l'utilisateur sélectionné que vous suivez?"; +#elif L==6 // gn + "¿Desea dejar de seguir al usuario seleccionado que sigue?"; // Okoteve traducción +#elif L==7 // it + "Vuoi smettere di seguire l'utente selezionato che segui?"; +#elif L==8 // pl + "Czy chcesz przestać śledzić wybranego użytkownika, którego śledzisz?"; +#elif L==9 // pt + "Você quer parar de seguir o usuário selecionado que você segue?"; +#endif + +const char *Txt_Do_you_want_to_stop_following_the_X_selected_users_whom_you_follow = // Warning: it is very important to include %u in the following sentences +#if L==1 // ca + "Voleu deixar de seguir als %u usuaris seleccionats als que segueix?"; +#elif L==2 // de + "Möchten Sie nicht mehr den %u ausgewählten Nutzern folgen, denen Sie folgen?"; +#elif L==3 // en + "Do you want to stop following the %u selected users whom you follow?"; +#elif L==4 // es + "¿Desea dejar de seguir a los %u usuarios seleccionados que sigue?"; +#elif L==5 // fr + "Voulez-vous arrêter de suivre les %u utilisateurs sélectionnés que vous suivez?"; +#elif L==6 // gn + "¿Desea dejar de seguir a los %u usuarios seleccionados que sigue?"; // Okoteve traducción +#elif L==7 // it + "Vuoi smettere di seguire i %u utenti selezionati che segui?"; +#elif L==8 // pl + "Czy chcesz przestać śledzić %u wybranych użytkowników, których śledzisz?"; +#elif L==9 // pt + "Você quer parar de seguir os %u usuários selecionados que você segue?"; +#endif + const char *Txt_Document = #if L==1 // ca "Document"; @@ -37643,6 +37727,45 @@ const char *Txt_Select_the_groups_in_from_which_you_want_to_register_remove_user " ou serão removidos da disciplina e de todos os grupos."; #endif +const char *Txt_Select_users_X_Followed_Y_Not_followed_Z = // Warning: it is very important to include three %u in the following sentences +#if L==1 // ca + "Usuaris seleccionats: %u
" + "• Seguits: %u
" + "• No seguits: %u"; +#elif L==2 // de + "Ausgewählte Benutzer: %u
" + "• Gefolgt: %u
" + "• Nicht gefolgt: %u"; +#elif L==3 // en + "Selected users: %u
" + "• Followed: %u
" + "• Not followed: %u"; +#elif L==4 // es + "Usuarios seleccionados: %u
" + "• Seguidos: %u
" + "• No seguidos: %u"; +#elif L==5 // fr + "Utilisateurs sélectionnés: %u
" + "• Suivis: %u
" + "• Non suivis: %u"; +#elif L==6 // gn + "Usuarios seleccionados: %u
" + "• Seguidos: %u
" + "• No seguidos: %u"; // Okoteve traducción +#elif L==7 // it + "Utenti selezionati: %u
" + "• Seguiti: %u
" + "• Non seguiti: %u"; +#elif L==8 // pl + "Wybrani użytkownicy: %u
" + "• Następnie: %u
" + "• Nie przestrzegano: %u"; +#elif L==9 // pt + "Usuários selecionados: %u
" + "• Seguidos: %u
" + "• Não seguidos: %u"; +#endif + const char *Txt_Send = #if L==1 // ca "Enviar"; @@ -54679,6 +54802,48 @@ const char *Txt_You_have_eliminated_the_confirmation_that_you_have_read_this_inf " de que leu esta informação."; #endif +const char *Txt_You_have_followed_one_user = +#if L==1 // ca + "Ha seguit a un usuari."; +#elif L==2 // de + "Sie haben einen Benutzer verfolgt."; +#elif L==3 // en + "You have followed one user."; +#elif L==4 // es + "Ha seguido a un usuario."; +#elif L==5 // fr + "Vous avez suivi un utilisateur."; +#elif L==6 // gn + "Ha seguido a un usuario."; // Okoteve traducción +#elif L==7 // it + "Hai seguito un utente."; +#elif L==8 // pl + "Śledziłeś jednego użytkownika."; +#elif L==9 // pt + "Você seguiu um usuário."; +#endif + +const char *Txt_You_have_followed_X_users = // Warning: it is very important to include %u in the following sentences +#if L==1 // ca + "Ha seguit a %u usuaris."; +#elif L==2 // de + "Sie haben %u Benutzer verfolgt."; +#elif L==3 // en + "You have followed %u users."; +#elif L==4 // es + "Ha seguido a %u usuarios."; +#elif L==5 // fr + "Vous avez suivi %u utilisateurs."; +#elif L==6 // gn + "Ha seguido a %u usuarios."; // Okoteve traducción +#elif L==7 // it + "Hai seguito %u utenti."; +#elif L==8 // pl + "Śledziłeś %u użytkowników."; +#elif L==9 // pt + "Você seguiu %u usuários."; +#endif + const char *Txt_You_have_no_notifications = #if L==1 // ca "No tens notificacions."; @@ -54805,6 +54970,48 @@ const char *Txt_You_have_not_written_twice_the_same_new_password = "Você não escreveu duas vezes a mesma nova senha."; #endif +const char *Txt_You_have_stopped_following_one_user = +#if L==1 // ca + "Ha deixat de seguir a un usuari."; +#elif L==2 // de + "Sie haben aufgehört, einem Benutzer zu folgen."; +#elif L==3 // en + "You have stopped following one user."; +#elif L==4 // es + "Ha dejado de seguir a un usuario."; +#elif L==5 // fr + "Vous avez arrêté de suivre un utilisateur."; +#elif L==6 // gn + "Ha dejado de seguir a un usuario."; // Okoteve traducción +#elif L==7 // it + "Hai smesso di seguire un utente."; +#elif L==8 // pl + "Przestałeś obserwować użytkownika."; +#elif L==9 // pt + "Você parou de seguir um usuário."; +#endif + +const char *Txt_You_have_stopped_following_X_users = // Warning: it is very important to include %u in the following sentences +#if L==1 // ca + "Ha deixat de seguir a %u usuaris."; +#elif L==2 // de + "Sie haben aufgehört, %u Benutzern zu folgen."; +#elif L==3 // en + "You have stopped following %u users."; +#elif L==4 // es + "Ha seguido a %u usuarios."; +#elif L==5 // fr + "Vous avez cessé de suivre %u utilisateurs."; +#elif L==6 // gn + "Ha seguido a %u usuarios."; // Okoteve traducción +#elif L==7 // it + "Hai smesso di seguire %u utenti."; +#elif L==8 // pl + "Zatrzymałeś śledzenie %u użytkowników."; +#elif L==9 // pt + "Você parou de seguir %u usuários."; +#endif + const char *Txt_You_have_to_register_compulsorily_at_least_in_one_group_of_type_X = // Warning: it is very important to include %s in the following sentences #if L==1 // ca "Tiene que apuntarse obligatoriamente al menos a un grupo de tipo %s."; // Necessita traduccio diff --git a/swad_user.c b/swad_user.c index 5c5aead5..1f725b8e 100644 --- a/swad_user.c +++ b/swad_user.c @@ -242,6 +242,7 @@ static void Usr_PutActionShowHomework (void); static void Usr_PutActionShowAttendance (void); static void Usr_PutActionNewMessage (void); static void Usr_PutActionFollowUsers (void); +static void Usr_PutActionUnfollowUsers (void); static void Usr_StartListUsrsAction (Usr_ListUsrsAction_t ListUsrsAction); static void Usr_EndListUsrsAction (void); static Usr_ListUsrsAction_t Usr_ListUsrsAction (Usr_ListUsrsAction_t DefaultAction); @@ -8027,6 +8028,7 @@ static bool Usr_PutActionsSeveralUsrs (Rol_Role_t UsrsRole) bool ICanViewAttendance; bool ICanSendMessage; bool ICanFollow; + bool ICanUnfollow; bool OptionsShown = false; /***** Get the action to do *****/ @@ -8040,7 +8042,8 @@ static bool Usr_PutActionsSeveralUsrs (Rol_Role_t UsrsRole) ICanViewHomework = ICanViewAttendance = ICanSendMessage = - ICanFollow = false; + ICanFollow = + ICanUnfollow = false; break; case Rol_STD: ICanViewRecords = @@ -8053,6 +8056,7 @@ static bool Usr_PutActionsSeveralUsrs (Rol_Role_t UsrsRole) ICanViewAttendance = (Gbl.Usrs.Me.Role.Logged == Rol_NET || Gbl.Usrs.Me.Role.Logged == Rol_TCH || Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM); + ICanUnfollow = true; break; case Rol_TCH: ICanViewRecords = @@ -8064,13 +8068,15 @@ static bool Usr_PutActionsSeveralUsrs (Rol_Role_t UsrsRole) Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM); ICanViewAttendance = false; + ICanUnfollow = true; break; default: ICanViewRecords = ICanViewHomework = ICanViewAttendance = ICanSendMessage = - ICanFollow = false; + ICanFollow = + ICanUnfollow = false; break; } @@ -8113,6 +8119,13 @@ static bool Usr_PutActionsSeveralUsrs (Rol_Role_t UsrsRole) OptionsShown = true; } + /***** Unfollow *****/ + if (ICanUnfollow) + { // I can unfollow users + Usr_PutActionUnfollowUsers (); + OptionsShown = true; + } + /***** End list of options *****/ fprintf (Gbl.F.Out,""); @@ -8184,6 +8197,19 @@ static void Usr_PutActionFollowUsers (void) Usr_EndListUsrsAction (); } +/*****************************************************************************/ +/*********************** Put action to follow users **************************/ +/*****************************************************************************/ + +static void Usr_PutActionUnfollowUsers (void) + { + extern const char *Txt_Unfollow; + + Usr_StartListUsrsAction (Usr_UNFOLLOW_USERS); + fprintf (Gbl.F.Out,"%s",Txt_Unfollow); + Usr_EndListUsrsAction (); + } + /*****************************************************************************/ /************ Put start/end of action to register/remove one user ************/ /*****************************************************************************/ @@ -8231,7 +8257,9 @@ void Usr_DoActionOnSeveralUsrs1 (void) /* Get the action to do */ Gbl.Usrs.Selected.Action = Usr_ListUsrsAction (Usr_LIST_USRS_UNKNOWN_ACTION); - /***** Do actions *****/ + /***** Change action depending on my selection *****/ + Gbl.Action.Original = Gbl.Action.Act; + switch (Gbl.Usrs.Selected.Action) { case Usr_SHOW_RECORDS: @@ -8239,19 +8267,15 @@ void Usr_DoActionOnSeveralUsrs1 (void) { case ActDoActOnSevGst: Gbl.Action.Act = ActSeeRecSevGst; - Tab_SetCurrentTab (); break; case ActDoActOnSevStd: Gbl.Action.Act = ActSeeRecSevStd; - Tab_SetCurrentTab (); break; case ActDoActOnSevTch: Gbl.Action.Act = ActSeeRecSevTch; - Tab_SetCurrentTab (); break; default: - Ale_CreateAlert (Ale_ERROR,NULL, - "Wrong action."); + Ale_CreateAlert (Ale_ERROR,NULL,"Wrong action."); break; } break; @@ -8261,11 +8285,9 @@ void Usr_DoActionOnSeveralUsrs1 (void) case ActDoActOnSevStd: case ActDoActOnSevTch: Gbl.Action.Act = ActAdmAsgWrkCrs; - Tab_SetCurrentTab (); break; default: - Ale_CreateAlert (Ale_ERROR,NULL, - "Wrong action."); + Ale_CreateAlert (Ale_ERROR,NULL,"Wrong action."); break; } break; @@ -8274,11 +8296,9 @@ void Usr_DoActionOnSeveralUsrs1 (void) { case ActDoActOnSevStd: Gbl.Action.Act = ActSeeLstStdAtt; - Tab_SetCurrentTab (); break; default: - Ale_CreateAlert (Ale_ERROR,NULL, - "Wrong action."); + Ale_CreateAlert (Ale_ERROR,NULL,"Wrong action."); break; } break; @@ -8288,23 +8308,47 @@ void Usr_DoActionOnSeveralUsrs1 (void) case ActDoActOnSevStd: case ActDoActOnSevTch: Gbl.Action.Act = ActReqMsgUsr; - Tab_SetCurrentTab (); break; default: - Ale_CreateAlert (Ale_ERROR,NULL, - "Wrong action."); + Ale_CreateAlert (Ale_ERROR,NULL,"Wrong action."); break; } break; case Usr_FOLLOW_USERS: - Ale_CreateAlert (Ale_WARNING,NULL, - "Not implemented."); + switch (Gbl.Action.Act) + { + case ActDoActOnSevStd: + Gbl.Action.Act = ActReqFolSevStd; + break; + case ActDoActOnSevTch: + Gbl.Action.Act = ActReqFolSevTch; + break; + default: + Ale_CreateAlert (Ale_ERROR,NULL,"Wrong action."); + break; + } + break; + case Usr_UNFOLLOW_USERS: + switch (Gbl.Action.Act) + { + case ActDoActOnSevStd: + Gbl.Action.Act = ActReqUnfSevStd; + break; + case ActDoActOnSevTch: + Gbl.Action.Act = ActReqUnfSevTch; + break; + default: + Ale_CreateAlert (Ale_ERROR,NULL,"Wrong action."); + break; + } break; default: - Ale_CreateAlert (Ale_ERROR,NULL, - "Wrong action."); + Ale_CreateAlert (Ale_ERROR,NULL,"Wrong action."); break; } + + if (Gbl.Action.Act != Gbl.Action.Original) // Action has changed + Tab_SetCurrentTab (); } void Usr_DoActionOnSeveralUsrs2 (void) diff --git a/swad_user.h b/swad_user.h index 23d00506..7d88d5f7 100644 --- a/swad_user.h +++ b/swad_user.h @@ -115,7 +115,7 @@ typedef enum } Usr_ShowUsrsType_t; #define Usr_SHOW_USRS_TYPE_DEFAULT Usr_LIST_AS_CLASS_PHOTO -#define Usr_LIST_USRS_NUM_ACTIONS 6 +#define Usr_LIST_USRS_NUM_ACTIONS 7 typedef enum { Usr_LIST_USRS_UNKNOWN_ACTION = 0, @@ -124,6 +124,7 @@ typedef enum Usr_SHOW_ATTENDANCE = 3, Usr_NEW_MESSAGE = 4, Usr_FOLLOW_USERS = 5, + Usr_UNFOLLOW_USERS = 6, } Usr_ListUsrsAction_t; #define Usr_LIST_USRS_DEFAULT_ACTION Usr_SHOW_RECORDS