diff --git a/Makefile b/Makefile index c37a97bb..c864e55e 100644 --- a/Makefile +++ b/Makefile @@ -61,7 +61,8 @@ OBJS = swad_account.o swad_action.o swad_agenda.o swad_alert.o \ swad_system_config.o \ swad_tab.o swad_tag.o swad_test.o swad_test_config.o \ swad_test_import.o swad_test_print.o swad_test_visibility.o \ - swad_theme.o swad_timeline.o swad_timeline_favourite.o \ + swad_theme.o \ + swad_timeline.o swad_timeline_favourite.o swad_timeline_share.o \ swad_timetable.o \ swad_user.o \ swad_xml.o \ diff --git a/swad_action.c b/swad_action.c index 31211677..b7884b22 100644 --- a/swad_action.c +++ b/swad_action.c @@ -96,6 +96,7 @@ #include "swad_test_import.h" #include "swad_timeline.h" #include "swad_timeline_favourite.h" +#include "swad_timeline_share.h" #include "swad_timetable.h" #include "swad_zip.h" diff --git a/swad_changelog.h b/swad_changelog.h index 0f0f8712..64e4289d 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -553,7 +553,7 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 20.13 (2021-02-08)" +#define Log_PLATFORM_VERSION "SWAD 20.14 (2021-02-08)" #define CSS_FILE "swad20.8.css" #define JS_FILE "swad20.6.2.js" /* @@ -600,6 +600,7 @@ TODO: DNI de un estudiante sale err TODO: BUG: Cuando un tipo de grupo sólo tiene un grupo, inscribirse es voluntario, el estudiante sólo puede pertenecer a un grupo, y se inscribe en él, debería poder desapuntarse. Ahora no puede. + Version 20.14: Feb 08, 2021 New module timeline_shared. (305048 lines) Version 20.13: Feb 08, 2021 New module timeline_favourite. (304971 lines) Version 20.12.1: Feb 08, 2021 Code refactoring in timeline. (304900 lines) Version 20.12: Feb 08, 2021 Code refactoring in timeline. (304882 lines) diff --git a/swad_timeline.c b/swad_timeline.c index d3d9d34d..88f73b2c 100644 --- a/swad_timeline.c +++ b/swad_timeline.c @@ -53,6 +53,7 @@ #include "swad_setting.h" #include "swad_timeline.h" #include "swad_timeline_favourite.h" +#include "swad_timeline_share.h" /*****************************************************************************/ /****************************** Public constants *****************************/ @@ -71,9 +72,6 @@ #define TL_MAX_CHARS_IN_POST 1000 // Maximum number of characters in a post -#define TL_ICON_SHARE "share-alt.svg" -#define TL_ICON_SHARED "share-alt-green.svg" - typedef enum { TL_TIMELINE_USR, // Show the timeline of a user @@ -160,27 +158,6 @@ typedef enum */ -#define TL_NUM_PUB_TYPES 4 -// If the numbers assigned to each event type change, -// it is necessary to change old numbers to new ones in database table tl_notes -typedef enum - { - TL_PUB_UNKNOWN = 0, - TL_PUB_ORIGINAL_NOTE = 1, - TL_PUB_SHARED_NOTE = 2, - TL_PUB_COMMENT_TO_NOTE = 3, - } TL_PubType_t; - -struct TL_Publication - { - long PubCod; - long NotCod; - long PublisherCod; // Sharer or writer of the publication - TL_PubType_t PubType; - time_t DateTimeUTC; - TL_TopMessage_t TopMessage; // Used to show feedback on the action made - }; - /*****************************************************************************/ /************** External global variables from others modules ****************/ /*****************************************************************************/ @@ -262,7 +239,6 @@ static void TL_PutFormGoToAction (const struct TL_Note *SocNot, static void TL_GetNoteSummary (const struct TL_Note *SocNot, char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1]); static void TL_StoreAndPublishNoteInternal (TL_NoteType_t NoteType,long Cod,struct TL_Publication *SocPub); -static void TL_PublishNoteInTimeline (struct TL_Publication *SocPub); static void TL_PutFormToWriteNewPost (struct TL_Timeline *Timeline); static void TL_PutTextarea (const char *Placeholder,const char *ClassTextArea); @@ -302,13 +278,6 @@ static void TL_WriteAuthorComment (struct UsrData *UsrDat); static void TL_PutFormToRemoveComment (const struct TL_Timeline *Timeline, long PubCod); -static void TL_Sha_PutDisabledIconShare (unsigned NumShared); - -static void TL_Sha_PutFormToSeeAllSharersNote (const struct TL_Note *SocNot, - TL_HowManyUsrs_t HowManyUsrs); -static void TL_Sha_PutFormToShaNote (const struct TL_Note *SocNot); -static void TL_Sha_PutFormToUnsNote (const struct TL_Note *SocNot); - static void TL_PutFormToRemovePublication (const struct TL_Timeline *Timeline, long NotCod); @@ -316,11 +285,6 @@ static void TL_PutHiddenParamNotCod (long NotCod); static long TL_ReceiveComment (void); -static void TL_Sha_PutFormToShaUnsNote (const struct TL_Note *SocNot, - TL_HowManyUsrs_t HowManyUsrs); -static void TL_Sha_ShaNote (struct TL_Note *SocNot); -static void TL_Sha_UnsNote (struct TL_Note *SocNot); - static void TL_RequestRemovalNote (struct TL_Timeline *Timeline); static void TL_PutParamsRemoveNote (void *Timeline); static void TL_RemoveNote (void); @@ -333,13 +297,6 @@ static void TL_PutParamsRemoveComment (void *Timeline); static void TL_RemoveComment (void); static void TL_RemoveCommentMediaAndDBEntries (long PubCod); -static bool TL_Sha_CheckIfNoteIsSharedByUsr (long NotCod,long UsrCod); - -static void TL_Sha_UpdateNumTimesANoteHasBeenShared (struct TL_Note *SocNot); - -static void TL_Sha_ShowUsrsWhoHaveSharedNote (const struct TL_Note *SocNot, - TL_HowManyUsrs_t HowManyUsrs); - static void TL_GetDataOfPublicationFromRow (MYSQL_ROW row,struct TL_Publication *SocPub); static void TL_GetDataOfNoteFromRow (MYSQL_ROW row,struct TL_Note *SocNot); static TL_PubType_t TL_GetPubTypeFromStr (const char *Str); @@ -2399,7 +2356,7 @@ void TL_MarkNotesChildrenOfFolderAsUnavailable (const char *Path) /*****************************************************************************/ // SocPub->PubCod is set by the function -static void TL_PublishNoteInTimeline (struct TL_Publication *SocPub) +void TL_PublishNoteInTimeline (struct TL_Publication *SocPub) { /***** Publish note in timeline *****/ SocPub->PubCod = @@ -3207,74 +3164,6 @@ static void TL_PutFormToRemoveComment (const struct TL_Timeline *Timeline, Frm_EndForm (); } -/*****************************************************************************/ -/*********************** Put disabled icon to share **************************/ -/*****************************************************************************/ - -static void TL_Sha_PutDisabledIconShare (unsigned NumShared) - { - extern const char *Txt_TIMELINE_NOTE_Shared_by_X_USERS; - extern const char *Txt_TIMELINE_NOTE_Not_shared_by_anyone; - - /***** Disabled icon to share *****/ - if (NumShared) - { - Ico_PutDivIcon ("TL_ICO_DISABLED",TL_ICON_SHARE, - Str_BuildStringLong (Txt_TIMELINE_NOTE_Shared_by_X_USERS, - (long) NumShared)); - Str_FreeString (); - } - else - Ico_PutDivIcon ("TL_ICO_DISABLED",TL_ICON_SHARE, - Txt_TIMELINE_NOTE_Not_shared_by_anyone); - } - -/*****************************************************************************/ -/*********************** Form to share/unshare note **************************/ -/*****************************************************************************/ - -static void TL_Sha_PutFormToSeeAllSharersNote (const struct TL_Note *SocNot, - TL_HowManyUsrs_t HowManyUsrs) - { - extern const char *Txt_View_all_USERS; - char ParamCod[7 + Cns_MAX_DECIMAL_DIGITS_LONG + 1]; - - switch (HowManyUsrs) - { - case TL_SHOW_FEW_USRS: - /***** Form and icon to mark note as favourite *****/ - sprintf (ParamCod,"NotCod=%ld",SocNot->NotCod); - TL_FormFavSha (ActAllShaSocNotGbl,ActAllShaSocNotUsr,ParamCod, - TL_ICON_ELLIPSIS,Txt_View_all_USERS); - break; - case TL_SHOW_ALL_USRS: - Ico_PutIconOff (TL_ICON_ELLIPSIS,Txt_View_all_USERS); - break; - } - } - -static void TL_Sha_PutFormToShaNote (const struct TL_Note *SocNot) - { - extern const char *Txt_Share; - char ParamCod[7 + Cns_MAX_DECIMAL_DIGITS_LONG + 1]; - - /***** Form and icon to mark note as favourite *****/ - sprintf (ParamCod,"NotCod=%ld",SocNot->NotCod); - TL_FormFavSha (ActShaSocNotGbl,ActShaSocNotUsr,ParamCod, - TL_ICON_SHARE,Txt_Share); - } - -static void TL_Sha_PutFormToUnsNote (const struct TL_Note *SocNot) - { - extern const char *Txt_TIMELINE_NOTE_Shared; - char ParamCod[7 + Cns_MAX_DECIMAL_DIGITS_LONG + 1]; - - /***** Form and icon to mark note as favourite *****/ - sprintf (ParamCod,"NotCod=%ld",SocNot->NotCod); - TL_FormFavSha (ActUnsSocNotGbl,ActUnsSocNotUsr,ParamCod, - TL_ICON_SHARED,Txt_TIMELINE_NOTE_Shared); - } - /*****************************************************************************/ /************************ Form to remove publication *************************/ /*****************************************************************************/ @@ -3440,116 +3329,6 @@ static long TL_ReceiveComment (void) return SocNot.NotCod; } -/*****************************************************************************/ -/******************************** Share a note *******************************/ -/*****************************************************************************/ - -void TL_Sha_ShowAllSharersNoteUsr (void) - { - /***** Get user whom profile is displayed *****/ - Usr_GetParamOtherUsrCodEncryptedAndGetUsrData (); - - /***** Show all sharers *****/ - TL_Sha_ShowAllSharersNoteGbl (); - } - -void TL_Sha_ShowAllSharersNoteGbl (void) - { - struct TL_Note SocNot; - - /***** Get data of note *****/ - SocNot.NotCod = TL_GetParamNotCod (); - TL_GetDataOfNoteByCod (&SocNot); - - /***** Write HTML inside DIV with form to share/unshare *****/ - TL_Sha_PutFormToShaUnsNote (&SocNot,TL_SHOW_ALL_USRS); - } - -void TL_Sha_ShaNoteUsr (void) - { - /***** Get user whom profile is displayed *****/ - Usr_GetParamOtherUsrCodEncryptedAndGetUsrData (); - - /***** Share note *****/ - TL_Sha_ShaNoteGbl (); - } - -void TL_Sha_ShaNoteGbl (void) - { - struct TL_Note SocNot; - - /***** Share note *****/ - TL_Sha_ShaNote (&SocNot); - - /***** Write HTML inside DIV with form to unshare *****/ - TL_Sha_PutFormToShaUnsNote (&SocNot,TL_SHOW_FEW_USRS); - } - -static void TL_Sha_PutFormToShaUnsNote (const struct TL_Note *SocNot, - TL_HowManyUsrs_t HowManyUsrs) - { - bool IAmTheAuthor; - bool IAmASharerOfThisSocNot; - - /***** Put form to share/unshare this note *****/ - HTM_DIV_Begin ("class=\"TL_ICO\""); - IAmTheAuthor = Usr_ItsMe (SocNot->UsrCod); - if (SocNot->Unavailable || // Unavailable notes can not be shared - IAmTheAuthor) // I am the author - /* Put disabled icon */ - TL_Sha_PutDisabledIconShare (SocNot->NumShared); - else // Available and I am not the author - { - /* Put icon to share/unshare */ - IAmASharerOfThisSocNot = TL_Sha_CheckIfNoteIsSharedByUsr (SocNot->NotCod, - Gbl.Usrs.Me.UsrDat.UsrCod); - if (IAmASharerOfThisSocNot) // I have shared this note - TL_Sha_PutFormToUnsNote (SocNot); - else // I have not shared this note - TL_Sha_PutFormToShaNote (SocNot); - } - HTM_DIV_End (); - - /***** Show who have shared this note *****/ - TL_Sha_ShowUsrsWhoHaveSharedNote (SocNot,HowManyUsrs); - } - -static void TL_Sha_ShaNote (struct TL_Note *SocNot) - { - extern const char *Txt_The_original_post_no_longer_exists; - struct TL_Publication SocPub; - bool ItsMe; - long OriginalPubCod; - - /***** Get data of note *****/ - SocNot->NotCod = TL_GetParamNotCod (); - TL_GetDataOfNoteByCod (SocNot); - - if (SocNot->NotCod > 0) - { - ItsMe = Usr_ItsMe (SocNot->UsrCod); - if (Gbl.Usrs.Me.Logged && !ItsMe) // I am not the author - if (!TL_Sha_CheckIfNoteIsSharedByUsr (SocNot->NotCod, - Gbl.Usrs.Me.UsrDat.UsrCod)) // Not yet shared by me - { - /***** Share (publish note in timeline) *****/ - SocPub.NotCod = SocNot->NotCod; - SocPub.PublisherCod = Gbl.Usrs.Me.UsrDat.UsrCod; - SocPub.PubType = TL_PUB_SHARED_NOTE; - TL_PublishNoteInTimeline (&SocPub); // Set SocPub.PubCod - - /* Update number of times this note is shared */ - TL_Sha_UpdateNumTimesANoteHasBeenShared (SocNot); - - /**** Create notification about shared post - for the author of the post ***/ - OriginalPubCod = TL_GetPubCodOfOriginalNote (SocNot->NotCod); - if (OriginalPubCod > 0) - TL_CreateNotifToAuthor (SocNot->UsrCod,OriginalPubCod,Ntf_EVENT_TIMELINE_SHARE); - } - } - } - /*****************************************************************************/ /*********** Create a notification for the author of a post/comment **********/ /*****************************************************************************/ @@ -3589,69 +3368,6 @@ void TL_CreateNotifToAuthor (long AuthorCod,long PubCod, Usr_UsrDataDestructor (&UsrDat); } -/*****************************************************************************/ -/******************** Unshare a previously shared note ***********************/ -/*****************************************************************************/ - -void TL_Sha_UnsNoteUsr (void) - { - /***** Get user whom profile is displayed *****/ - Usr_GetParamOtherUsrCodEncryptedAndGetUsrData (); - - /***** Unshare note *****/ - TL_Sha_UnsNoteGbl (); - } - -void TL_Sha_UnsNoteGbl (void) - { - struct TL_Note SocNot; - - /***** Unshare note *****/ - TL_Sha_UnsNote (&SocNot); - - /***** Write HTML inside DIV with form to share *****/ - TL_Sha_PutFormToShaUnsNote (&SocNot,TL_SHOW_FEW_USRS); - } - -static void TL_Sha_UnsNote (struct TL_Note *SocNot) - { - extern const char *Txt_The_original_post_no_longer_exists; - long OriginalPubCod; - bool ItsMe; - - /***** Get data of note *****/ - SocNot->NotCod = TL_GetParamNotCod (); - TL_GetDataOfNoteByCod (SocNot); - - if (SocNot->NotCod > 0) - { - ItsMe = Usr_ItsMe (SocNot->UsrCod); - if (SocNot->NumShared && - Gbl.Usrs.Me.Logged && !ItsMe) // I am not the author - if (TL_Sha_CheckIfNoteIsSharedByUsr (SocNot->NotCod, - Gbl.Usrs.Me.UsrDat.UsrCod)) // I am a sharer - { - /***** Delete publication from database *****/ - DB_QueryDELETE ("can not remove a publication", - "DELETE FROM tl_pubs" - " WHERE NotCod=%ld" - " AND PublisherCod=%ld" - " AND PubType=%u", - SocNot->NotCod, - Gbl.Usrs.Me.UsrDat.UsrCod, - (unsigned) TL_PUB_SHARED_NOTE); - - /***** Update number of times this note is shared *****/ - TL_Sha_UpdateNumTimesANoteHasBeenShared (SocNot); - - /***** Mark possible notifications on this note as removed *****/ - OriginalPubCod = TL_GetPubCodOfOriginalNote (SocNot->NotCod); - if (OriginalPubCod > 0) - Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_SHARE,OriginalPubCod); - } - } - } - /*****************************************************************************/ /*********************** Request the removal of a note ***********************/ /*****************************************************************************/ @@ -4332,82 +4048,6 @@ void TL_RemoveUsrContent (long UsrCod) UsrCod); } -/*****************************************************************************/ -/****************** Check if a user has published a note *********************/ -/*****************************************************************************/ - -static bool TL_Sha_CheckIfNoteIsSharedByUsr (long NotCod,long UsrCod) - { - return (DB_QueryCOUNT ("can not check if a user has shared a note", - "SELECT COUNT(*) FROM tl_pubs" - " WHERE NotCod=%ld" - " AND PublisherCod=%ld" - " AND PubType=%u", - NotCod, - UsrCod, - (unsigned) TL_PUB_SHARED_NOTE) != 0); - } - -/*****************************************************************************/ -/********** Get number of times a note has been shared in timeline ***********/ -/*****************************************************************************/ - -static void TL_Sha_UpdateNumTimesANoteHasBeenShared (struct TL_Note *SocNot) - { - /***** Get number of times (users) this note has been shared *****/ - SocNot->NumShared = - (unsigned) DB_QueryCOUNT ("can not get number of times" - " a note has been shared", - "SELECT COUNT(*) FROM tl_pubs" - " WHERE NotCod=%ld" - " AND PublisherCod<>%ld" - " AND PubType=%u", - SocNot->NotCod, - SocNot->UsrCod, // The author - (unsigned) TL_PUB_SHARED_NOTE); - } - -/*****************************************************************************/ -/******************* Show users who have shared this note ********************/ -/*****************************************************************************/ - -static void TL_Sha_ShowUsrsWhoHaveSharedNote (const struct TL_Note *SocNot, - TL_HowManyUsrs_t HowManyUsrs) - { - MYSQL_RES *mysql_res; - unsigned NumFirstUsrs = 0; - - /***** Get users who have shared this note *****/ - if (SocNot->NumShared) - NumFirstUsrs = - (unsigned) DB_QuerySELECT (&mysql_res,"can not get users", - "SELECT PublisherCod FROM tl_pubs" - " WHERE NotCod=%ld" - " AND PublisherCod<>%ld" - " AND PubType=%u" - " ORDER BY PubCod LIMIT %u", - SocNot->NotCod, - SocNot->UsrCod, - (unsigned) TL_PUB_SHARED_NOTE, - HowManyUsrs == TL_SHOW_FEW_USRS ? TL_DEF_USRS_SHOWN : - TL_MAX_USRS_SHOWN); - - /***** Show users *****/ - HTM_DIV_Begin ("class=\"TL_NUM_USRS\""); - TL_ShowNumSharersOrFavers (SocNot->NumShared); - HTM_DIV_End (); - - HTM_DIV_Begin ("class=\"TL_USRS\""); - TL_ShowSharersOrFavers (&mysql_res,SocNot->NumShared,NumFirstUsrs); - if (NumFirstUsrs < SocNot->NumShared) - TL_Sha_PutFormToSeeAllSharersNote (SocNot,HowManyUsrs); - HTM_DIV_End (); - - /***** Free structure that stores the query result *****/ - if (SocNot->NumShared) - DB_FreeMySQLResult (&mysql_res); - } - /*****************************************************************************/ /************************ Show sharers or favouriters ************************/ /*****************************************************************************/ diff --git a/swad_timeline.h b/swad_timeline.h index 361b53aa..0ecba5e7 100644 --- a/swad_timeline.h +++ b/swad_timeline.h @@ -97,6 +97,27 @@ typedef enum TL_SHOW_ALL_USRS, // Show all favers/sharers } TL_HowManyUsrs_t; +#define TL_NUM_PUB_TYPES 4 +// If the numbers assigned to each event type change, +// it is necessary to change old numbers to new ones in database table tl_notes +typedef enum + { + TL_PUB_UNKNOWN = 0, + TL_PUB_ORIGINAL_NOTE = 1, + TL_PUB_SHARED_NOTE = 2, + TL_PUB_COMMENT_TO_NOTE = 3, + } TL_PubType_t; + +struct TL_Publication + { + long PubCod; + long NotCod; + long PublisherCod; // Sharer or writer of the publication + TL_PubType_t PubType; + time_t DateTimeUTC; + TL_TopMessage_t TopMessage; // Used to show feedback on the action made + }; + struct TL_PostContent { char Txt[Cns_MAX_BYTES_LONG_TEXT + 1]; @@ -154,6 +175,8 @@ void TL_MarkNoteAsUnavailable (TL_NoteType_t NoteType,long Cod); void TL_MarkNoteOneFileAsUnavailable (const char *Path); void TL_MarkNotesChildrenOfFolderAsUnavailable (const char *Path); +void TL_PublishNoteInTimeline (struct TL_Publication *SocPub); + void TL_ReceivePostUsr (void); void TL_ReceivePostGbl (void); @@ -167,17 +190,9 @@ long TL_GetParamPubCod (void); void TL_ReceiveCommentUsr (void); void TL_ReceiveCommentGbl (void); -void TL_Sha_ShowAllSharersNoteUsr (void); -void TL_Sha_ShowAllSharersNoteGbl (void); -void TL_Sha_ShaNoteUsr (void); -void TL_Sha_ShaNoteGbl (void); - void TL_CreateNotifToAuthor (long AuthorCod,long PubCod, Ntf_NotifyEvent_t NotifyEvent); -void TL_Sha_UnsNoteUsr (void); -void TL_Sha_UnsNoteGbl (void); - void TL_RequestRemNoteUsr (void); void TL_RequestRemNoteGbl (void); void TL_RemoveNoteUsr (void); diff --git a/swad_timeline_share.c b/swad_timeline_share.c new file mode 100644 index 00000000..42e2f43f --- /dev/null +++ b/swad_timeline_share.c @@ -0,0 +1,387 @@ +// swad_timeline_share.c: social timeline shared + +/* + SWAD (Shared Workspace At a Distance), + is a web platform developed at the University of Granada (Spain), + and used to support university teaching. + + This file is part of SWAD core. + Copyright (C) 1999-2020 Antonio Cañas Vargas + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General 3 License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +/*****************************************************************************/ +/*********************************** Headers *********************************/ +/*****************************************************************************/ + +#include "swad_database.h" +#include "swad_global.h" +#include "swad_timeline.h" +#include "swad_timeline_share.h" + +/*****************************************************************************/ +/****************************** Public constants *****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/************************* Private constants and types ***********************/ +/*****************************************************************************/ + +#define TL_ICON_SHARE "share-alt.svg" +#define TL_ICON_SHARED "share-alt-green.svg" + +/*****************************************************************************/ +/************** External global variables from others modules ****************/ +/*****************************************************************************/ + +extern struct Globals Gbl; + +/*****************************************************************************/ +/************************* Private global variables **************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Private prototypes ****************************/ +/*****************************************************************************/ + +static void TL_Sha_PutDisabledIconShare (unsigned NumShared); + +static void TL_Sha_PutFormToShaNote (const struct TL_Note *SocNot); +static void TL_Sha_PutFormToUnsNote (const struct TL_Note *SocNot); + +static void TL_Sha_ShaNote (struct TL_Note *SocNot); +static void TL_Sha_UnsNote (struct TL_Note *SocNot); + +static bool TL_Sha_CheckIfNoteIsSharedByUsr (long NotCod,long UsrCod); + +static void TL_Sha_ShowUsrsWhoHaveSharedNote (const struct TL_Note *SocNot, + TL_HowManyUsrs_t HowManyUsrs); + +/*****************************************************************************/ +/*********************** Put disabled icon to share **************************/ +/*****************************************************************************/ + +static void TL_Sha_PutDisabledIconShare (unsigned NumShared) + { + extern const char *Txt_TIMELINE_NOTE_Shared_by_X_USERS; + extern const char *Txt_TIMELINE_NOTE_Not_shared_by_anyone; + + /***** Disabled icon to share *****/ + if (NumShared) + { + Ico_PutDivIcon ("TL_ICO_DISABLED",TL_ICON_SHARE, + Str_BuildStringLong (Txt_TIMELINE_NOTE_Shared_by_X_USERS, + (long) NumShared)); + Str_FreeString (); + } + else + Ico_PutDivIcon ("TL_ICO_DISABLED",TL_ICON_SHARE, + Txt_TIMELINE_NOTE_Not_shared_by_anyone); + } + +/*****************************************************************************/ +/*********************** Form to share/unshare note **************************/ +/*****************************************************************************/ + +void TL_Sha_PutFormToSeeAllSharersNote (const struct TL_Note *SocNot, + TL_HowManyUsrs_t HowManyUsrs) + { + extern const char *Txt_View_all_USERS; + char ParamCod[7 + Cns_MAX_DECIMAL_DIGITS_LONG + 1]; + + switch (HowManyUsrs) + { + case TL_SHOW_FEW_USRS: + /***** Form and icon to mark note as favourite *****/ + sprintf (ParamCod,"NotCod=%ld",SocNot->NotCod); + TL_FormFavSha (ActAllShaSocNotGbl,ActAllShaSocNotUsr,ParamCod, + TL_ICON_ELLIPSIS,Txt_View_all_USERS); + break; + case TL_SHOW_ALL_USRS: + Ico_PutIconOff (TL_ICON_ELLIPSIS,Txt_View_all_USERS); + break; + } + } + +static void TL_Sha_PutFormToShaNote (const struct TL_Note *SocNot) + { + extern const char *Txt_Share; + char ParamCod[7 + Cns_MAX_DECIMAL_DIGITS_LONG + 1]; + + /***** Form and icon to mark note as favourite *****/ + sprintf (ParamCod,"NotCod=%ld",SocNot->NotCod); + TL_FormFavSha (ActShaSocNotGbl,ActShaSocNotUsr,ParamCod, + TL_ICON_SHARE,Txt_Share); + } + +static void TL_Sha_PutFormToUnsNote (const struct TL_Note *SocNot) + { + extern const char *Txt_TIMELINE_NOTE_Shared; + char ParamCod[7 + Cns_MAX_DECIMAL_DIGITS_LONG + 1]; + + /***** Form and icon to mark note as favourite *****/ + sprintf (ParamCod,"NotCod=%ld",SocNot->NotCod); + TL_FormFavSha (ActUnsSocNotGbl,ActUnsSocNotUsr,ParamCod, + TL_ICON_SHARED,Txt_TIMELINE_NOTE_Shared); + } + +/*****************************************************************************/ +/******************************** Share a note *******************************/ +/*****************************************************************************/ + +void TL_Sha_ShowAllSharersNoteUsr (void) + { + /***** Get user whom profile is displayed *****/ + Usr_GetParamOtherUsrCodEncryptedAndGetUsrData (); + + /***** Show all sharers *****/ + TL_Sha_ShowAllSharersNoteGbl (); + } + +void TL_Sha_ShowAllSharersNoteGbl (void) + { + struct TL_Note SocNot; + + /***** Get data of note *****/ + SocNot.NotCod = TL_GetParamNotCod (); + TL_GetDataOfNoteByCod (&SocNot); + + /***** Write HTML inside DIV with form to share/unshare *****/ + TL_Sha_PutFormToShaUnsNote (&SocNot,TL_SHOW_ALL_USRS); + } + +void TL_Sha_ShaNoteUsr (void) + { + /***** Get user whom profile is displayed *****/ + Usr_GetParamOtherUsrCodEncryptedAndGetUsrData (); + + /***** Share note *****/ + TL_Sha_ShaNoteGbl (); + } + +void TL_Sha_ShaNoteGbl (void) + { + struct TL_Note SocNot; + + /***** Share note *****/ + TL_Sha_ShaNote (&SocNot); + + /***** Write HTML inside DIV with form to unshare *****/ + TL_Sha_PutFormToShaUnsNote (&SocNot,TL_SHOW_FEW_USRS); + } + +static void TL_Sha_ShaNote (struct TL_Note *SocNot) + { + // extern const char *Txt_The_original_post_no_longer_exists; + struct TL_Publication SocPub; + bool ItsMe; + long OriginalPubCod; + + /***** Get data of note *****/ + SocNot->NotCod = TL_GetParamNotCod (); + TL_GetDataOfNoteByCod (SocNot); + + if (SocNot->NotCod > 0) + { + ItsMe = Usr_ItsMe (SocNot->UsrCod); + if (Gbl.Usrs.Me.Logged && !ItsMe) // I am not the author + if (!TL_Sha_CheckIfNoteIsSharedByUsr (SocNot->NotCod, + Gbl.Usrs.Me.UsrDat.UsrCod)) // Not yet shared by me + { + /***** Share (publish note in timeline) *****/ + SocPub.NotCod = SocNot->NotCod; + SocPub.PublisherCod = Gbl.Usrs.Me.UsrDat.UsrCod; + SocPub.PubType = TL_PUB_SHARED_NOTE; + TL_PublishNoteInTimeline (&SocPub); // Set SocPub.PubCod + + /* Update number of times this note is shared */ + TL_Sha_UpdateNumTimesANoteHasBeenShared (SocNot); + + /**** Create notification about shared post + for the author of the post ***/ + OriginalPubCod = TL_GetPubCodOfOriginalNote (SocNot->NotCod); + if (OriginalPubCod > 0) + TL_CreateNotifToAuthor (SocNot->UsrCod,OriginalPubCod,Ntf_EVENT_TIMELINE_SHARE); + } + } + } + +/*****************************************************************************/ +/******************** Unshare a previously shared note ***********************/ +/*****************************************************************************/ + +void TL_Sha_UnsNoteUsr (void) + { + /***** Get user whom profile is displayed *****/ + Usr_GetParamOtherUsrCodEncryptedAndGetUsrData (); + + /***** Unshare note *****/ + TL_Sha_UnsNoteGbl (); + } + +void TL_Sha_UnsNoteGbl (void) + { + struct TL_Note SocNot; + + /***** Unshare note *****/ + TL_Sha_UnsNote (&SocNot); + + /***** Write HTML inside DIV with form to share *****/ + TL_Sha_PutFormToShaUnsNote (&SocNot,TL_SHOW_FEW_USRS); + } + +static void TL_Sha_UnsNote (struct TL_Note *SocNot) + { + // extern const char *Txt_The_original_post_no_longer_exists; + long OriginalPubCod; + bool ItsMe; + + /***** Get data of note *****/ + SocNot->NotCod = TL_GetParamNotCod (); + TL_GetDataOfNoteByCod (SocNot); + + if (SocNot->NotCod > 0) + { + ItsMe = Usr_ItsMe (SocNot->UsrCod); + if (SocNot->NumShared && + Gbl.Usrs.Me.Logged && !ItsMe) // I am not the author + if (TL_Sha_CheckIfNoteIsSharedByUsr (SocNot->NotCod, + Gbl.Usrs.Me.UsrDat.UsrCod)) // I am a sharer + { + /***** Delete publication from database *****/ + DB_QueryDELETE ("can not remove a publication", + "DELETE FROM tl_pubs" + " WHERE NotCod=%ld" + " AND PublisherCod=%ld" + " AND PubType=%u", + SocNot->NotCod, + Gbl.Usrs.Me.UsrDat.UsrCod, + (unsigned) TL_PUB_SHARED_NOTE); + + /***** Update number of times this note is shared *****/ + TL_Sha_UpdateNumTimesANoteHasBeenShared (SocNot); + + /***** Mark possible notifications on this note as removed *****/ + OriginalPubCod = TL_GetPubCodOfOriginalNote (SocNot->NotCod); + if (OriginalPubCod > 0) + Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_SHARE,OriginalPubCod); + } + } + } + +void TL_Sha_PutFormToShaUnsNote (const struct TL_Note *SocNot, + TL_HowManyUsrs_t HowManyUsrs) + { + bool IAmTheAuthor; + bool IAmASharerOfThisSocNot; + + /***** Put form to share/unshare this note *****/ + HTM_DIV_Begin ("class=\"TL_ICO\""); + IAmTheAuthor = Usr_ItsMe (SocNot->UsrCod); + if (SocNot->Unavailable || // Unavailable notes can not be shared + IAmTheAuthor) // I am the author + /* Put disabled icon */ + TL_Sha_PutDisabledIconShare (SocNot->NumShared); + else // Available and I am not the author + { + /* Put icon to share/unshare */ + IAmASharerOfThisSocNot = TL_Sha_CheckIfNoteIsSharedByUsr (SocNot->NotCod, + Gbl.Usrs.Me.UsrDat.UsrCod); + if (IAmASharerOfThisSocNot) // I have shared this note + TL_Sha_PutFormToUnsNote (SocNot); + else // I have not shared this note + TL_Sha_PutFormToShaNote (SocNot); + } + HTM_DIV_End (); + + /***** Show who have shared this note *****/ + TL_Sha_ShowUsrsWhoHaveSharedNote (SocNot,HowManyUsrs); + } + +/*****************************************************************************/ +/****************** Check if a user has published a note *********************/ +/*****************************************************************************/ + +static bool TL_Sha_CheckIfNoteIsSharedByUsr (long NotCod,long UsrCod) + { + return (DB_QueryCOUNT ("can not check if a user has shared a note", + "SELECT COUNT(*) FROM tl_pubs" + " WHERE NotCod=%ld" + " AND PublisherCod=%ld" + " AND PubType=%u", + NotCod, + UsrCod, + (unsigned) TL_PUB_SHARED_NOTE) != 0); + } + +/*****************************************************************************/ +/********** Get number of times a note has been shared in timeline ***********/ +/*****************************************************************************/ + +void TL_Sha_UpdateNumTimesANoteHasBeenShared (struct TL_Note *SocNot) + { + /***** Get number of times (users) this note has been shared *****/ + SocNot->NumShared = + (unsigned) DB_QueryCOUNT ("can not get number of times" + " a note has been shared", + "SELECT COUNT(*) FROM tl_pubs" + " WHERE NotCod=%ld" + " AND PublisherCod<>%ld" + " AND PubType=%u", + SocNot->NotCod, + SocNot->UsrCod, // The author + (unsigned) TL_PUB_SHARED_NOTE); + } + +/*****************************************************************************/ +/******************* Show users who have shared this note ********************/ +/*****************************************************************************/ + +static void TL_Sha_ShowUsrsWhoHaveSharedNote (const struct TL_Note *SocNot, + TL_HowManyUsrs_t HowManyUsrs) + { + MYSQL_RES *mysql_res; + unsigned NumFirstUsrs = 0; + + /***** Get users who have shared this note *****/ + if (SocNot->NumShared) + NumFirstUsrs = + (unsigned) DB_QuerySELECT (&mysql_res,"can not get users", + "SELECT PublisherCod FROM tl_pubs" + " WHERE NotCod=%ld" + " AND PublisherCod<>%ld" + " AND PubType=%u" + " ORDER BY PubCod LIMIT %u", + SocNot->NotCod, + SocNot->UsrCod, + (unsigned) TL_PUB_SHARED_NOTE, + HowManyUsrs == TL_SHOW_FEW_USRS ? TL_DEF_USRS_SHOWN : + TL_MAX_USRS_SHOWN); + + /***** Show users *****/ + HTM_DIV_Begin ("class=\"TL_NUM_USRS\""); + TL_ShowNumSharersOrFavers (SocNot->NumShared); + HTM_DIV_End (); + + HTM_DIV_Begin ("class=\"TL_USRS\""); + TL_ShowSharersOrFavers (&mysql_res,SocNot->NumShared,NumFirstUsrs); + if (NumFirstUsrs < SocNot->NumShared) + TL_Sha_PutFormToSeeAllSharersNote (SocNot,HowManyUsrs); + HTM_DIV_End (); + + /***** Free structure that stores the query result *****/ + if (SocNot->NumShared) + DB_FreeMySQLResult (&mysql_res); + } + diff --git a/swad_timeline_share.h b/swad_timeline_share.h new file mode 100644 index 00000000..54ff0ccc --- /dev/null +++ b/swad_timeline_share.h @@ -0,0 +1,56 @@ +// swad_timeline_share.h: social timeline shared + +#ifndef _SWAD_TL_SHA +#define _SWAD_TL_SHA +/* + SWAD (Shared Workspace At a Distance in Spanish), + is a web platform developed at the University of Granada (Spain), + and used to support university teaching. + + This file is part of SWAD core. + Copyright (C) 1999-2020 Antonio Cañas Vargas + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +/*****************************************************************************/ +/********************************** Headers **********************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/****************************** Public constants *****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/******************************** Public types *******************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/****************************** Public prototypes ****************************/ +/*****************************************************************************/ + +void TL_Sha_PutFormToSeeAllSharersNote (const struct TL_Note *SocNot, + TL_HowManyUsrs_t HowManyUsrs); + +void TL_Sha_ShowAllSharersNoteUsr (void); +void TL_Sha_ShowAllSharersNoteGbl (void); +void TL_Sha_ShaNoteUsr (void); +void TL_Sha_ShaNoteGbl (void); +void TL_Sha_UnsNoteUsr (void); +void TL_Sha_UnsNoteGbl (void); +void TL_Sha_PutFormToShaUnsNote (const struct TL_Note *SocNot, + TL_HowManyUsrs_t HowManyUsrs); + +void TL_Sha_UpdateNumTimesANoteHasBeenShared (struct TL_Note *SocNot); + +#endif