mirror of https://github.com/acanas/swad-core.git
Version20.27
This commit is contained in:
parent
e5b7b3e425
commit
aa47fc1210
2
Makefile
2
Makefile
|
@ -62,7 +62,7 @@ OBJS = swad_account.o swad_action.o swad_agenda.o swad_alert.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_comment.o \
|
||||
swad_timeline_favourite.o swad_timeline_note.o \
|
||||
swad_timeline_favourite.o swad_timeline_note.o swad_timeline_post.o \
|
||||
swad_timeline_publication.o swad_timeline_share.o swad_timeline_who.o \
|
||||
swad_timetable.o \
|
||||
swad_user.o \
|
||||
|
|
|
@ -144,7 +144,7 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] =
|
|||
|
||||
[ActRefNewTL_PubGbl ] = {1509,-1,TabUnk,ActSeeTmlGbl ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_AJAX_RFRESH,TL_Who_GetParamWho ,TL_RefreshNewTimelineGbl ,NULL},
|
||||
[ActRefOldTL_PubGbl ] = {1510,-1,TabUnk,ActSeeTmlGbl ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_AJAX_NORMAL,TL_Who_GetParamWho ,TL_RefreshOldTimelineGbl ,NULL},
|
||||
[ActRcvTL_PstGbl ] = {1492,-1,TabUnk,ActSeeTmlGbl ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_DATA,Act_BRW_1ST_TAB,TL_Who_GetParamWho ,TL_ReceivePostGbl ,NULL},
|
||||
[ActRcvTL_PstGbl ] = {1492,-1,TabUnk,ActSeeTmlGbl ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_DATA,Act_BRW_1ST_TAB,TL_Who_GetParamWho ,TL_Pst_ReceivePostGbl ,NULL},
|
||||
[ActRcvTL_ComGbl ] = {1503,-1,TabUnk,ActSeeTmlGbl ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_DATA,Act_BRW_1ST_TAB,TL_Who_GetParamWho ,TL_Com_ReceiveCommentGbl ,NULL},
|
||||
[ActShoHidTL_ComGbl ] = {1806,-1,TabUnk,ActSeeTmlGbl ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_AJAX_NORMAL,NULL ,TL_Com_ShowHiddenCommentsGbl ,NULL},
|
||||
[ActAllShaTL_NotGbl ] = {1766,-1,TabUnk,ActSeeTmlGbl ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_AJAX_NORMAL,NULL ,TL_Sha_ShowAllSharersNoteGbl ,NULL},
|
||||
|
@ -164,7 +164,7 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] =
|
|||
[ActReqOthPubPrf ] = {1401,-1,TabUnk,ActSeeSocPrf ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Prf_RequestUserProfile ,NULL},
|
||||
|
||||
[ActRefOldTL_PubUsr ] = {1511,-1,TabUnk,ActSeeSocPrf ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_AJAX_NORMAL,NULL ,TL_RefreshOldTimelineUsr ,NULL},
|
||||
[ActRcvTL_PstUsr ] = {1498,-1,TabUnk,ActSeeSocPrf ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_DATA,Act_BRW_1ST_TAB,NULL ,TL_ReceivePostUsr ,NULL},
|
||||
[ActRcvTL_PstUsr ] = {1498,-1,TabUnk,ActSeeSocPrf ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_DATA,Act_BRW_1ST_TAB,NULL ,TL_Pst_ReceivePostUsr ,NULL},
|
||||
[ActRcvTL_ComUsr ] = {1504,-1,TabUnk,ActSeeSocPrf ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_DATA,Act_BRW_1ST_TAB,NULL ,TL_Com_ReceiveCommentUsr ,NULL},
|
||||
[ActShoHidTL_ComUsr ] = {1807,-1,TabUnk,ActSeeSocPrf ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_AJAX_NORMAL,NULL ,TL_Com_ShowHiddenCommentsUsr ,NULL},
|
||||
[ActAllShaTL_NotUsr ] = {1769,-1,TabUnk,ActSeeSocPrf ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_AJAX_NORMAL,NULL ,TL_Sha_ShowAllSharersNoteUsr ,NULL},
|
||||
|
|
|
@ -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.26.1 (2021-02-11)"
|
||||
#define Log_PLATFORM_VERSION "SWAD 20.27 (2021-02-11)"
|
||||
#define CSS_FILE "swad20.8.css"
|
||||
#define JS_FILE "swad20.6.2.js"
|
||||
/*
|
||||
|
@ -601,6 +601,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.
|
||||
TODO: Salvador Romero Cortés: @acanas opción para editar posts
|
||||
|
||||
Version 20.27: Feb 11, 2021 New module swad_timeline_post. (305593 lines)
|
||||
Version 20.26.1: Feb 11, 2021 Code refactoring in timeline. (305504 lines)
|
||||
Version 20.26: Feb 11, 2021 New module swad_timeline_who. (305540 lines)
|
||||
Version 20.25: Feb 11, 2021 New module swad_timeline_publication. (305440 lines)
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
/********************************** Headers **********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#include "swad_course.h"
|
||||
#include "swad_notification.h"
|
||||
#include "swad_statistic.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
/********************************* Headers ***********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#include "swad_user.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************* Public types and constants ************************/
|
||||
/*****************************************************************************/
|
||||
|
|
309
swad_timeline.c
309
swad_timeline.c
|
@ -21,37 +21,6 @@
|
|||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
/*********************************** Headers *********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _GNU_SOURCE // For asprintf
|
||||
#include <linux/limits.h> // For PATH_MAX
|
||||
#include <stdio.h> // For asprintf
|
||||
|
||||
#include "swad_database.h"
|
||||
#include "swad_figure.h"
|
||||
#include "swad_global.h"
|
||||
#include "swad_message.h"
|
||||
#include "swad_notification.h"
|
||||
#include "swad_photo.h"
|
||||
#include "swad_profile.h"
|
||||
#include "swad_timeline.h"
|
||||
#include "swad_timeline_favourite.h"
|
||||
#include "swad_timeline_note.h"
|
||||
#include "swad_timeline_publication.h"
|
||||
#include "swad_timeline_share.h"
|
||||
#include "swad_timeline_who.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************************** Public constants *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************* Private constants and types ***********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define TL_MAX_CHARS_IN_POST 1000 // Maximum number of characters in a post
|
||||
|
||||
/*
|
||||
mysql> SHOW TABLES LIKE 'tl_%';
|
||||
|
@ -150,6 +119,35 @@ mysql> SHOW TABLES LIKE 'tl_%';
|
|||
|______________|
|
||||
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
/*********************************** Headers *********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _GNU_SOURCE // For asprintf
|
||||
#include <linux/limits.h> // For PATH_MAX
|
||||
#include <stdio.h> // For asprintf
|
||||
|
||||
#include "swad_database.h"
|
||||
#include "swad_figure.h"
|
||||
#include "swad_global.h"
|
||||
#include "swad_message.h"
|
||||
#include "swad_notification.h"
|
||||
#include "swad_photo.h"
|
||||
#include "swad_profile.h"
|
||||
#include "swad_timeline.h"
|
||||
#include "swad_timeline_favourite.h"
|
||||
#include "swad_timeline_note.h"
|
||||
#include "swad_timeline_publication.h"
|
||||
#include "swad_timeline_share.h"
|
||||
#include "swad_timeline_who.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************************** Public constants *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************* Private constants and types ***********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/************** External global variables from others modules ****************/
|
||||
|
@ -161,10 +159,6 @@ extern struct Globals Gbl;
|
|||
/************************* Private global variables **************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
Usr_Who_t TL_GlobalWho;
|
||||
|
||||
#define TL_DEFAULT_WHO Usr_WHO_FOLLOWED
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Private prototypes ****************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -175,10 +169,6 @@ static void TL_ShowTimeline (struct TL_Timeline *Timeline,
|
|||
const char *Title,long NotCodToHighlight);
|
||||
static void TL_PutIconsTimeline (__attribute__((unused)) void *Args);
|
||||
|
||||
static void TL_PutFormToWriteNewPost (struct TL_Timeline *Timeline);
|
||||
|
||||
static long TL_ReceivePost (void);
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************ Initialize global timeline *************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -202,7 +192,7 @@ void TL_InitTimelineGbl (struct TL_Timeline *Timeline)
|
|||
void TL_ResetTimeline (struct TL_Timeline *Timeline)
|
||||
{
|
||||
Timeline->UsrOrGbl = TL_TIMELINE_GBL;
|
||||
Timeline->Who = TL_DEFAULT_WHO;
|
||||
Timeline->Who = TL_Who_DEFAULT_WHO;
|
||||
Timeline->WhatToGet = TL_GET_RECENT_TIMELINE;
|
||||
Timeline->Pubs.Top =
|
||||
Timeline->Pubs.Bottom = NULL,
|
||||
|
@ -461,7 +451,7 @@ static void TL_ShowTimeline (struct TL_Timeline *Timeline,
|
|||
|
||||
/***** Form to write a new post *****/
|
||||
if (GlobalTimeline || ItsMe)
|
||||
TL_PutFormToWriteNewPost (Timeline);
|
||||
TL_Pst_PutFormToWriteNewPost (Timeline);
|
||||
|
||||
/***** New publications refreshed dynamically via AJAX *****/
|
||||
if (GlobalTimeline)
|
||||
|
@ -612,243 +602,6 @@ void TL_WriteDateTime (time_t TimeUTC)
|
|||
true,true,false,0x6);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************** Get from database and write public post *******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void TL_GetAndWritePost (long PstCod)
|
||||
{
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
unsigned long NumRows;
|
||||
struct TL_PostContent Content;
|
||||
|
||||
/***** Initialize image *****/
|
||||
Med_MediaConstructor (&Content.Media);
|
||||
|
||||
/***** Get post from database *****/
|
||||
NumRows = DB_QuerySELECT (&mysql_res,"can not get the content"
|
||||
" of a post",
|
||||
"SELECT Txt," // row[0]
|
||||
"MedCod" // row[1]
|
||||
" FROM tl_posts"
|
||||
" WHERE PstCod=%ld",
|
||||
PstCod);
|
||||
|
||||
/***** Result should have a unique row *****/
|
||||
if (NumRows == 1)
|
||||
{
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
/****** Get content (row[0]) *****/
|
||||
Str_Copy (Content.Txt,row[0],
|
||||
Cns_MAX_BYTES_LONG_TEXT);
|
||||
|
||||
/***** Get media (row[1]) *****/
|
||||
Content.Media.MedCod = Str_ConvertStrCodToLongCod (row[1]);
|
||||
Med_GetMediaDataByCod (&Content.Media);
|
||||
}
|
||||
else
|
||||
Content.Txt[0] = '\0';
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
||||
/***** Write content *****/
|
||||
if (Content.Txt[0])
|
||||
{
|
||||
HTM_DIV_Begin ("class=\"TL_TXT\"");
|
||||
Msg_WriteMsgContent (Content.Txt,Cns_MAX_BYTES_LONG_TEXT,true,false);
|
||||
HTM_DIV_End ();
|
||||
}
|
||||
|
||||
/***** Show image *****/
|
||||
Med_ShowMedia (&Content.Media,"TL_PST_MED_CONT TL_RIGHT_WIDTH",
|
||||
"TL_PST_MED TL_RIGHT_WIDTH");
|
||||
|
||||
/***** Free image *****/
|
||||
Med_MediaDestructor (&Content.Media);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************** Form to write a new publication **********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TL_PutFormToWriteNewPost (struct TL_Timeline *Timeline)
|
||||
{
|
||||
extern const char *Txt_New_TIMELINE_post;
|
||||
bool ShowPhoto;
|
||||
char PhotoURL[PATH_MAX + 1];
|
||||
|
||||
/***** Start list *****/
|
||||
HTM_UL_Begin ("class=\"TL_LIST\"");
|
||||
HTM_LI_Begin ("class=\"TL_WIDTH\"");
|
||||
|
||||
/***** Left: write author's photo (my photo) *****/
|
||||
HTM_DIV_Begin ("class=\"TL_LEFT_PHOTO\"");
|
||||
ShowPhoto = Pho_ShowingUsrPhotoIsAllowed (&Gbl.Usrs.Me.UsrDat,PhotoURL);
|
||||
Pho_ShowUsrPhoto (&Gbl.Usrs.Me.UsrDat,ShowPhoto ? PhotoURL :
|
||||
NULL,
|
||||
"PHOTO45x60",Pho_ZOOM,false);
|
||||
HTM_DIV_End ();
|
||||
|
||||
/***** Right: author's name, time, textarea *****/
|
||||
HTM_DIV_Begin ("class=\"TL_RIGHT_CONT TL_RIGHT_WIDTH\"");
|
||||
|
||||
/* Author name */
|
||||
TL_Not_WriteAuthorNote (&Gbl.Usrs.Me.UsrDat);
|
||||
|
||||
/* Form to write the post */
|
||||
HTM_DIV_Begin ("class=\"TL_FORM_NEW_PST TL_RIGHT_WIDTH\"");
|
||||
TL_FormStart (Timeline,ActRcvTL_PstGbl,ActRcvTL_PstUsr);
|
||||
TL_PutTextarea (Txt_New_TIMELINE_post,"TL_PST_TEXTAREA TL_RIGHT_WIDTH");
|
||||
Frm_EndForm ();
|
||||
HTM_DIV_End ();
|
||||
|
||||
HTM_DIV_End ();
|
||||
|
||||
/***** End list *****/
|
||||
HTM_LI_End ();
|
||||
HTM_UL_End ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*** Put textarea and button inside a form to submit a new post or comment ***/
|
||||
/*****************************************************************************/
|
||||
|
||||
void TL_PutTextarea (const char *Placeholder,const char *ClassTextArea)
|
||||
{
|
||||
extern const char *Txt_Post;
|
||||
char IdDivImgButton[Frm_MAX_BYTES_ID + 1];
|
||||
|
||||
/***** Set unique id for the hidden div *****/
|
||||
Frm_SetUniqueId (IdDivImgButton);
|
||||
|
||||
/***** Textarea to write the content *****/
|
||||
HTM_TEXTAREA_Begin ("name=\"Txt\" rows=\"1\" maxlength=\"%u\""
|
||||
" placeholder=\"%s…\" class=\"%s\""
|
||||
" onfocus=\"expandTextarea(this,'%s','6');\"",
|
||||
TL_MAX_CHARS_IN_POST,
|
||||
Placeholder,ClassTextArea,
|
||||
IdDivImgButton);
|
||||
HTM_TEXTAREA_End ();
|
||||
|
||||
/***** Start concealable div *****/
|
||||
HTM_DIV_Begin ("id=\"%s\" style=\"display:none;\"",IdDivImgButton);
|
||||
|
||||
/***** Help on editor *****/
|
||||
Lay_HelpPlainEditor ();
|
||||
|
||||
/***** Attached image (optional) *****/
|
||||
Med_PutMediaUploader (-1,"TL_MED_INPUT_WIDTH");
|
||||
|
||||
/***** Submit button *****/
|
||||
HTM_BUTTON_SUBMIT_Begin (NULL,"BT_SUBMIT_INLINE BT_CREATE",NULL);
|
||||
HTM_Txt (Txt_Post);
|
||||
HTM_BUTTON_End ();
|
||||
|
||||
/***** End hidden div *****/
|
||||
HTM_DIV_End ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************* Receive and store a new public post *********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void TL_ReceivePostUsr (void)
|
||||
{
|
||||
struct TL_Timeline Timeline;
|
||||
long NotCod;
|
||||
|
||||
/***** Reset timeline context *****/
|
||||
TL_ResetTimeline (&Timeline);
|
||||
|
||||
/***** Get user whom profile is displayed *****/
|
||||
Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ();
|
||||
|
||||
/***** Show user's profile *****/
|
||||
Prf_ShowUserProfile (&Gbl.Usrs.Other.UsrDat);
|
||||
|
||||
/***** Start section *****/
|
||||
HTM_SECTION_Begin (TL_TIMELINE_SECTION_ID);
|
||||
|
||||
/***** Receive and store post, and
|
||||
write updated timeline after publication (user) *****/
|
||||
NotCod = TL_ReceivePost ();
|
||||
TL_ShowTimelineUsrHighlightingNot (&Timeline,NotCod);
|
||||
|
||||
/***** End section *****/
|
||||
HTM_SECTION_End ();
|
||||
}
|
||||
|
||||
void TL_ReceivePostGbl (void)
|
||||
{
|
||||
struct TL_Timeline Timeline;
|
||||
long NotCod;
|
||||
|
||||
/***** Initialize timeline *****/
|
||||
TL_InitTimelineGbl (&Timeline);
|
||||
|
||||
/***** Receive and store post *****/
|
||||
NotCod = TL_ReceivePost ();
|
||||
|
||||
/***** Write updated timeline after publication (global) *****/
|
||||
TL_ShowTimelineGblHighlightingNot (&Timeline,NotCod);
|
||||
}
|
||||
|
||||
// Returns the code of the note just created
|
||||
static long TL_ReceivePost (void)
|
||||
{
|
||||
struct TL_PostContent Content;
|
||||
long PstCod;
|
||||
struct TL_Pub_Publication Pub;
|
||||
|
||||
/***** Get the content of the new post *****/
|
||||
Par_GetParAndChangeFormat ("Txt",Content.Txt,Cns_MAX_BYTES_LONG_TEXT,
|
||||
Str_TO_RIGOROUS_HTML,true);
|
||||
|
||||
/***** Initialize image *****/
|
||||
Med_MediaConstructor (&Content.Media);
|
||||
|
||||
/***** Get attached image (action, file and title) *****/
|
||||
Content.Media.Width = TL_IMAGE_SAVED_MAX_WIDTH;
|
||||
Content.Media.Height = TL_IMAGE_SAVED_MAX_HEIGHT;
|
||||
Content.Media.Quality = TL_IMAGE_SAVED_QUALITY;
|
||||
Med_GetMediaFromForm (-1L,-1L,-1,&Content.Media,NULL,NULL);
|
||||
Ale_ShowAlerts (NULL);
|
||||
|
||||
if (Content.Txt[0] || // Text not empty
|
||||
Content.Media.Status == Med_PROCESSED) // A media is attached
|
||||
{
|
||||
/***** Store media in filesystem and database *****/
|
||||
Med_RemoveKeepOrStoreMedia (-1L,&Content.Media);
|
||||
|
||||
/***** Publish *****/
|
||||
/* Insert post content in the database */
|
||||
PstCod =
|
||||
DB_QueryINSERTandReturnCode ("can not create post",
|
||||
"INSERT INTO tl_posts"
|
||||
" (Txt,MedCod)"
|
||||
" VALUES"
|
||||
" ('%s',%ld)",
|
||||
Content.Txt,
|
||||
Content.Media.MedCod);
|
||||
|
||||
/* Insert post in notes */
|
||||
TL_Not_StoreAndPublishNoteInternal (TL_NOTE_POST,PstCod,&Pub);
|
||||
|
||||
/***** Analyze content and store notifications about mentions *****/
|
||||
Str_AnalyzeTxtAndStoreNotifyEventToMentionedUsrs (Pub.PubCod,Content.Txt);
|
||||
}
|
||||
else // Text and image are empty
|
||||
Pub.NotCod = -1L;
|
||||
|
||||
/***** Free image *****/
|
||||
Med_MediaDestructor (&Content.Media);
|
||||
|
||||
return Pub.NotCod;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************* Remove all the content of a user from database ****************/
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -107,12 +107,6 @@ typedef enum
|
|||
TL_SHOW_ALL_USRS, // Show all favers/sharers
|
||||
} TL_HowManyUsrs_t;
|
||||
|
||||
struct TL_PostContent
|
||||
{
|
||||
char Txt[Cns_MAX_BYTES_LONG_TEXT + 1];
|
||||
struct Med_Media Media;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TL_DONT_HIGHLIGHT,
|
||||
|
@ -157,13 +151,6 @@ void TL_WriteTopMessage (TL_TopMessage_t TopMessage,long PublisherCod);
|
|||
|
||||
void TL_WriteDateTime (time_t TimeUTC);
|
||||
|
||||
void TL_GetAndWritePost (long PstCod);
|
||||
|
||||
void TL_PutTextarea (const char *Placeholder,const char *ClassTextArea);
|
||||
|
||||
void TL_ReceivePostUsr (void);
|
||||
void TL_ReceivePostGbl (void);
|
||||
|
||||
void TL_RemoveUsrContent (long UsrCod);
|
||||
|
||||
void TL_ShowNumSharersOrFavers (unsigned NumUsrs);
|
||||
|
|
|
@ -164,7 +164,7 @@ void TL_Com_PutHiddenFormToWriteNewComment (const struct TL_Timeline *Timeline,
|
|||
TL_Not_PutHiddenParamNotCod (NotCod);
|
||||
|
||||
/* Textarea and button */
|
||||
TL_PutTextarea (Txt_New_TIMELINE_comment,
|
||||
TL_Pst_PutTextarea (Txt_New_TIMELINE_comment,
|
||||
"TL_COM_TEXTAREA TL_COMM_WIDTH");
|
||||
|
||||
/* End form */
|
||||
|
@ -753,7 +753,7 @@ void TL_Com_ReceiveCommentGbl (void)
|
|||
static long TL_Com_ReceiveComment (void)
|
||||
{
|
||||
extern const char *Txt_The_original_post_no_longer_exists;
|
||||
struct TL_PostContent Content;
|
||||
struct TL_Pst_PostContent Content;
|
||||
struct TL_Not_Note Not;
|
||||
struct TL_Pub_Publication Pub;
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
/*****************************************************************************/
|
||||
|
||||
#include "swad_timeline_note.h"
|
||||
#include "swad_timeline_post.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************************** Public constants *****************************/
|
||||
|
@ -44,7 +45,7 @@ struct TL_Com_Comment
|
|||
long NotCod; // Note code to which this comment belongs
|
||||
time_t DateTimeUTC; // Date-time of publication in UTC time
|
||||
unsigned NumFavs; // Number of times (users) this comment has been favourited
|
||||
struct TL_PostContent Content;
|
||||
struct TL_Pst_PostContent Content;
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -262,7 +262,7 @@ void TL_Not_WriteNote (struct TL_Timeline *Timeline,
|
|||
/* Write content of the note */
|
||||
if (Not->NoteType == TL_NOTE_POST)
|
||||
/* Write post content */
|
||||
TL_GetAndWritePost (Not->Cod);
|
||||
TL_Pst_GetAndWritePost (Not->Cod);
|
||||
else
|
||||
{
|
||||
/* Reset forums */
|
||||
|
|
|
@ -0,0 +1,300 @@
|
|||
// swad_timeline_post.c: social timeline posts
|
||||
|
||||
/*
|
||||
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-2021 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
/*********************************** Headers *********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#include "swad_database.h"
|
||||
#include "swad_global.h"
|
||||
#include "swad_info.h"
|
||||
#include "swad_media.h"
|
||||
#include "swad_message.h"
|
||||
#include "swad_profile.h"
|
||||
#include "swad_timeline.h"
|
||||
#include "swad_timeline_note.h"
|
||||
#include "swad_timeline_post.h"
|
||||
#include "swad_timeline_publication.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************************** Public constants *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************* Private constants and types ***********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define TL_Pst_MAX_CHARS_IN_POST 1000 // Maximum number of characters in a post
|
||||
|
||||
/*****************************************************************************/
|
||||
/************** External global variables from others modules ****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
extern struct Globals Gbl;
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************* Private global variables **************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Private prototypes ****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static long TL_Pst_ReceivePost (void);
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************** Get from database and write public post *******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void TL_Pst_GetAndWritePost (long PstCod)
|
||||
{
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
unsigned long NumRows;
|
||||
struct TL_Pst_PostContent Content;
|
||||
|
||||
/***** Initialize image *****/
|
||||
Med_MediaConstructor (&Content.Media);
|
||||
|
||||
/***** Get post from database *****/
|
||||
NumRows = DB_QuerySELECT (&mysql_res,"can not get the content"
|
||||
" of a post",
|
||||
"SELECT Txt," // row[0]
|
||||
"MedCod" // row[1]
|
||||
" FROM tl_posts"
|
||||
" WHERE PstCod=%ld",
|
||||
PstCod);
|
||||
|
||||
/***** Result should have a unique row *****/
|
||||
if (NumRows == 1)
|
||||
{
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
/****** Get content (row[0]) *****/
|
||||
Str_Copy (Content.Txt,row[0],
|
||||
Cns_MAX_BYTES_LONG_TEXT);
|
||||
|
||||
/***** Get media (row[1]) *****/
|
||||
Content.Media.MedCod = Str_ConvertStrCodToLongCod (row[1]);
|
||||
Med_GetMediaDataByCod (&Content.Media);
|
||||
}
|
||||
else
|
||||
Content.Txt[0] = '\0';
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
||||
/***** Write content *****/
|
||||
if (Content.Txt[0])
|
||||
{
|
||||
HTM_DIV_Begin ("class=\"TL_TXT\"");
|
||||
Msg_WriteMsgContent (Content.Txt,Cns_MAX_BYTES_LONG_TEXT,true,false);
|
||||
HTM_DIV_End ();
|
||||
}
|
||||
|
||||
/***** Show image *****/
|
||||
Med_ShowMedia (&Content.Media,"TL_PST_MED_CONT TL_RIGHT_WIDTH",
|
||||
"TL_PST_MED TL_RIGHT_WIDTH");
|
||||
|
||||
/***** Free image *****/
|
||||
Med_MediaDestructor (&Content.Media);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************** Form to write a new publication **********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void TL_Pst_PutFormToWriteNewPost (struct TL_Timeline *Timeline)
|
||||
{
|
||||
extern const char *Txt_New_TIMELINE_post;
|
||||
bool ShowPhoto;
|
||||
char PhotoURL[PATH_MAX + 1];
|
||||
|
||||
/***** Start list *****/
|
||||
HTM_UL_Begin ("class=\"TL_LIST\"");
|
||||
HTM_LI_Begin ("class=\"TL_WIDTH\"");
|
||||
|
||||
/***** Left: write author's photo (my photo) *****/
|
||||
HTM_DIV_Begin ("class=\"TL_LEFT_PHOTO\"");
|
||||
ShowPhoto = Pho_ShowingUsrPhotoIsAllowed (&Gbl.Usrs.Me.UsrDat,PhotoURL);
|
||||
Pho_ShowUsrPhoto (&Gbl.Usrs.Me.UsrDat,ShowPhoto ? PhotoURL :
|
||||
NULL,
|
||||
"PHOTO45x60",Pho_ZOOM,false);
|
||||
HTM_DIV_End ();
|
||||
|
||||
/***** Right: author's name, time, textarea *****/
|
||||
HTM_DIV_Begin ("class=\"TL_RIGHT_CONT TL_RIGHT_WIDTH\"");
|
||||
|
||||
/* Author name */
|
||||
TL_Not_WriteAuthorNote (&Gbl.Usrs.Me.UsrDat);
|
||||
|
||||
/* Form to write the post */
|
||||
HTM_DIV_Begin ("class=\"TL_FORM_NEW_PST TL_RIGHT_WIDTH\"");
|
||||
TL_FormStart (Timeline,ActRcvTL_PstGbl,ActRcvTL_PstUsr);
|
||||
TL_Pst_PutTextarea (Txt_New_TIMELINE_post,"TL_PST_TEXTAREA TL_RIGHT_WIDTH");
|
||||
Frm_EndForm ();
|
||||
HTM_DIV_End ();
|
||||
|
||||
HTM_DIV_End ();
|
||||
|
||||
/***** End list *****/
|
||||
HTM_LI_End ();
|
||||
HTM_UL_End ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*** Put textarea and button inside a form to submit a new post or comment ***/
|
||||
/*****************************************************************************/
|
||||
|
||||
void TL_Pst_PutTextarea (const char *Placeholder,const char *ClassTextArea)
|
||||
{
|
||||
extern const char *Txt_Post;
|
||||
char IdDivImgButton[Frm_MAX_BYTES_ID + 1];
|
||||
|
||||
/***** Set unique id for the hidden div *****/
|
||||
Frm_SetUniqueId (IdDivImgButton);
|
||||
|
||||
/***** Textarea to write the content *****/
|
||||
HTM_TEXTAREA_Begin ("name=\"Txt\" rows=\"1\" maxlength=\"%u\""
|
||||
" placeholder=\"%s…\" class=\"%s\""
|
||||
" onfocus=\"expandTextarea(this,'%s','6');\"",
|
||||
TL_Pst_MAX_CHARS_IN_POST,
|
||||
Placeholder,ClassTextArea,
|
||||
IdDivImgButton);
|
||||
HTM_TEXTAREA_End ();
|
||||
|
||||
/***** Start concealable div *****/
|
||||
HTM_DIV_Begin ("id=\"%s\" style=\"display:none;\"",IdDivImgButton);
|
||||
|
||||
/***** Help on editor *****/
|
||||
Lay_HelpPlainEditor ();
|
||||
|
||||
/***** Attached image (optional) *****/
|
||||
Med_PutMediaUploader (-1,"TL_MED_INPUT_WIDTH");
|
||||
|
||||
/***** Submit button *****/
|
||||
HTM_BUTTON_SUBMIT_Begin (NULL,"BT_SUBMIT_INLINE BT_CREATE",NULL);
|
||||
HTM_Txt (Txt_Post);
|
||||
HTM_BUTTON_End ();
|
||||
|
||||
/***** End hidden div *****/
|
||||
HTM_DIV_End ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************* Receive and store a new public post *********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void TL_Pst_ReceivePostUsr (void)
|
||||
{
|
||||
struct TL_Timeline Timeline;
|
||||
long NotCod;
|
||||
|
||||
/***** Reset timeline context *****/
|
||||
TL_ResetTimeline (&Timeline);
|
||||
|
||||
/***** Get user whom profile is displayed *****/
|
||||
Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ();
|
||||
|
||||
/***** Show user's profile *****/
|
||||
Prf_ShowUserProfile (&Gbl.Usrs.Other.UsrDat);
|
||||
|
||||
/***** Start section *****/
|
||||
HTM_SECTION_Begin (TL_TIMELINE_SECTION_ID);
|
||||
|
||||
/***** Receive and store post, and
|
||||
write updated timeline after publication (user) *****/
|
||||
NotCod = TL_Pst_ReceivePost ();
|
||||
TL_ShowTimelineUsrHighlightingNot (&Timeline,NotCod);
|
||||
|
||||
/***** End section *****/
|
||||
HTM_SECTION_End ();
|
||||
}
|
||||
|
||||
void TL_Pst_ReceivePostGbl (void)
|
||||
{
|
||||
struct TL_Timeline Timeline;
|
||||
long NotCod;
|
||||
|
||||
/***** Initialize timeline *****/
|
||||
TL_InitTimelineGbl (&Timeline);
|
||||
|
||||
/***** Receive and store post *****/
|
||||
NotCod = TL_Pst_ReceivePost ();
|
||||
|
||||
/***** Write updated timeline after publication (global) *****/
|
||||
TL_ShowTimelineGblHighlightingNot (&Timeline,NotCod);
|
||||
}
|
||||
|
||||
// Returns the code of the note just created
|
||||
static long TL_Pst_ReceivePost (void)
|
||||
{
|
||||
struct TL_Pst_PostContent Content;
|
||||
long PstCod;
|
||||
struct TL_Pub_Publication Pub;
|
||||
|
||||
/***** Get the content of the new post *****/
|
||||
Par_GetParAndChangeFormat ("Txt",Content.Txt,Cns_MAX_BYTES_LONG_TEXT,
|
||||
Str_TO_RIGOROUS_HTML,true);
|
||||
|
||||
/***** Initialize image *****/
|
||||
Med_MediaConstructor (&Content.Media);
|
||||
|
||||
/***** Get attached image (action, file and title) *****/
|
||||
Content.Media.Width = TL_IMAGE_SAVED_MAX_WIDTH;
|
||||
Content.Media.Height = TL_IMAGE_SAVED_MAX_HEIGHT;
|
||||
Content.Media.Quality = TL_IMAGE_SAVED_QUALITY;
|
||||
Med_GetMediaFromForm (-1L,-1L,-1,&Content.Media,NULL,NULL);
|
||||
Ale_ShowAlerts (NULL);
|
||||
|
||||
if (Content.Txt[0] || // Text not empty
|
||||
Content.Media.Status == Med_PROCESSED) // A media is attached
|
||||
{
|
||||
/***** Store media in filesystem and database *****/
|
||||
Med_RemoveKeepOrStoreMedia (-1L,&Content.Media);
|
||||
|
||||
/***** Publish *****/
|
||||
/* Insert post content in the database */
|
||||
PstCod =
|
||||
DB_QueryINSERTandReturnCode ("can not create post",
|
||||
"INSERT INTO tl_posts"
|
||||
" (Txt,MedCod)"
|
||||
" VALUES"
|
||||
" ('%s',%ld)",
|
||||
Content.Txt,
|
||||
Content.Media.MedCod);
|
||||
|
||||
/* Insert post in notes */
|
||||
TL_Not_StoreAndPublishNoteInternal (TL_NOTE_POST,PstCod,&Pub);
|
||||
|
||||
/***** Analyze content and store notifications about mentions *****/
|
||||
Str_AnalyzeTxtAndStoreNotifyEventToMentionedUsrs (Pub.PubCod,Content.Txt);
|
||||
}
|
||||
else // Text and image are empty
|
||||
Pub.NotCod = -1L;
|
||||
|
||||
/***** Free image *****/
|
||||
Med_MediaDestructor (&Content.Media);
|
||||
|
||||
return Pub.NotCod;
|
||||
}
|
|
@ -820,7 +820,7 @@ void TL_Pub_GetNotifPublication (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1],
|
|||
MYSQL_ROW row;
|
||||
struct TL_Pub_Publication Pub;
|
||||
struct TL_Not_Note Not;
|
||||
struct TL_PostContent Content;
|
||||
struct TL_Pst_PostContent Content;
|
||||
size_t Length;
|
||||
bool ContentCopied = false;
|
||||
|
||||
|
|
|
@ -53,8 +53,6 @@ extern struct Globals Gbl;
|
|||
|
||||
Usr_Who_t TL_GlobalWho;
|
||||
|
||||
#define TL_DEFAULT_WHO Usr_WHO_FOLLOWED
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Private prototypes ****************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -118,7 +116,7 @@ void TL_Who_GetParamWho (void)
|
|||
|
||||
/***** If parameter Who is unknown, set it to default *****/
|
||||
if (Who == Usr_WHO_UNKNOWN)
|
||||
Who = TL_DEFAULT_WHO;
|
||||
Who = TL_Who_DEFAULT_WHO;
|
||||
|
||||
/***** Set global variable *****/
|
||||
TL_Who_SetGlobalWho (Who);
|
||||
|
@ -164,7 +162,7 @@ void TL_Who_SaveWhoInDB (struct TL_Timeline *Timeline)
|
|||
if (Gbl.Usrs.Me.Logged)
|
||||
{
|
||||
if (Timeline->Who == Usr_WHO_UNKNOWN)
|
||||
Timeline->Who = TL_DEFAULT_WHO;
|
||||
Timeline->Who = TL_Who_DEFAULT_WHO;
|
||||
|
||||
/***** Update which users in database *****/
|
||||
// Who is stored in usr_last for next time I log in
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
/****************************** Public constants *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define TL_Who_DEFAULT_WHO Usr_WHO_FOLLOWED
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************** Public types *******************************/
|
||||
/*****************************************************************************/
|
||||
|
|
Loading…
Reference in New Issue