diff --git a/css/swad15.117.css b/css/swad15.117.css index 01dae6cdd..4acb6f661 100644 --- a/css/swad15.117.css +++ b/css/swad15.117.css @@ -1763,19 +1763,20 @@ a:hover img.CENTRE_PHOTO_SHOW { display:inline-block; padding-top:10px; - padding-right:20px; vertical-align:bottom; } -.SOCIAL_ICON_SHARE +.SOCIAL_ICON_SHARE_FAV { display:inline-block; padding-top:10px; + padding-left:20px; vertical-align:bottom; } -.SOCIAL_ICON_SHARE_DISABLED +.SOCIAL_ICON_SHARE_FAV_DISABLED { display:inline-block; padding-top:10px; + padding-left:20px; opacity:0.2; vertical-align:bottom; } diff --git a/icon/fav64x64.png b/icon/fav64x64.png new file mode 100644 index 000000000..89ff9430a Binary files /dev/null and b/icon/fav64x64.png differ diff --git a/icon/faved64x64.png b/icon/faved64x64.png new file mode 100644 index 000000000..2c6ba903e Binary files /dev/null and b/icon/faved64x64.png differ diff --git a/icon/star-yellow64x64.png b/icon/star-yellow64x64.png new file mode 100644 index 000000000..2c6ba903e Binary files /dev/null and b/icon/star-yellow64x64.png differ diff --git a/icon/star64x64.png b/icon/star64x64.png new file mode 100644 index 000000000..89ff9430a Binary files /dev/null and b/icon/star64x64.png differ diff --git a/sql/swad.sql b/sql/swad.sql index 25ca91bf8..0449d0d87 100644 --- a/sql/swad.sql +++ b/sql/swad.sql @@ -923,9 +923,9 @@ CREATE TABLE IF NOT EXISTS social_comments ( UNIQUE INDEX(ComCod), FULLTEXT(Content)) ENGINE = MYISAM; -- --- Table social_comments_favs: stores users who marked social comments as favourite +-- Table social_comments_fav: stores users who marked social comments as favourite -- -CREATE TABLE IF NOT EXISTS social_comments_favs ( +CREATE TABLE IF NOT EXISTS social_comments_fav ( ComCod BIGINT NOT NULL, UsrCod INT NOT NULL, UNIQUE INDEX(ComCod,UsrCod), @@ -946,9 +946,9 @@ CREATE TABLE IF NOT EXISTS social_notes ( INDEX(UsrCod), INDEX(TimeNote)); -- --- Table social_notes_favs: stores users who marked social notes as favourite +-- Table social_notes_fav: stores users who marked social notes as favourite -- -CREATE TABLE IF NOT EXISTS social_notes_favs ( +CREATE TABLE IF NOT EXISTS social_notes_fav ( NotCod BIGINT NOT NULL, UsrCod INT NOT NULL, UNIQUE INDEX(NotCod,UsrCod), diff --git a/swad_action.c b/swad_action.c index 7bfe4932a..2b471eaac 100644 --- a/swad_action.c +++ b/swad_action.c @@ -1007,8 +1007,10 @@ Social: 841. ActRcvSocPstGbl Receive a public social post to be displayed in the timeline (global) 842. ActRcvSocComGbl Comment a social note in the timeline (global) - 843. ActShaSocNotGbl Share a social publishing in the timeline (global) - 844. ActUnsSocPubGbl Unshare a previously shared social publishing in the timeline (global) + 843. ActShaSocNotGbl Share a social note in the timeline (global) + 844. ActUnsSocNotGbl Unshare a previously shared social note in the timeline (global) +NEW 843. ActFavSocNotGbl Favourite a social note in the timeline (global) +NEW 844. ActUnfSocNotGbl Unfavourite a previously shared social note in the timeline (global) 845. ActReqRemSocPubGbl Request the removal of a social publishing in the timeline (global) 846. ActRemSocPubGbl Remove a social publishing in the timeline (global) 847. ActReqRemSocComGbl Request the removal of a comment in a social note (global) @@ -1017,7 +1019,9 @@ Social: 849. ActRcvSocPstUsr Receive a public social post to be displayed in the timeline (user) 850. ActRcvSocComUsr Comment a social note in the timeline (user) 851. ActShaSocNotUsr Share a social note in the timeline (user) - 852. ActUnsSocPubUsr Unshare a previously shared social note in the timeline (user) + 852. ActUnsSocNotUsr Unshare a previously shared social note in the timeline (user) +NEW 851. ActFavSocNotUsr Favourite a social note in the timeline (user) +NEW 852. ActUnfSocNotUsr Unfavourite a previously shared social note in the timeline (user) 853. ActReqRemSocPubUsr Request the removal of a social publishing in the timeline (user) 854. ActRemSocPubUsr Remove a social publishing in the timeline (user) 855. ActReqRemSocComUsr Request the removal of a comment in a social note (user) @@ -2336,7 +2340,9 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActRcvSocPstGbl */{1492,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_ReceiveSocialPostGbl ,NULL}, /* ActRcvSocComGbl */{1503,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_ReceiveCommentGbl ,NULL}, /* ActShaSocNotGbl */{1495,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_ShareSocialNoteGbl ,NULL}, - /* ActUnsSocPubGbl */{1496,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_UnshareSocialNoteGbl ,NULL}, + /* ActUnsSocNotGbl */{1496,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_UnshareSocialNoteGbl ,NULL}, + /* ActFavSocNotGbl */{1512,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_FavSocialNoteGbl ,NULL}, + /* ActUnfSocNotGbl */{1513,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_UnfavSocialNoteGbl ,NULL}, /* ActReqRemSocPubGbl*/{1494,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_RequestRemSocialNoteGbl ,NULL}, /* ActRemSocPubGbl */{1493,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_RemoveSocialNoteGbl ,NULL}, /* ActReqRemSocComGbl*/{1505,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_RequestRemSocialComGbl ,NULL}, @@ -2345,7 +2351,9 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActRcvSocPstUsr */{1498,-1,TabSoc,ActReqPubPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_ReceiveSocialPostUsr ,NULL}, /* ActRcvSocComUsr */{1504,-1,TabSoc,ActReqPubPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_ReceiveCommentUsr ,NULL}, /* ActShaSocNotUsr */{1499,-1,TabSoc,ActReqPubPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_ShareSocialNoteUsr ,NULL}, - /* ActUnsSocPubUsr */{1500,-1,TabSoc,ActReqPubPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_UnshareSocialNoteUsr ,NULL}, + /* ActUnsSocNotUsr */{1500,-1,TabSoc,ActReqPubPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_UnshareSocialNoteUsr ,NULL}, + /* ActShaSocNotUsr */{1514,-1,TabSoc,ActReqPubPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_FavSocialNoteUsr ,NULL}, + /* ActUnsSocNotUsr */{1515,-1,TabSoc,ActReqPubPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_UnfavSocialNoteUsr ,NULL}, /* ActReqRemSocPubUsr*/{1501,-1,TabSoc,ActReqPubPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_RequestRemSocialNoteUsr ,NULL}, /* ActRemSocPubUsr */{1502,-1,TabSoc,ActReqPubPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_RemoveSocialNoteUsr ,NULL}, /* ActReqRemSocComGbl*/{1506,-1,TabSoc,ActReqPubPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_RequestRemSocialComUsr ,NULL}, @@ -4193,11 +4201,11 @@ Act_Action_t Act_FromActCodToAction[1+Act_MAX_ACTION_COD] = // Do not reuse uniq ActRemSocPubGbl, // #1493 ActReqRemSocPubGbl, // #1494 ActShaSocNotGbl, // #1495 - ActUnsSocPubGbl, // #1496 + ActUnsSocNotGbl, // #1496 -1, // #1497 (obsolete action) ActRcvSocPstUsr, // #1498 ActShaSocNotUsr, // #1499 - ActUnsSocPubUsr, // #1500 + ActUnsSocNotUsr, // #1500 ActReqRemSocPubUsr, // #1501 ActRemSocPubUsr, // #1502 ActRcvSocComGbl, // #1503 @@ -4209,6 +4217,10 @@ Act_Action_t Act_FromActCodToAction[1+Act_MAX_ACTION_COD] = // Do not reuse uniq ActRefNewSocPubGbl, // #1509 ActRefOldSocPubGbl, // #1510 ActRefOldSocPubUsr, // #1511 + ActFavSocNotGbl, // #1512 + ActUnfSocNotGbl, // #1513 + ActFavSocNotUsr, // #1514 + ActUnfSocNotUsr, // #1515 }; /*****************************************************************************/ diff --git a/swad_action.h b/swad_action.h index 53e936839..db3ce3e12 100644 --- a/swad_action.h +++ b/swad_action.h @@ -71,9 +71,9 @@ typedef enum typedef int Act_Action_t; // Must be a signed type, because -1 is used to indicate obsolete action -#define Act_NUM_ACTIONS (1+9+52+15+90+72+67+205+183+143+163+36+27+82) +#define Act_NUM_ACTIONS (1+9+52+15+90+72+67+205+183+143+167+36+27+82) -#define Act_MAX_ACTION_COD 1511 +#define Act_MAX_ACTION_COD 1515 #define Act_MAX_OPTIONS_IN_MENU_PER_TAB 20 @@ -314,7 +314,6 @@ typedef int Act_Action_t; // Must be a signed type, because -1 is used to indica #define ActChgDegCtr (ActDowShaIns+ 21) #define ActChgDegFstYea (ActDowShaIns+ 22) #define ActChgDegLstYea (ActDowShaIns+ 23) -// #define ActChgDegOptYea (ActDowShaIns+ 24) #define ActChgDegWWW (ActDowShaIns+ 24) #define ActChgDegSta (ActDowShaIns+ 25) @@ -1051,167 +1050,171 @@ typedef int Act_Action_t; // Must be a signed type, because -1 is used to indica #define ActRcvSocPstGbl (ActLstClk+ 5) #define ActRcvSocComGbl (ActLstClk+ 6) #define ActShaSocNotGbl (ActLstClk+ 7) -#define ActUnsSocPubGbl (ActLstClk+ 8) -#define ActReqRemSocPubGbl (ActLstClk+ 9) -#define ActRemSocPubGbl (ActLstClk+ 10) -#define ActReqRemSocComGbl (ActLstClk+ 11) -#define ActRemSocComGbl (ActLstClk+ 12) +#define ActUnsSocNotGbl (ActLstClk+ 8) +#define ActFavSocNotGbl (ActLstClk+ 9) +#define ActUnfSocNotGbl (ActLstClk+ 10) +#define ActReqRemSocPubGbl (ActLstClk+ 11) +#define ActRemSocPubGbl (ActLstClk+ 12) +#define ActReqRemSocComGbl (ActLstClk+ 13) +#define ActRemSocComGbl (ActLstClk+ 14) -#define ActRcvSocPstUsr (ActLstClk+ 13) -#define ActRcvSocComUsr (ActLstClk+ 14) -#define ActShaSocNotUsr (ActLstClk+ 15) -#define ActUnsSocPubUsr (ActLstClk+ 16) -#define ActReqRemSocPubUsr (ActLstClk+ 17) -#define ActRemSocPubUsr (ActLstClk+ 18) -#define ActReqRemSocComUsr (ActLstClk+ 19) -#define ActRemSocComUsr (ActLstClk+ 20) +#define ActRcvSocPstUsr (ActLstClk+ 15) +#define ActRcvSocComUsr (ActLstClk+ 16) +#define ActShaSocNotUsr (ActLstClk+ 17) +#define ActUnsSocNotUsr (ActLstClk+ 18) +#define ActFavSocNotUsr (ActLstClk+ 19) +#define ActUnfSocNotUsr (ActLstClk+ 20) +#define ActReqRemSocPubUsr (ActLstClk+ 21) +#define ActRemSocPubUsr (ActLstClk+ 22) +#define ActReqRemSocComUsr (ActLstClk+ 23) +#define ActRemSocComUsr (ActLstClk+ 24) -#define ActSeePubPrf (ActLstClk+ 21) -#define ActCal1stClkTim (ActLstClk+ 22) -#define ActCalNumClk (ActLstClk+ 23) -#define ActCalNumFilVie (ActLstClk+ 24) -#define ActCalNumForPst (ActLstClk+ 25) -#define ActCalNumMsgSnt (ActLstClk+ 26) +#define ActSeePubPrf (ActLstClk+ 25) +#define ActCal1stClkTim (ActLstClk+ 26) +#define ActCalNumClk (ActLstClk+ 27) +#define ActCalNumFilVie (ActLstClk+ 28) +#define ActCalNumForPst (ActLstClk+ 29) +#define ActCalNumMsgSnt (ActLstClk+ 30) -#define ActFolUsr (ActLstClk+ 27) -#define ActUnfUsr (ActLstClk+ 28) -#define ActSeeFlg (ActLstClk+ 29) -#define ActSeeFlr (ActLstClk+ 30) +#define ActFolUsr (ActLstClk+ 31) +#define ActUnfUsr (ActLstClk+ 32) +#define ActSeeFlg (ActLstClk+ 33) +#define ActSeeFlr (ActLstClk+ 34) -#define ActSeeForCrsUsr (ActLstClk+ 31) -#define ActSeeForCrsTch (ActLstClk+ 32) -#define ActSeeForDegUsr (ActLstClk+ 33) -#define ActSeeForDegTch (ActLstClk+ 34) -#define ActSeeForCtrUsr (ActLstClk+ 35) -#define ActSeeForCtrTch (ActLstClk+ 36) -#define ActSeeForInsUsr (ActLstClk+ 37) -#define ActSeeForInsTch (ActLstClk+ 38) -#define ActSeeForGenUsr (ActLstClk+ 39) -#define ActSeeForGenTch (ActLstClk+ 40) -#define ActSeeForSWAUsr (ActLstClk+ 41) -#define ActSeeForSWATch (ActLstClk+ 42) -#define ActSeePstForCrsUsr (ActLstClk+ 43) -#define ActSeePstForCrsTch (ActLstClk+ 44) -#define ActSeePstForDegUsr (ActLstClk+ 45) -#define ActSeePstForDegTch (ActLstClk+ 46) -#define ActSeePstForCtrUsr (ActLstClk+ 47) -#define ActSeePstForCtrTch (ActLstClk+ 48) -#define ActSeePstForInsUsr (ActLstClk+ 49) -#define ActSeePstForInsTch (ActLstClk+ 50) -#define ActSeePstForGenUsr (ActLstClk+ 51) -#define ActSeePstForGenTch (ActLstClk+ 52) -#define ActSeePstForSWAUsr (ActLstClk+ 53) -#define ActSeePstForSWATch (ActLstClk+ 54) -#define ActRcvThrForCrsUsr (ActLstClk+ 55) -#define ActRcvThrForCrsTch (ActLstClk+ 56) -#define ActRcvThrForDegUsr (ActLstClk+ 57) -#define ActRcvThrForDegTch (ActLstClk+ 58) -#define ActRcvThrForCtrUsr (ActLstClk+ 59) -#define ActRcvThrForCtrTch (ActLstClk+ 60) -#define ActRcvThrForInsUsr (ActLstClk+ 61) -#define ActRcvThrForInsTch (ActLstClk+ 62) -#define ActRcvThrForGenUsr (ActLstClk+ 63) -#define ActRcvThrForGenTch (ActLstClk+ 64) -#define ActRcvThrForSWAUsr (ActLstClk+ 65) -#define ActRcvThrForSWATch (ActLstClk+ 66) -#define ActRcvRepForCrsUsr (ActLstClk+ 67) -#define ActRcvRepForCrsTch (ActLstClk+ 68) -#define ActRcvRepForDegUsr (ActLstClk+ 69) -#define ActRcvRepForDegTch (ActLstClk+ 70) -#define ActRcvRepForCtrUsr (ActLstClk+ 71) -#define ActRcvRepForCtrTch (ActLstClk+ 72) -#define ActRcvRepForInsUsr (ActLstClk+ 73) -#define ActRcvRepForInsTch (ActLstClk+ 74) -#define ActRcvRepForGenUsr (ActLstClk+ 75) -#define ActRcvRepForGenTch (ActLstClk+ 76) -#define ActRcvRepForSWAUsr (ActLstClk+ 77) -#define ActRcvRepForSWATch (ActLstClk+ 78) -#define ActReqDelThrCrsUsr (ActLstClk+ 79) -#define ActReqDelThrCrsTch (ActLstClk+ 80) -#define ActReqDelThrDegUsr (ActLstClk+ 81) -#define ActReqDelThrDegTch (ActLstClk+ 82) -#define ActReqDelThrCtrUsr (ActLstClk+ 83) -#define ActReqDelThrCtrTch (ActLstClk+ 84) -#define ActReqDelThrInsUsr (ActLstClk+ 85) -#define ActReqDelThrInsTch (ActLstClk+ 86) -#define ActReqDelThrGenUsr (ActLstClk+ 87) -#define ActReqDelThrGenTch (ActLstClk+ 88) -#define ActReqDelThrSWAUsr (ActLstClk+ 89) -#define ActReqDelThrSWATch (ActLstClk+ 90) -#define ActDelThrForCrsUsr (ActLstClk+ 91) -#define ActDelThrForCrsTch (ActLstClk+ 92) -#define ActDelThrForDegUsr (ActLstClk+ 93) -#define ActDelThrForDegTch (ActLstClk+ 94) -#define ActDelThrForCtrUsr (ActLstClk+ 95) -#define ActDelThrForCtrTch (ActLstClk+ 96) -#define ActDelThrForInsUsr (ActLstClk+ 97) -#define ActDelThrForInsTch (ActLstClk+ 98) -#define ActDelThrForGenUsr (ActLstClk+ 99) -#define ActDelThrForGenTch (ActLstClk+100) -#define ActDelThrForSWAUsr (ActLstClk+101) -#define ActDelThrForSWATch (ActLstClk+102) -#define ActCutThrForCrsUsr (ActLstClk+103) -#define ActCutThrForCrsTch (ActLstClk+104) -#define ActCutThrForDegUsr (ActLstClk+105) -#define ActCutThrForDegTch (ActLstClk+106) -#define ActCutThrForCtrUsr (ActLstClk+107) -#define ActCutThrForCtrTch (ActLstClk+108) -#define ActCutThrForInsUsr (ActLstClk+109) -#define ActCutThrForInsTch (ActLstClk+110) -#define ActCutThrForGenUsr (ActLstClk+111) -#define ActCutThrForGenTch (ActLstClk+112) -#define ActCutThrForSWAUsr (ActLstClk+113) -#define ActCutThrForSWATch (ActLstClk+114) -#define ActPasThrForCrsUsr (ActLstClk+115) -#define ActPasThrForCrsTch (ActLstClk+116) -#define ActPasThrForDegUsr (ActLstClk+117) -#define ActPasThrForDegTch (ActLstClk+118) -#define ActPasThrForCtrUsr (ActLstClk+119) -#define ActPasThrForCtrTch (ActLstClk+120) -#define ActPasThrForInsUsr (ActLstClk+121) -#define ActPasThrForInsTch (ActLstClk+122) -#define ActPasThrForGenUsr (ActLstClk+123) -#define ActPasThrForGenTch (ActLstClk+124) -#define ActPasThrForSWAUsr (ActLstClk+125) -#define ActPasThrForSWATch (ActLstClk+126) -#define ActDelPstForCrsUsr (ActLstClk+127) -#define ActDelPstForCrsTch (ActLstClk+128) -#define ActDelPstForDegUsr (ActLstClk+129) -#define ActDelPstForDegTch (ActLstClk+130) -#define ActDelPstForCtrUsr (ActLstClk+131) -#define ActDelPstForCtrTch (ActLstClk+132) -#define ActDelPstForInsUsr (ActLstClk+133) -#define ActDelPstForInsTch (ActLstClk+134) -#define ActDelPstForGenUsr (ActLstClk+135) -#define ActDelPstForGenTch (ActLstClk+136) -#define ActDelPstForSWAUsr (ActLstClk+137) -#define ActDelPstForSWATch (ActLstClk+138) -#define ActEnbPstForCrsUsr (ActLstClk+139) -#define ActEnbPstForCrsTch (ActLstClk+140) -#define ActEnbPstForDegUsr (ActLstClk+141) -#define ActEnbPstForDegTch (ActLstClk+142) -#define ActEnbPstForCtrUsr (ActLstClk+143) -#define ActEnbPstForCtrTch (ActLstClk+144) -#define ActEnbPstForInsUsr (ActLstClk+145) -#define ActEnbPstForInsTch (ActLstClk+146) -#define ActEnbPstForGenUsr (ActLstClk+147) -#define ActEnbPstForGenTch (ActLstClk+148) -#define ActEnbPstForSWAUsr (ActLstClk+149) -#define ActEnbPstForSWATch (ActLstClk+150) -#define ActDisPstForCrsUsr (ActLstClk+151) -#define ActDisPstForCrsTch (ActLstClk+152) -#define ActDisPstForDegUsr (ActLstClk+153) -#define ActDisPstForDegTch (ActLstClk+154) -#define ActDisPstForCtrUsr (ActLstClk+155) -#define ActDisPstForCtrTch (ActLstClk+156) -#define ActDisPstForInsUsr (ActLstClk+157) -#define ActDisPstForInsTch (ActLstClk+158) -#define ActDisPstForGenUsr (ActLstClk+159) -#define ActDisPstForGenTch (ActLstClk+160) -#define ActDisPstForSWAUsr (ActLstClk+161) -#define ActDisPstForSWATch (ActLstClk+162) +#define ActSeeForCrsUsr (ActLstClk+ 35) +#define ActSeeForCrsTch (ActLstClk+ 36) +#define ActSeeForDegUsr (ActLstClk+ 37) +#define ActSeeForDegTch (ActLstClk+ 38) +#define ActSeeForCtrUsr (ActLstClk+ 39) +#define ActSeeForCtrTch (ActLstClk+ 40) +#define ActSeeForInsUsr (ActLstClk+ 41) +#define ActSeeForInsTch (ActLstClk+ 42) +#define ActSeeForGenUsr (ActLstClk+ 43) +#define ActSeeForGenTch (ActLstClk+ 44) +#define ActSeeForSWAUsr (ActLstClk+ 45) +#define ActSeeForSWATch (ActLstClk+ 46) +#define ActSeePstForCrsUsr (ActLstClk+ 47) +#define ActSeePstForCrsTch (ActLstClk+ 48) +#define ActSeePstForDegUsr (ActLstClk+ 49) +#define ActSeePstForDegTch (ActLstClk+ 50) +#define ActSeePstForCtrUsr (ActLstClk+ 51) +#define ActSeePstForCtrTch (ActLstClk+ 52) +#define ActSeePstForInsUsr (ActLstClk+ 53) +#define ActSeePstForInsTch (ActLstClk+ 54) +#define ActSeePstForGenUsr (ActLstClk+ 55) +#define ActSeePstForGenTch (ActLstClk+ 56) +#define ActSeePstForSWAUsr (ActLstClk+ 57) +#define ActSeePstForSWATch (ActLstClk+ 58) +#define ActRcvThrForCrsUsr (ActLstClk+ 59) +#define ActRcvThrForCrsTch (ActLstClk+ 60) +#define ActRcvThrForDegUsr (ActLstClk+ 61) +#define ActRcvThrForDegTch (ActLstClk+ 62) +#define ActRcvThrForCtrUsr (ActLstClk+ 63) +#define ActRcvThrForCtrTch (ActLstClk+ 64) +#define ActRcvThrForInsUsr (ActLstClk+ 65) +#define ActRcvThrForInsTch (ActLstClk+ 66) +#define ActRcvThrForGenUsr (ActLstClk+ 67) +#define ActRcvThrForGenTch (ActLstClk+ 68) +#define ActRcvThrForSWAUsr (ActLstClk+ 69) +#define ActRcvThrForSWATch (ActLstClk+ 70) +#define ActRcvRepForCrsUsr (ActLstClk+ 71) +#define ActRcvRepForCrsTch (ActLstClk+ 72) +#define ActRcvRepForDegUsr (ActLstClk+ 73) +#define ActRcvRepForDegTch (ActLstClk+ 74) +#define ActRcvRepForCtrUsr (ActLstClk+ 75) +#define ActRcvRepForCtrTch (ActLstClk+ 76) +#define ActRcvRepForInsUsr (ActLstClk+ 77) +#define ActRcvRepForInsTch (ActLstClk+ 78) +#define ActRcvRepForGenUsr (ActLstClk+ 79) +#define ActRcvRepForGenTch (ActLstClk+ 80) +#define ActRcvRepForSWAUsr (ActLstClk+ 81) +#define ActRcvRepForSWATch (ActLstClk+ 82) +#define ActReqDelThrCrsUsr (ActLstClk+ 83) +#define ActReqDelThrCrsTch (ActLstClk+ 84) +#define ActReqDelThrDegUsr (ActLstClk+ 85) +#define ActReqDelThrDegTch (ActLstClk+ 86) +#define ActReqDelThrCtrUsr (ActLstClk+ 87) +#define ActReqDelThrCtrTch (ActLstClk+ 88) +#define ActReqDelThrInsUsr (ActLstClk+ 89) +#define ActReqDelThrInsTch (ActLstClk+ 90) +#define ActReqDelThrGenUsr (ActLstClk+ 91) +#define ActReqDelThrGenTch (ActLstClk+ 92) +#define ActReqDelThrSWAUsr (ActLstClk+ 93) +#define ActReqDelThrSWATch (ActLstClk+ 94) +#define ActDelThrForCrsUsr (ActLstClk+ 95) +#define ActDelThrForCrsTch (ActLstClk+ 96) +#define ActDelThrForDegUsr (ActLstClk+ 97) +#define ActDelThrForDegTch (ActLstClk+ 98) +#define ActDelThrForCtrUsr (ActLstClk+ 99) +#define ActDelThrForCtrTch (ActLstClk+100) +#define ActDelThrForInsUsr (ActLstClk+101) +#define ActDelThrForInsTch (ActLstClk+102) +#define ActDelThrForGenUsr (ActLstClk+103) +#define ActDelThrForGenTch (ActLstClk+104) +#define ActDelThrForSWAUsr (ActLstClk+105) +#define ActDelThrForSWATch (ActLstClk+106) +#define ActCutThrForCrsUsr (ActLstClk+107) +#define ActCutThrForCrsTch (ActLstClk+108) +#define ActCutThrForDegUsr (ActLstClk+109) +#define ActCutThrForDegTch (ActLstClk+110) +#define ActCutThrForCtrUsr (ActLstClk+111) +#define ActCutThrForCtrTch (ActLstClk+112) +#define ActCutThrForInsUsr (ActLstClk+113) +#define ActCutThrForInsTch (ActLstClk+114) +#define ActCutThrForGenUsr (ActLstClk+115) +#define ActCutThrForGenTch (ActLstClk+116) +#define ActCutThrForSWAUsr (ActLstClk+117) +#define ActCutThrForSWATch (ActLstClk+118) +#define ActPasThrForCrsUsr (ActLstClk+119) +#define ActPasThrForCrsTch (ActLstClk+120) +#define ActPasThrForDegUsr (ActLstClk+121) +#define ActPasThrForDegTch (ActLstClk+122) +#define ActPasThrForCtrUsr (ActLstClk+123) +#define ActPasThrForCtrTch (ActLstClk+124) +#define ActPasThrForInsUsr (ActLstClk+125) +#define ActPasThrForInsTch (ActLstClk+126) +#define ActPasThrForGenUsr (ActLstClk+127) +#define ActPasThrForGenTch (ActLstClk+128) +#define ActPasThrForSWAUsr (ActLstClk+129) +#define ActPasThrForSWATch (ActLstClk+130) +#define ActDelPstForCrsUsr (ActLstClk+131) +#define ActDelPstForCrsTch (ActLstClk+132) +#define ActDelPstForDegUsr (ActLstClk+133) +#define ActDelPstForDegTch (ActLstClk+134) +#define ActDelPstForCtrUsr (ActLstClk+135) +#define ActDelPstForCtrTch (ActLstClk+136) +#define ActDelPstForInsUsr (ActLstClk+137) +#define ActDelPstForInsTch (ActLstClk+138) +#define ActDelPstForGenUsr (ActLstClk+139) +#define ActDelPstForGenTch (ActLstClk+140) +#define ActDelPstForSWAUsr (ActLstClk+141) +#define ActDelPstForSWATch (ActLstClk+142) +#define ActEnbPstForCrsUsr (ActLstClk+143) +#define ActEnbPstForCrsTch (ActLstClk+144) +#define ActEnbPstForDegUsr (ActLstClk+145) +#define ActEnbPstForDegTch (ActLstClk+146) +#define ActEnbPstForCtrUsr (ActLstClk+147) +#define ActEnbPstForCtrTch (ActLstClk+148) +#define ActEnbPstForInsUsr (ActLstClk+149) +#define ActEnbPstForInsTch (ActLstClk+150) +#define ActEnbPstForGenUsr (ActLstClk+151) +#define ActEnbPstForGenTch (ActLstClk+152) +#define ActEnbPstForSWAUsr (ActLstClk+153) +#define ActEnbPstForSWATch (ActLstClk+154) +#define ActDisPstForCrsUsr (ActLstClk+155) +#define ActDisPstForCrsTch (ActLstClk+156) +#define ActDisPstForDegUsr (ActLstClk+157) +#define ActDisPstForDegTch (ActLstClk+158) +#define ActDisPstForCtrUsr (ActLstClk+159) +#define ActDisPstForCtrTch (ActLstClk+160) +#define ActDisPstForInsUsr (ActLstClk+161) +#define ActDisPstForInsTch (ActLstClk+162) +#define ActDisPstForGenUsr (ActLstClk+163) +#define ActDisPstForGenTch (ActLstClk+164) +#define ActDisPstForSWAUsr (ActLstClk+165) +#define ActDisPstForSWATch (ActLstClk+166) -#define ActCht (ActLstClk+163) +#define ActCht (ActLstClk+167) /*****************************************************************************/ /******************************* Messages tab ********************************/ diff --git a/swad_changelog.h b/swad_changelog.h index 50b60fff4..1b85e9787 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -122,17 +122,18 @@ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 15.119 (2016-01-18)" +#define Log_PLATFORM_VERSION "SWAD 15.120 (2016-01-19)" #define CSS_FILE "swad15.117.css" #define JS_FILE "swad15.118.4.js" // Number of lines (includes comments but not blank lines) has been got with the following command: // nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*.h sql/swad*.sql | tail -1 /* + Version 15.120: Jan 19, 2016 Mark/unmark social notes as favourites. (193475 lines) Version 15.119: Jan 18, 2016 New tables to mark social notes and comments as favourites. (193036 lines) 2 changes necessary in database: -CREATE TABLE IF NOT EXISTS social_comments_favs (ComCod BIGINT NOT NULL,UsrCod INT NOT NULL,UNIQUE INDEX(ComCod,UsrCod),INDEX(UsrCod)); -CREATE TABLE IF NOT EXISTS social_notes_favs (NotCod BIGINT NOT NULL,UsrCod INT NOT NULL,UNIQUE INDEX(NotCod,UsrCod),INDEX(UsrCod)); +CREATE TABLE IF NOT EXISTS social_comments_fav (ComCod BIGINT NOT NULL,UsrCod INT NOT NULL,UNIQUE INDEX(ComCod,UsrCod),INDEX(UsrCod)); +CREATE TABLE IF NOT EXISTS social_notes_fav (NotCod BIGINT NOT NULL,UsrCod INT NOT NULL,UNIQUE INDEX(NotCod,UsrCod),INDEX(UsrCod)); Version 15.118.4: Jan 18, 2016 Date-time without seconds in user's public profile. (192984 lines) Version 15.118.3: Jan 18, 2016 Fixed bug in date-time of files in file-browsers. (192975 lines) diff --git a/swad_database.c b/swad_database.c index 919da0b5b..e5d40a978 100644 --- a/swad_database.c +++ b/swad_database.c @@ -1957,9 +1957,9 @@ mysql> DESCRIBE social_comments; "UNIQUE INDEX(ComCod)," "FULLTEXT(Content)) ENGINE = MYISAM;"); - /***** Table social_comments_favs *****/ + /***** Table social_comments_fav *****/ /* -mysql> DESCRIBE social_comments_favs; +mysql> DESCRIBE social_comments_fav; +--------+------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+------------+------+-----+---------+-------+ @@ -1968,7 +1968,7 @@ mysql> DESCRIBE social_comments_favs; +--------+------------+------+-----+---------+-------+ 2 rows in set (0.00 sec) */ - DB_CreateTable ("CREATE TABLE IF NOT EXISTS social_comments_favs (" + DB_CreateTable ("CREATE TABLE IF NOT EXISTS social_comments_fav (" "ComCod BIGINT NOT NULL," "UsrCod INT NOT NULL," "UNIQUE INDEX(ComCod,UsrCod)," @@ -2003,9 +2003,9 @@ mysql> DESCRIBE social_notes; "INDEX(UsrCod)," "INDEX(TimeNote))"); - /***** Table social_notes_favs *****/ + /***** Table social_notes_fav *****/ /* -mysql> DESCRIBE social_notes_favs; +mysql> DESCRIBE social_notes_fav; +--------+------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+------------+------+-----+---------+-------+ @@ -2014,7 +2014,7 @@ mysql> DESCRIBE social_notes_favs; +--------+------------+------+-----+---------+-------+ 2 rows in set (0.00 sec) */ - DB_CreateTable ("CREATE TABLE IF NOT EXISTS social_notes_favs (" + DB_CreateTable ("CREATE TABLE IF NOT EXISTS social_notes_fav (" "NotCod BIGINT NOT NULL," "UsrCod INT NOT NULL," "UNIQUE INDEX(NotCod,UsrCod)," diff --git a/swad_layout.c b/swad_layout.c index 330180a34..3dd8ad5ef 100644 --- a/swad_layout.c +++ b/swad_layout.c @@ -614,7 +614,9 @@ static void Lay_WriteScriptInit (void) Gbl.Action.Act == ActRcvSocPstGbl || Gbl.Action.Act == ActRcvSocComGbl || Gbl.Action.Act == ActShaSocNotGbl || - Gbl.Action.Act == ActUnsSocPubGbl || + Gbl.Action.Act == ActUnsSocNotGbl || + Gbl.Action.Act == ActFavSocNotGbl || + Gbl.Action.Act == ActUnfSocNotGbl || Gbl.Action.Act == ActReqRemSocPubGbl || Gbl.Action.Act == ActRemSocPubGbl || Gbl.Action.Act == ActReqRemSocComGbl || @@ -649,7 +651,9 @@ static void Lay_WriteScriptParamsAJAX (void) Gbl.Action.Act == ActRcvSocPstGbl || Gbl.Action.Act == ActRcvSocComGbl || Gbl.Action.Act == ActShaSocNotGbl || - Gbl.Action.Act == ActUnsSocPubGbl || + Gbl.Action.Act == ActUnsSocNotGbl || + Gbl.Action.Act == ActFavSocNotGbl || + Gbl.Action.Act == ActUnfSocNotGbl || Gbl.Action.Act == ActReqRemSocPubGbl || Gbl.Action.Act == ActRemSocPubGbl || Gbl.Action.Act == ActReqRemSocComGbl || @@ -662,14 +666,16 @@ static void Lay_WriteScriptParamsAJAX (void) Act_Actions[ActRefNewSocPubGbl].ActCod, Act_Actions[ActRefOldSocPubGbl].ActCod); else if (Gbl.Action.Act == ActSeePubPrf || - Gbl.Action.Act == ActRcvSocPstGbl || + Gbl.Action.Act == ActRcvSocPstUsr || Gbl.Action.Act == ActRcvSocComUsr || - Gbl.Action.Act == ActShaSocNotGbl || - Gbl.Action.Act == ActUnsSocPubGbl || - Gbl.Action.Act == ActReqRemSocPubGbl || - Gbl.Action.Act == ActRemSocPubGbl || - Gbl.Action.Act == ActReqRemSocComGbl || - Gbl.Action.Act == ActRemSocComGbl) + Gbl.Action.Act == ActShaSocNotUsr || + Gbl.Action.Act == ActUnsSocNotUsr || + Gbl.Action.Act == ActFavSocNotUsr || + Gbl.Action.Act == ActUnfSocNotUsr || + Gbl.Action.Act == ActReqRemSocPubUsr || + Gbl.Action.Act == ActRemSocPubUsr || + Gbl.Action.Act == ActReqRemSocComUsr || + Gbl.Action.Act == ActRemSocComUsr) { /* In all the actions related to view or editing user's timeline ==> put parameters used by AJAX */ diff --git a/swad_social.c b/swad_social.c index 028ff3bd3..1aa3b5eae 100644 --- a/swad_social.c +++ b/swad_social.c @@ -80,6 +80,16 @@ typedef enum // when user clicks on link at bottom of timeline } Soc_WhatToGetFromTimeline_t; +typedef enum + { + Soc_TOP_MESSAGE_NONE, + Soc_TOP_MESSAGE_SHARED, + Soc_TOP_MESSAGE_UNSHARED, + Soc_TOP_MESSAGE_FAV, + Soc_TOP_MESSAGE_UNFAV, + Soc_TOP_MESSAGE_COMMENTED, + } Soc_TopMessage_t; + static const Act_Action_t Soc_DefaultActions[Soc_NUM_NOTE_TYPES] = { ActUnk, // Soc_NOTE_UNKNOWN @@ -167,6 +177,7 @@ struct SocialPublishing long PublisherCod; // Sharer or writer of a comment Soc_PubType_t PubType; time_t DateTimeUTC; + Soc_TopMessage_t TopMessage; // Used to show feedback on the action made }; struct SocialNote @@ -179,6 +190,7 @@ struct SocialNote bool Unavailable; // File, forum post, notice,... unavailable (removed) time_t DateTimeUTC; unsigned NumShared; // Number of times (users) this note has been shared + unsigned NumFavs; // Number of times (users) this note has been favourited }; struct SocialComment @@ -229,10 +241,11 @@ static void Soc_PutLinkToViewNewPublishings (void); static void Soc_PutLinkToViewOldPublishings (void); static void Soc_WriteSocialNote (const struct SocialNote *SocNot, - const struct SocialPublishing *SocPub, + Soc_TopMessage_t TopMessage, + long UsrCod, bool Highlight, bool ShowNoteAlone); -static void Soc_WriteTopPublisher (const struct SocialPublishing *SocPub); +static void Soc_WriteTopPublisher (Soc_TopMessage_t TopMessage,long UsrCod); static void Soc_WriteAuthorNote (struct UsrData *UsrDat); static void Soc_WriteDateTime (time_t TimeUTC); static void Soc_GetAndWriteSocialPost (long PstCod); @@ -257,9 +270,16 @@ static void Soc_WriteSocialComment (struct SocialComment *SocCom, bool ShowCommentAlone); static void Soc_WriteAuthorComment (struct UsrData *UsrDat); static void Soc_PutFormToRemoveComment (long ComCod); + static void Soc_PutDisabledIconShare (unsigned NumShared); +static void Soc_PutDisabledIconFav (unsigned NumFavs); + static void Soc_PutFormToShareSocialNote (long NotCod); -static void Soc_PutFormToUnshareSocialPublishing (long NotCod); +static void Soc_PutFormToFavSocialNote (long NotCod); + +static void Soc_PutFormToUnshareSocialNote (long NotCod); +static void Soc_PutFormToUnfavSocialNote (long NotCod); + static void Soc_PutFormToRemoveSocialPublishing (long NotCod); static void Soc_PutHiddenParamNotCod (long NotCod); @@ -270,8 +290,11 @@ static long Soc_GetParamComCod (void); static long Soc_ReceiveComment (void); static long Soc_ShareSocialNote (void); +static long Soc_FavSocialNote (void); + static long Soc_UnshareSocialNote (void); static void Soc_UnshareASocialPublishingFromDB (struct SocialNote *SocNot); +static long Soc_UnfavSocialNote (void); static void Soc_RequestRemovalSocialNote (void); static void Soc_RemoveSocialNote (void); @@ -282,7 +305,11 @@ static void Soc_RemoveSocialComment (void); static void Soc_RemoveASocialCommentFromDB (struct SocialComment *SocCom); static bool Soc_CheckIfNoteIsPublishedInTimelineByUsr (long NotCod,long UsrCod); +static bool Soc_CheckIfNoteIsFavouritedByUsr (long NotCod,long UsrCod); + static void Soc_UpdateNumTimesANoteHasBeenShared (struct SocialNote *SocNot); +static void Soc_UpdateNumTimesANoteHasBeenFav (struct SocialNote *SocNot); + static void Soc_ShowUsrsWhoHaveSharedSocialNote (const struct SocialNote *SocNot); static void Soc_GetDataOfSocialNoteByCod (struct SocialNote *SocNot); @@ -831,7 +858,8 @@ static void Soc_ShowTimeline (const char *Query,const char *Title, Soc_GetDataOfSocialNoteByCod (&SocNot); /* Write social note */ - Soc_WriteSocialNote (&SocNot,&SocPub, + Soc_WriteSocialNote (&SocNot, + SocPub.TopMessage,SocPub.PublisherCod, SocNot.NotCod == NotCodToHighlight, false); } @@ -887,7 +915,9 @@ static void Soc_InsertNewPubsInTimeline (const char *Query) Soc_GetDataOfSocialNoteByCod (&SocNot); /* Write social note */ - Soc_WriteSocialNote (&SocNot,&SocPub,false,false); + Soc_WriteSocialNote (&SocNot, + SocPub.TopMessage,SocPub.PublisherCod, + false,false); } /***** Free structure that stores the query result *****/ @@ -925,7 +955,9 @@ static void Soc_ShowOldPubsInTimeline (const char *Query) Soc_GetDataOfSocialNoteByCod (&SocNot); /* Write social note */ - Soc_WriteSocialNote (&SocNot,&SocPub,false,false); + Soc_WriteSocialNote (&SocNot, + SocPub.TopMessage,SocPub.PublisherCod, + false,false); } /***** Store first publishing code into session *****/ @@ -985,7 +1017,8 @@ static void Soc_PutLinkToViewOldPublishings (void) // All forms in this function and nested functions must have unique identifiers static void Soc_WriteSocialNote (const struct SocialNote *SocNot, - const struct SocialPublishing *SocPub, + Soc_TopMessage_t TopMessage, + long UsrCod, bool Highlight, // Highlight social note bool ShowNoteAlone) // Social note is shown alone, not in a list { @@ -997,6 +1030,7 @@ static void Soc_WriteSocialNote (const struct SocialNote *SocNot, struct UsrData UsrDat; bool IAmTheAuthor = false; bool IAmAPublisherOfThisSocNot = false; + bool IAmAFavouriterOfThisSocNot = false; struct Institution Ins; struct Centre Ctr; struct Degree Deg; @@ -1041,8 +1075,7 @@ static void Soc_WriteSocialNote (const struct SocialNote *SocNot, Crs.CrsCod = -1L; /***** Write sharer/commenter if distinct to author *****/ - if (SocPub) // SocPub may be NULL - Soc_WriteTopPublisher (SocPub); + Soc_WriteTopPublisher (TopMessage,UsrCod); /***** Initialize structure with user's data *****/ Usr_UsrDataConstructor (&UsrDat); @@ -1055,6 +1088,8 @@ static void Soc_WriteSocialNote (const struct SocialNote *SocNot, IAmTheAuthor = (UsrDat.UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod); IAmAPublisherOfThisSocNot = Soc_CheckIfNoteIsPublishedInTimelineByUsr (SocNot->NotCod, Gbl.Usrs.Me.UsrDat.UsrCod); + IAmAFavouriterOfThisSocNot = Soc_CheckIfNoteIsFavouritedByUsr (SocNot->NotCod, + Gbl.Usrs.Me.UsrDat.UsrCod); } /***** Left: write author's photo *****/ @@ -1198,7 +1233,7 @@ static void Soc_WriteSocialNote (const struct SocialNote *SocNot, else if (IAmAPublisherOfThisSocNot) // I am a sharer of this social note, // but not the author ==> I have shared this social note /* Put icon to unshare this publishing */ - Soc_PutFormToUnshareSocialPublishing (SocNot->NotCod); + Soc_PutFormToUnshareSocialNote (SocNot->NotCod); else // I am not the author and I am not a sharer { if (SocNot->Unavailable) // Unavailable social notes can not be shared @@ -1211,7 +1246,22 @@ static void Soc_WriteSocialNote (const struct SocialNote *SocNot, /* Show who have shared this social note */ Soc_ShowUsrsWhoHaveSharedSocialNote (SocNot); - /* Put icon to remove this publishing */ + /* Put icon to mark this social note as favourite */ + if (IAmTheAuthor) // I am the author + Soc_PutDisabledIconFav (SocNot->NumFavs); + else if (IAmAFavouriterOfThisSocNot) // I have favourited this social note + /* Put icon to unfav this publishing */ + Soc_PutFormToUnfavSocialNote (SocNot->NotCod); + else // I am not the author and I am not a sharer + { + if (SocNot->Unavailable) // Unavailable social notes can not be favourited + Soc_PutDisabledIconFav (SocNot->NumFavs); + else + /* Put icon to share this publishing */ + Soc_PutFormToFavSocialNote (SocNot->NotCod); + } + + /* Put icon to remove this social note */ if (IAmTheAuthor) Soc_PutFormToRemoveSocialPublishing (SocNot->NotCod); @@ -1245,56 +1295,63 @@ static void Soc_WriteSocialNote (const struct SocialNote *SocNot, /*****************************************************************************/ // All forms in this function and nested functions must have unique identifiers -static void Soc_WriteTopPublisher (const struct SocialPublishing *SocPub) +static void Soc_WriteTopPublisher (Soc_TopMessage_t TopMessage,long UsrCod) { extern const char *Txt_View_public_profile; - extern const char *Txt_SOCIAL_USER_has_stopped_sharing; extern const char *Txt_SOCIAL_USER_has_shared; + extern const char *Txt_SOCIAL_USER_has_stopped_sharing; + extern const char *Txt_SOCIAL_USER_has_marked_as_favourite; + extern const char *Txt_SOCIAL_USER_has_unmarked_as_favourite; extern const char *Txt_SOCIAL_USER_has_commented; struct UsrData UsrDat; - if (SocPub) - if (SocPub->PubType != Soc_PUB_ORIGINAL_NOTE) + if (TopMessage != Soc_TOP_MESSAGE_NONE) + { + /***** Initialize structure with user's data *****/ + Usr_UsrDataConstructor (&UsrDat); + + /***** Get user's data *****/ + UsrDat.UsrCod = UsrCod; + if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat)) // Really we only need EncryptedUsrCod and FullName { - /***** Initialize structure with user's data *****/ - Usr_UsrDataConstructor (&UsrDat); + fprintf (Gbl.F.Out,"
"); - /***** Get user's data *****/ - UsrDat.UsrCod = SocPub->PublisherCod; - if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat)) // Really we only need EncryptedUsrCod and FullName + /***** Show user's name inside form to go to user's public profile *****/ + Act_FormStartUnique (ActSeePubPrf); + Usr_PutParamUsrCodEncrypted (UsrDat.EncryptedUsrCod); + Act_LinkFormSubmitUnique (Txt_View_public_profile,"SOCIAL_TOP_PUBLISHER"); + Str_LimitLengthHTMLStr (UsrDat.FullName,40); + fprintf (Gbl.F.Out,"%s",UsrDat.FullName); + Act_FormEnd (); + + /***** Show action made *****/ + switch (TopMessage) { - fprintf (Gbl.F.Out,"
"); - - /***** Show user's name inside form to go to user's public profile *****/ - Act_FormStartUnique (ActSeePubPrf); - Usr_PutParamUsrCodEncrypted (UsrDat.EncryptedUsrCod); - Act_LinkFormSubmitUnique (Txt_View_public_profile,"SOCIAL_TOP_PUBLISHER"); - Str_LimitLengthHTMLStr (UsrDat.FullName,40); - fprintf (Gbl.F.Out,"%s",UsrDat.FullName); - Act_FormEnd (); - - /***** Show action made *****/ - switch (SocPub->PubType) - { - case Soc_PUB_UNKNOWN: // Used to print message indicating that I have unshared - fprintf (Gbl.F.Out," %s",Txt_SOCIAL_USER_has_stopped_sharing); - break; - case Soc_PUB_ORIGINAL_NOTE: // Not applicable - break; - case Soc_PUB_SHARED_NOTE: - fprintf (Gbl.F.Out," %s",Txt_SOCIAL_USER_has_shared); - break; - case Soc_PUB_COMMENT_TO_NOTE: - fprintf (Gbl.F.Out," %s",Txt_SOCIAL_USER_has_commented); - break; - } - - fprintf (Gbl.F.Out,"
"); + case Soc_TOP_MESSAGE_NONE: // Not applicable + break; + case Soc_TOP_MESSAGE_SHARED: + fprintf (Gbl.F.Out," %s",Txt_SOCIAL_USER_has_shared); + break; + case Soc_TOP_MESSAGE_UNSHARED: + fprintf (Gbl.F.Out," %s",Txt_SOCIAL_USER_has_stopped_sharing); + break; + case Soc_TOP_MESSAGE_FAV: + fprintf (Gbl.F.Out," %s",Txt_SOCIAL_USER_has_marked_as_favourite); + break; + case Soc_TOP_MESSAGE_UNFAV: + fprintf (Gbl.F.Out," %s",Txt_SOCIAL_USER_has_unmarked_as_favourite); + break; + case Soc_TOP_MESSAGE_COMMENTED: + fprintf (Gbl.F.Out," %s",Txt_SOCIAL_USER_has_commented); + break; } - /***** Free memory used for user's data *****/ - Usr_UsrDataDestructor (&UsrDat); + fprintf (Gbl.F.Out,"
"); } + + /***** Free memory used for user's data *****/ + Usr_UsrDataDestructor (&UsrDat); + } } /*****************************************************************************/ @@ -2217,7 +2274,7 @@ static void Soc_PutDisabledIconShare (unsigned NumShared) strcpy (Gbl.Title,Txt_SOCIAL_NOTE_Not_shared_by_anyone); /***** Disabled icon to share *****/ - fprintf (Gbl.F.Out,"
" + fprintf (Gbl.F.Out,"
" "\"%s\"" @@ -2226,6 +2283,30 @@ static void Soc_PutDisabledIconShare (unsigned NumShared) Gbl.Title,Gbl.Title); } +/*****************************************************************************/ +/****************** Put disabled icon to mark as favourite *******************/ +/*****************************************************************************/ + +static void Soc_PutDisabledIconFav (unsigned NumFavs) + { + extern const char *Txt_SOCIAL_NOTE_Favourited_by_X_USERS; + extern const char *Txt_SOCIAL_NOTE_Not_favourited_by_anyone; + + if (NumFavs) + sprintf (Gbl.Title,Txt_SOCIAL_NOTE_Favourited_by_X_USERS,NumFavs); + else + strcpy (Gbl.Title,Txt_SOCIAL_NOTE_Not_favourited_by_anyone); + + /***** Disabled icon to mark as favourite *****/ + fprintf (Gbl.F.Out,"
" + "\"%s\"" + "
", + Gbl.Prefs.IconsURL, + Gbl.Title,Gbl.Title); + } + /*****************************************************************************/ /************************* Form to share social note *************************/ /*****************************************************************************/ @@ -2244,7 +2325,7 @@ static void Soc_PutFormToShareSocialNote (long NotCod) else Act_FormStartUnique (ActShaSocNotGbl); Soc_PutHiddenParamNotCod (NotCod); - fprintf (Gbl.F.Out,"
" + fprintf (Gbl.F.Out,"
" " 0) + { + Act_FormStartUniqueAnchor (ActFavSocNotUsr,"timeline"); + Usr_PutParamOtherUsrCodEncrypted (); + } + else + Act_FormStartUnique (ActFavSocNotGbl); + Soc_PutHiddenParamNotCod (NotCod); + fprintf (Gbl.F.Out,"
" + "" + "
", + Gbl.Prefs.IconsURL, + Txt_Mark_as_favourite,Txt_Mark_as_favourite); + Act_FormEnd (); + } + +/*****************************************************************************/ +/*************** Form to unshare (stop sharing) social note ******************/ +/*****************************************************************************/ +// All forms in this function and nested functions must have unique identifiers + +static void Soc_PutFormToUnshareSocialNote (long NotCod) { extern const char *Txt_Unshare; /***** Form to share social publishing *****/ if (Gbl.Usrs.Other.UsrDat.UsrCod > 0) { - Act_FormStartUniqueAnchor (ActUnsSocPubUsr,"timeline"); + Act_FormStartUniqueAnchor (ActUnsSocNotUsr,"timeline"); Usr_PutParamOtherUsrCodEncrypted (); } else - Act_FormStartUnique (ActUnsSocPubGbl); + Act_FormStartUnique (ActUnsSocNotGbl); Soc_PutHiddenParamNotCod (NotCod); - fprintf (Gbl.F.Out,"
" + fprintf (Gbl.F.Out,"
" " 0) + { + Act_FormStartUniqueAnchor (ActUnfSocNotUsr,"timeline"); + Usr_PutParamOtherUsrCodEncrypted (); + } + else + Act_FormStartUnique (ActUnfSocNotGbl); + Soc_PutHiddenParamNotCod (NotCod); + fprintf (Gbl.F.Out,"
" + "" + "
", + Gbl.Prefs.IconsURL, + Txt_Favourite,Txt_Favourite); + Act_FormEnd (); + } + /*****************************************************************************/ /******************** Form to remove social publishing ***********************/ /*****************************************************************************/ @@ -2440,7 +2579,9 @@ static long Soc_ReceiveComment (void) DB_QueryINSERT (Query,"can not store comment content"); /***** Show the social note just commented *****/ - Soc_WriteSocialNote (&SocNot,&SocPub,true,true); + Soc_WriteSocialNote (&SocNot, + Soc_TOP_MESSAGE_COMMENTED,Gbl.Usrs.Me.UsrDat.UsrCod, + true,true); } } else @@ -2531,6 +2672,92 @@ static long Soc_ShareSocialNote (void) return SocNot.NotCod; } +/*****************************************************************************/ +/********************** Mark a social note as favourite **********************/ +/*****************************************************************************/ + +void Soc_FavSocialNoteGbl (void) + { + long NotCod; + + /***** Mark social note as favourite *****/ + NotCod = Soc_FavSocialNote (); + + /***** Write updated timeline after marking as favourite (global) *****/ + Soc_ShowTimelineGblHighlightingNot (NotCod); + } + +void Soc_FavSocialNoteUsr (void) + { + long NotCod; + + /***** Get user whom profile is displayed *****/ + Usr_GetParamOtherUsrCodEncryptedAndGetUsrData (); + + /***** Show user's profile *****/ + Prf_ShowUserProfile (); + + /***** Start section *****/ + fprintf (Gbl.F.Out,"
"); + + /***** Mark social note as favourite *****/ + NotCod = Soc_FavSocialNote (); + + /***** Write updated timeline after marking as favourite (user) *****/ + Soc_ShowTimelineUsrHighlightingNot (NotCod); + + /***** End section *****/ + fprintf (Gbl.F.Out,"
"); + } + +static long Soc_FavSocialNote (void) + { + extern const char *Txt_The_original_post_no_longer_exists; + struct SocialNote SocNot; + bool IAmTheAuthor; + bool IAmAFavouriterOfThisSocNot; + bool ICanFav; + char Query[256]; + + /***** Get the code of the social note to mark as favourite *****/ + SocNot.NotCod = Soc_GetParamNotCod (); + + /***** Get data of social note *****/ + Soc_GetDataOfSocialNoteByCod (&SocNot); + + if (SocNot.NotCod > 0) + { + IAmTheAuthor = (SocNot.UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod); + IAmAFavouriterOfThisSocNot = Soc_CheckIfNoteIsFavouritedByUsr (SocNot.NotCod, + Gbl.Usrs.Me.UsrDat.UsrCod); + ICanFav = (Gbl.Usrs.Me.Logged && + !IAmTheAuthor && // I am not the author + !IAmAFavouriterOfThisSocNot); // I have not favourited the note + if (ICanFav) + { + /***** Mark as favourite in database *****/ + sprintf (Query,"INSERT IGNORE INTO social_notes_fav" + " (NotCod,UsrCod) VALUES ('%ld','%ld')", + SocNot.NotCod, + Gbl.Usrs.Me.UsrDat.UsrCod); + DB_QueryINSERT (Query,"can not favourite social note"); + + /* Update number of times this social note is favourited */ + Soc_UpdateNumTimesANoteHasBeenFav (&SocNot); + + /***** Show the social note corresponding + to the publishing just fav *****/ + Soc_WriteSocialNote (&SocNot, + Soc_TOP_MESSAGE_FAV,Gbl.Usrs.Me.UsrDat.UsrCod, + true,true); + } + } + else + Lay_ShowAlert (Lay_WARNING,Txt_The_original_post_no_longer_exists); + + return SocNot.NotCod; + } + /*****************************************************************************/ /***************** Unshare a previously shared social note *******************/ /*****************************************************************************/ @@ -2553,7 +2780,7 @@ void Soc_UnshareSocialNoteUsr (void) /***** Get user whom profile is displayed *****/ Usr_GetParamOtherUsrCodEncryptedAndGetUsrData (); - /***** Show user's profile *****/ + /***** Show user's profile *****/ Prf_ShowUserProfile (); /***** Start section *****/ @@ -2572,7 +2799,6 @@ void Soc_UnshareSocialNoteUsr (void) static long Soc_UnshareSocialNote (void) { struct SocialNote SocNot; - struct SocialPublishing SocPub; // Used to print message indicating that I have unshared bool IAmTheAuthor; bool IAmAPublisherOfThisSocNot; bool ICanUnshare; @@ -2600,9 +2826,9 @@ static long Soc_UnshareSocialNote (void) /***** Show the social note corresponding to the publishing just unshared *****/ - SocPub.PublisherCod = Gbl.Usrs.Me.UsrDat.UsrCod; - SocPub.PubType = Soc_PUB_UNKNOWN; // Used to print message indicating that I have unshared - Soc_WriteSocialNote (&SocNot,&SocPub,true,true); + Soc_WriteSocialNote (&SocNot, + Soc_TOP_MESSAGE_UNSHARED,Gbl.Usrs.Me.UsrDat.UsrCod, + true,true); } return SocNot.NotCod; @@ -2627,6 +2853,84 @@ static void Soc_UnshareASocialPublishingFromDB (struct SocialNote *SocNot) DB_QueryDELETE (Query,"can not remove a social publishing"); } +/*****************************************************************************/ +/******* Stop marking as favourite a previously favourited social note *******/ +/*****************************************************************************/ + +void Soc_UnfavSocialNoteGbl (void) + { + long NotCod; + + /***** Stop marking as favourite a previously favourited social note *****/ + NotCod = Soc_UnfavSocialNote (); + + /***** Write updated timeline after unfav (global) *****/ + Soc_ShowTimelineGblHighlightingNot (NotCod); + } + +void Soc_UnfavSocialNoteUsr (void) + { + long NotCod; + + /***** Get user whom profile is displayed *****/ + Usr_GetParamOtherUsrCodEncryptedAndGetUsrData (); + + /***** Show user's profile *****/ + Prf_ShowUserProfile (); + + /***** Start section *****/ + fprintf (Gbl.F.Out,"
"); + + /***** Unshare a previously shared social note *****/ + NotCod = Soc_UnfavSocialNote (); + + /***** Write updated timeline after unfav (user) *****/ + Soc_ShowTimelineUsrHighlightingNot (NotCod); + + /***** End section *****/ + fprintf (Gbl.F.Out,"
"); + } + +static long Soc_UnfavSocialNote (void) + { + struct SocialNote SocNot; + bool IAmTheAuthor; + bool IAmAFavouriterOfThisSocNot; + bool ICanUnfav; + char Query[256]; + + /***** Get data of social note *****/ + SocNot.NotCod = Soc_GetParamNotCod (); + Soc_GetDataOfSocialNoteByCod (&SocNot); + + IAmTheAuthor = (SocNot.UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod); + IAmAFavouriterOfThisSocNot = Soc_CheckIfNoteIsFavouritedByUsr (SocNot.NotCod, + Gbl.Usrs.Me.UsrDat.UsrCod); + ICanUnfav = (Gbl.Usrs.Me.Logged && + !IAmTheAuthor && // I am not the author + IAmAFavouriterOfThisSocNot); // I have favourited the note + if (ICanUnfav) + { + /***** Delete the mark as favourite from database *****/ + sprintf (Query,"DELETE FROM social_notes_fav" + " WHERE NotCod='%ld' AND UsrCod='%ld'", + SocNot.NotCod, + Gbl.Usrs.Me.UsrDat.UsrCod); + DB_QueryDELETE (Query,"can not unfavourite social note"); + + /***** Update number of times this social note is favourited *****/ + Soc_UpdateNumTimesANoteHasBeenFav (&SocNot); + + /***** Show the social note corresponding + to the publishing just unfavourited *****/ + Soc_WriteSocialNote (&SocNot, + Soc_TOP_MESSAGE_UNFAV,Gbl.Usrs.Me.UsrDat.UsrCod, + true,true); + } + + return SocNot.NotCod; + } + /*****************************************************************************/ /******************* Request the removal of a social note ********************/ /*****************************************************************************/ @@ -2683,7 +2987,9 @@ static void Soc_RequestRemovalSocialNote (void) Lay_ShowAlert (Lay_WARNING,Txt_Do_you_really_want_to_remove_the_following_post); /* Show social note */ - Soc_WriteSocialNote (&SocNot,NULL,false,true); + Soc_WriteSocialNote (&SocNot, + Soc_TOP_MESSAGE_NONE,-1L, + false,true); /***** Form to ask for confirmation to remove this social post *****/ /* Start form */ @@ -3051,6 +3357,20 @@ static bool Soc_CheckIfNoteIsPublishedInTimelineByUsr (long NotCod,long UsrCod) return (DB_QueryCOUNT (Query,"can not check if a user has published a social note") != 0); } +/*****************************************************************************/ +/*************** Check if a user has favourited a social note ****************/ +/*****************************************************************************/ + +static bool Soc_CheckIfNoteIsFavouritedByUsr (long NotCod,long UsrCod) + { + char Query[256]; + + sprintf (Query,"SELECT COUNT(*) FROM social_notes_fav" + " WHERE NotCod='%ld' AND UsrCod='%ld'", + NotCod,UsrCod); + return (DB_QueryCOUNT (Query,"can not check if a user has favourited a social note") != 0); + } + /*****************************************************************************/ /******** Get number of times a note code has been shared in timeline ********/ /*****************************************************************************/ @@ -3070,6 +3390,23 @@ static void Soc_UpdateNumTimesANoteHasBeenShared (struct SocialNote *SocNot) SocNot->NumShared = (unsigned) DB_QueryCOUNT (Query,"can not get number of times a note has been shared"); } +/*****************************************************************************/ +/************ Get number of times a note code has been favourited ************/ +/*****************************************************************************/ + +static void Soc_UpdateNumTimesANoteHasBeenFav (struct SocialNote *SocNot) + { + char Query[256]; + + /***** Get number of times (users) this note has been favourited *****/ + sprintf (Query,"SELECT COUNT(*) FROM social_notes_fav" + " WHERE NotCod='%ld'" + " AND UsrCod<>'%ld'", // Extra check + SocNot->NotCod, + SocNot->UsrCod); // The author + SocNot->NumFavs = (unsigned) DB_QueryCOUNT (Query,"can not get number of times a note has been favourited"); + } + /*****************************************************************************/ /**************** Show users who have shared this social note ****************/ /*****************************************************************************/ @@ -3176,6 +3513,9 @@ static void Soc_GetDataOfSocialNoteByCod (struct SocialNote *SocNot) /***** Get number of times this social note has been shared *****/ Soc_UpdateNumTimesANoteHasBeenShared (SocNot); + + /***** Get number of times this social note has been favourited *****/ + Soc_UpdateNumTimesANoteHasBeenFav (SocNot); } else /***** Reset fields of social note *****/ @@ -3240,6 +3580,19 @@ static void Soc_GetDataOfSocialPublishingFromRow (MYSQL_ROW row,struct SocialPub /* Get type of publishing (row[3]) */ SocPub->PubType = Soc_GetPubTypeFromStr ((const char *) row[3]); + switch (SocPub->PubType) + { + case Soc_PUB_UNKNOWN: + case Soc_PUB_ORIGINAL_NOTE: + SocPub->TopMessage = Soc_TOP_MESSAGE_NONE; + break; + case Soc_PUB_SHARED_NOTE: + SocPub->TopMessage = Soc_TOP_MESSAGE_SHARED; + break; + case Soc_PUB_COMMENT_TO_NOTE: + SocPub->TopMessage = Soc_TOP_MESSAGE_COMMENTED; + break; + } /* Get time of the note (row[4]) */ SocPub->DateTimeUTC = Dat_GetUNIXTimeFromStr (row[4]); diff --git a/swad_social.h b/swad_social.h index 2f5678087..e25fdcc79 100644 --- a/swad_social.h +++ b/swad_social.h @@ -113,8 +113,13 @@ void Soc_ReceiveCommentUsr (void); void Soc_ShareSocialNoteGbl (void); void Soc_ShareSocialNoteUsr (void); +void Soc_FavSocialNoteGbl (void); +void Soc_FavSocialNoteUsr (void); + void Soc_UnshareSocialNoteGbl (void); void Soc_UnshareSocialNoteUsr (void); +void Soc_UnfavSocialNoteGbl (void); +void Soc_UnfavSocialNoteUsr (void); void Soc_RequestRemSocialNoteGbl (void); void Soc_RequestRemSocialNoteUsr (void); diff --git a/swad_text.c b/swad_text.c index 719e60a06..ffc119958 100644 --- a/swad_text.c +++ b/swad_text.c @@ -11055,6 +11055,27 @@ const char *Txt_Family_address = "Endereço Família"; #endif +const char *Txt_Favourite = +#if L==1 + "Favorit"; +#elif L==2 + "Favorit"; +#elif L==3 + "Favourite"; +#elif L==4 + "Favorito"; +#elif L==5 + "Favori"; +#elif L==6 + "Favorito"; // Okoteve traducción +#elif L==7 + "Preferito"; +#elif L==8 + "Ulubiony"; +#elif L==9 + "Favorito"; +#endif + const char *Txt_Feedback = #if L==1 "Realimentación"; // Necessita traduccio @@ -16403,6 +16424,27 @@ const char *Txt_Mark_all_notifications_as_read = "Marcar todas as notificações como lidas"; #endif +const char *Txt_Mark_as_favourite = +#if L==1 + "Marca com favorit"; +#elif L==2 + "Markieren als Favorit"; +#elif L==3 + "Mark as favourite"; +#elif L==4 + "Marcar como favorito"; +#elif L==5 + "Marquer comme favori"; +#elif L==6 + "Marcar como favorito"; // Okoteve traducción +#elif L==7 + "Segnare come preferito"; +#elif L==8 + "Oznacz jako ulubiony"; +#elif L==9 + "Marcar como favorito"; +#endif + const char *Txt_Marks_management_area = #if L==1 "Zona d'administració de qualificacions"; @@ -35740,6 +35782,27 @@ const char *Txt_SOCIAL_NOTE[Soc_NUM_NOTE_TYPES] = #endif }; +const char *Txt_SOCIAL_NOTE_Favourited_by_X_USERS = // Warning: it is very important to include %u in the following sentences +#if L==1 + "Marcat com favorit per %u"; +#elif L==2 + "Von %u vorgemerkt"; +#elif L==3 + "Favourited by %u"; +#elif L==4 + "Marcado como favorito por %u"; +#elif L==5 + "Ajouté aux favoris par %u"; +#elif L==6 + "Marcado como favorito por %u"; // Okoteve traducción +#elif L==7 + "Preferiti da %u"; +#elif L==8 + "Dodane do ulubionych przez %u"; +#elif L==9 + "Marcado como favorito por %u"; +#endif + const char *Txt_SOCIAL_NOTE_Shared_by_X_USERS = // Warning: it is very important to include %u in the following sentences #if L==1 "Compartit per %u"; @@ -35761,6 +35824,27 @@ const char *Txt_SOCIAL_NOTE_Shared_by_X_USERS = // Warning: it is very important "Compartilhado por %u"; #endif +const char *Txt_SOCIAL_NOTE_Not_favourited_by_anyone = // No longer shared +#if L==1 + "No marcat com favorit per ningú"; +#elif L==2 + "Niemand hat sie als Favorit markiert"; +#elif L==3 + "Not favourited by anyone"; +#elif L==4 + "No marcado como favorito por nadie"; +#elif L==5 + "Personne n'a marqué comme favori"; +#elif L==6 + "No marcado como favorito por nadie"; // Okoteve traducción +#elif L==7 + "Non preferiti da chiunque"; +#elif L==8 + "Nie przez nikogo ulubionych"; +#elif L==9 + "Não marcado como favorito por qualquer pessoa"; +#endif + const char *Txt_SOCIAL_NOTE_Not_shared_by_anyone = // No longer shared #if L==1 "No compartit per ningú"; @@ -35803,6 +35887,27 @@ const char *Txt_SOCIAL_USER_has_commented = "comentou:"; #endif +const char *Txt_SOCIAL_USER_has_marked_as_favourite = +#if L==1 + "ha marcat com favorit:"; +#elif L==2 + "hat als Favorit markiert:"; +#elif L==3 + "has marked as favourite:"; +#elif L==4 + "ha marcado como favorito:"; +#elif L==5 + "a marqué en tant que favori:"; +#elif L==6 + "ha marcado como favorito:"; // Okoteve traducción +#elif L==7 + "ha segnato come preferito:"; +#elif L==8 + "oznaczone jako ulubiony:"; +#elif L==9 + "marcou como favorito:"; +#endif + const char *Txt_SOCIAL_USER_has_shared = #if L==1 "ha compartit:"; @@ -35845,6 +35950,27 @@ const char *Txt_SOCIAL_USER_has_stopped_sharing = "parou compartilhar:"; #endif +const char *Txt_SOCIAL_USER_has_unmarked_as_favourite = +#if L==1 + "ha desmarcat com favorit:"; +#elif L==2 + "hat als Favorit unmarkiert:"; +#elif L==3 + "has unmarked as favourite:"; +#elif L==4 + "ha desmarcado como favorito:"; +#elif L==5 + "a pas marqué en tant que favori:"; +#elif L==6 + "ha desmarcado como favorito:"; // Okoteve traducción +#elif L==7 + "ha smarcato come preferito:"; +#elif L==8 + "nieoznaczonych jako ulubiony:"; +#elif L==9 + "desmarcou como favorito:"; +#endif + const char *Txt_Sort_degrees_by = #if L==1 "Ordenar titulacions per";