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