You now get an alert when someone replies to one of your topics.

Greatly improved the Alert CSS for every theme.
Fixed a bug where alerts aren't closed when the page is extremely short and you click outside it's bounds.
Fixed a bug where liking a topic didn't reload the cached data.
Fixed a few misnamed HTML tags.
This commit is contained in:
Azareal 2017-03-05 07:53:41 +00:00
parent c7d058fe90
commit 905a51d294
11 changed files with 118 additions and 59 deletions

View File

@ -138,7 +138,7 @@ CREATE TABLE `activity_subscriptions`(
`user` int not null,
`targetID` int not null, /* the ID of the element being acted upon */
`targetType` varchar(50) not null, /* topic, post (calling it post here to differentiate it from the 'reply' event), forum, user */
`level` tinyint DEFAULT 0 not null /* 0: Mentions (aka the global default for any post), 1: Replies, 2: Everyone*/
`level` tinyint DEFAULT 0 not null /* 0: Mentions (aka the global default for any post), 1: Replies To You, 2: All Replies*/
);
CREATE TABLE `settings`(

View File

@ -36,6 +36,7 @@ var add_likes_to_reply_stmt *sql.Stmt
var add_activity_stmt *sql.Stmt
var notify_watchers_stmt *sql.Stmt
var notify_one_stmt *sql.Stmt
var add_subscription_stmt *sql.Stmt
var edit_topic_stmt *sql.Stmt
var edit_reply_stmt *sql.Stmt
var delete_reply_stmt *sql.Stmt
@ -248,7 +249,7 @@ func init_database(err error) {
}
log.Print("Preparing notify_watchers statement.")
notify_watchers_stmt, err = db.Prepare("INSERT INTO activity_stream_matches(watcher, asid) SELECT activity_subscriptions.user, ? AS asid FROM activity_subscriptions LEFT JOIN activity_stream ON activity_subscriptions.targetType=activity_stream.elementType and activity_subscriptions.targetID=activity_stream.elementID")
notify_watchers_stmt, err = db.Prepare("INSERT INTO activity_stream_matches(watcher, asid) SELECT activity_subscriptions.user, activity_stream.asid FROM activity_stream INNER JOIN activity_subscriptions ON activity_subscriptions.targetType = activity_stream.elementType and activity_subscriptions.targetID = activity_stream.elementID and activity_subscriptions.user != activity_stream.actor where asid = ?")
if err != nil {
log.Fatal(err)
}
@ -259,6 +260,12 @@ func init_database(err error) {
log.Fatal(err)
}
log.Print("Preparing add_subscription statement.")
add_subscription_stmt, err = db.Prepare("INSERT INTO activity_subscriptions(user,targetID,targetType,level) VALUES(?,?,?,2)")
if err != nil {
log.Fatal(err)
}
log.Print("Preparing edit_topic statement.")
edit_topic_stmt, err = db.Prepare("UPDATE topics SET title = ?, content = ?, parsed_content = ?, is_closed = ? WHERE tid = ?")
if err != nil {
@ -296,7 +303,7 @@ func init_database(err error) {
}
log.Print("Preparing get_activity_feed_by_watcher statement.")
get_activity_feed_by_watcher_stmt, err = db.Prepare("SELECT activity_stream_matches.asid, activity_stream.actor, activity_stream.targetUser, activity_stream.event, activity_stream.elementType, activity_stream.elementID FROM `activity_stream_matches` LEFT JOIN `activity_stream` ON activity_stream_matches.asid = activity_stream.asid WHERE `watcher` = ?")
get_activity_feed_by_watcher_stmt, err = db.Prepare("SELECT activity_stream_matches.asid, activity_stream.actor, activity_stream.targetUser, activity_stream.event, activity_stream.elementType, activity_stream.elementID FROM `activity_stream_matches` INNER JOIN `activity_stream` ON activity_stream_matches.asid = activity_stream.asid AND activity_stream_matches.watcher != activity_stream.actor WHERE `watcher` = ?")
if err != nil {
log.Fatal(err)
}

View File

@ -226,7 +226,7 @@ $(document).ready(function(){
}
});
$('body').click(function() {
$(this).click(function() {
$(".selectedAlert").removeClass("selectedAlert");
});

View File

@ -639,6 +639,12 @@ func route_create_topic(w http.ResponseWriter, r *http.Request) {
forums[fid].LastReplyerID = user.ID
forums[fid].LastTopicTime = ""
_, err = add_subscription_stmt.Exec(user.ID,lastId,"topic")
if err != nil {
InternalError(err,w,r)
return
}
http.Redirect(w,r,"/topic/" + strconv.FormatInt(lastId,10), http.StatusSeeOther)
err = increase_post_user_stats(wcount,user.ID,true,user)
if err != nil {
@ -661,7 +667,8 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
var topic_name string
var fid int
err = db.QueryRow("select title, parentID from topics where tid = ?",tid).Scan(&topic_name,&fid)
var createdBy int
err = db.QueryRow("select title, parentID, createdBy from topics where tid = ?",tid).Scan(&topic_name,&fid,&createdBy)
if err == sql.ErrNoRows {
PreError("Couldn't find the parent topic",w,r)
return
@ -704,6 +711,23 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
return
}
res, err := add_activity_stmt.Exec(user.ID,createdBy,"reply","topic",tid)
if err != nil {
InternalError(err,w,r)
return
}
lastId, err := res.LastInsertId()
if err != nil {
InternalError(err,w,r)
return
}
_, err = notify_watchers_stmt.Exec(lastId)
if err != nil {
InternalError(err,w,r)
return
}
http.Redirect(w,r,"/topic/" + strconv.Itoa(tid), http.StatusSeeOther)
err = increase_post_user_stats(wcount, user.ID, false, user)
if err != nil {
@ -800,6 +824,16 @@ func route_like_topic(w http.ResponseWriter, r *http.Request) {
return
}
// Reload the topic...
err = topics.Load(tid)
if err != nil && err != sql.ErrNoRows {
LocalError("The liked topic no longer exists",w,r,user)
return
} else if err != nil {
InternalError(err,w,r)
return
}
http.Redirect(w,r,"/topic/" + strconv.Itoa(tid),http.StatusSeeOther)
}
@ -1756,6 +1790,8 @@ func route_api(w http.ResponseWriter, r *http.Request) {
"{x}{liked}{your post on}{user}{'s profile}" todo
"{x}{liked}{your post in}{topic}"
"{x}{replied to}{your post in}{topic}" todo
"{x}{replied to}{topic}"
"{x}{replied to}{your topic}{topic}"
"{x}{created a new topic}{topic}"
*/
@ -1789,6 +1825,7 @@ func route_api(w http.ResponseWriter, r *http.Request) {
}
url = build_topic_url(elementID)
area = topic.Title
if targetUser_id == user.ID {
post_act = " your topic"
}
@ -1816,7 +1853,8 @@ func route_api(w http.ResponseWriter, r *http.Request) {
LocalErrorJS("Invalid elementType",w,r)
}
if event == "like" {
switch(event) {
case "like":
if elementType == "user" {
act = "likes"
end_frag = ""
@ -1826,13 +1864,14 @@ func route_api(w http.ResponseWriter, r *http.Request) {
} else {
act = "liked"
}
} else if event == "mention" {
case "mention":
if elementType == "user" {
act = "mentioned you on"
} else {
act = "mentioned you in"
post_act = ""
}
case "reply": act = "replied to"
}
msglist += `{"msg":"{0} ` + start_frag + act + post_act + ` {1}` + end_frag + `","sub":["` + actor.Name + `","` + area + `"],"path":"` + url + `","avatar":"` + actor.Avatar + `"},`

View File

@ -15,7 +15,7 @@
<div class="formitem"><input name="account-avatar" type="file" /></div>
</div>
<div class="formrow">
<div class="formitem"><button name="account-button" class="formbutton">Update</div></div>
<div class="formitem"><button name="account-button" class="formbutton">Update</button></div>
</div>
</form>
</div>

View File

@ -14,7 +14,7 @@
<div class="formitem"><input name="account-new-username" type="text" /></div>
</div>
<div class="formrow">
<div class="formitem"><button name="account-button" class="formbutton">Update</div></div>
<div class="formitem"><button name="account-button" class="formbutton">Update</button></div>
</div>
</form>
</div>

View File

@ -18,7 +18,7 @@
<div class="formitem"><input name="account-confirm-password" type="password" placeholder="*****" /></div>
</div>
<div class="formrow">
<div class="formitem"><button name="account-button" class="formbutton">Update</div></div>
<div class="formitem"><button name="account-button" class="formbutton">Update</button></div>
</div>
</form>
</div>

View File

@ -18,7 +18,7 @@
<div class="formitem"><textarea name="topic-content" placeholder="Insert content here"></textarea></div>
</div>
<div class="formrow">
<div class="formitem"><button name="topic-button" class="formbutton">Create Topic</div></div>
<div class="formitem"><button name="topic-button" class="formbutton">Create Topic</button></div>
</div>
</form>
</div>

View File

@ -117,6 +117,10 @@ li:hover
.selectedAlert:hover {
background: white;
color: black;
font-weight: bold;
}
.selectedAlert .alert_counter {
display: none;
}
.menu_alerts .alertList {
display: none;
@ -128,7 +132,7 @@ li:hover
background: white;
font-size: 10px;
line-height: 16px;
width: 135px;
width: 156px;
right: -15px;
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
@ -141,21 +145,25 @@ li:hover
}
.alertItem.withAvatar {
/*background-image: url('/uploads/avatar_1.jpg');*/
background-size: auto 56px;
background-size: 36px;
background-repeat: no-repeat;
text-align: right;
text-align: center;
padding-right: 12px;
padding-left: 42px;
height: 46px;
}
.alertItem.withAvatar:not(:last-child) {
border-bottom: 1px solid rgb(230,230,230);
}
.alertItem.withAvatar .text {
.alertItem .text {
overflow: hidden;
text-overflow: ellipsis;
float: right;
width: calc(100% - 20px);
height: 30px;
width: 100%;
color: black;
}
.alertItem .text.smaller {
font-size: 9px;
}
#footer

View File

@ -89,22 +89,28 @@ li a
.selectedAlert:hover {
background: white;
color: black;
font-weight: bold;
}
.selectedAlert .alert_counter {
display: none;
}
.menu_alerts .alertList {
display: none;
text-transform: none;
}
.selectedAlert .alertList {
position: absolute;
top: 41px;
top: 43px;
display: block;
background: white;
font-size: 10px;
line-height: 16px;
width: 135px;
right: -15px;
width: 156px;
right: calc(5% + 7px);
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
}
.alertItem {
padding: 8px;
@ -113,21 +119,25 @@ li a
}
.alertItem.withAvatar {
/*background-image: url('/uploads/avatar_1.jpg');*/
background-size: auto 56px;
background-size: 36px;
background-repeat: no-repeat;
text-align: right;
text-align: center;
padding-right: 12px;
padding-left: 42px;
height: 46px;
}
.alertItem.withAvatar:not(:last-child) {
border-bottom: 1px solid rgb(230,230,230);
}
.alertItem.withAvatar .text {
.alertItem .text {
overflow: hidden;
text-overflow: ellipsis;
float: right;
width: calc(100% - 20px);
height: 30px;
width: 100%;
color: black;
}
.alertItem .text.smaller {
font-size: 9px;
}
.container
@ -514,17 +524,13 @@ button.username
/* Media Queries from Simple. Probably useless in Conflux */
@media (max-width: 880px) {
li
{
height: 25px;
font-size: 15px;
padding-left: 7px;
}
li { height: 25px; font-size: 15px; padding-left: 7px; }
ul { height: 26px; margin-top: 8px; }
.menu_left { padding-right: 7px; }
.menu_right { padding-right: 7px; }
body { padding-left: 4px; padding-right: 4px; margin: 0px !important; width: 100% !important; height: 100% !important; overflow-x: hidden; }
.container { width: auto; }
.selectedAlert .alertList { top: 33px; right: 4px; }
}
@media (max-width: 810px) {
@ -548,6 +554,7 @@ button.username
.menu_left { padding-right: 5px; }
.menu_right { padding-right: 5px; }
.menu_create_topic { display: none; }
.menu_alerts { padding-left: 4px; padding-right: 4px; }
.hide_on_mobile { display: none; }
.prev_button, .next_button { top: auto;bottom: 5px; }
}

View File

@ -90,19 +90,21 @@ li a
}
.menu_alerts .alertList {
display: none;
text-transform: none;
}
.selectedAlert .alertList {
position: absolute;
top: 41px;
top: 43px;
display: block;
background: white;
font-size: 10px;
line-height: 16px;
width: 135px;
right: -15px;
right: calc(5% + 7px);
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
}
.alertItem {
padding: 8px;
@ -110,7 +112,6 @@ li a
text-overflow: ellipsis;
}
.alertItem.withAvatar {
/*background-image: url('/uploads/avatar_1.jpg');*/
background-size: auto 56px;
background-repeat: no-repeat;
text-align: right;
@ -390,17 +391,13 @@ button.username
.next_button { right: 14px; }
@media (max-width: 880px) {
li
{
height: 25px;
font-size: 15px;
padding-left: 7px;
}
li { height: 25px; font-size: 15px; padding-left: 7px; }
ul { height: 26px; margin-top: 8px; }
.menu_left { padding-right: 7px; }
.menu_right { padding-right: 7px; }
body { padding-left: 4px; padding-right: 4px; margin: 0px !important; width: 100% !important; height: 100% !important; overflow-x: hidden; }
.container { width: auto; }
.selectedAlert .alertList { top: 33px; right: 4px; }
}
@media (max-width: 810px) {
@ -424,6 +421,7 @@ button.username
.menu_left { padding-right: 5px; }
.menu_right { padding-right: 5px; }
.menu_create_topic { display: none;}
.menu_alerts { padding-left: 4px; padding-right: 4px; }
.hide_on_mobile { display: none; }
.prev_button, .next_button { top: auto; bottom: 5px; }
}