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