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:
parent
c7d058fe90
commit
905a51d294
2
data.sql
2
data.sql
|
@ -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`(
|
||||
|
|
11
mysql.go
11
mysql.go
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -226,7 +226,7 @@ $(document).ready(function(){
|
|||
}
|
||||
});
|
||||
|
||||
$('body').click(function() {
|
||||
$(this).click(function() {
|
||||
$(".selectedAlert").removeClass("selectedAlert");
|
||||
});
|
||||
|
||||
|
|
77
routes.go
77
routes.go
|
@ -639,7 +639,13 @@ func route_create_topic(w http.ResponseWriter, r *http.Request) {
|
|||
forums[fid].LastReplyerID = user.ID
|
||||
forums[fid].LastTopicTime = ""
|
||||
|
||||
http.Redirect(w, r, "/topic/" + strconv.FormatInt(lastId,10), http.StatusSeeOther)
|
||||
_, 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 {
|
||||
InternalError(err,w,r)
|
||||
|
@ -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,7 +711,24 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
http.Redirect(w,r, "/topic/" + strconv.Itoa(tid), http.StatusSeeOther)
|
||||
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 {
|
||||
InternalError(err,w,r)
|
||||
|
@ -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,23 +1853,25 @@ func route_api(w http.ResponseWriter, r *http.Request) {
|
|||
LocalErrorJS("Invalid elementType",w,r)
|
||||
}
|
||||
|
||||
if event == "like" {
|
||||
if elementType == "user" {
|
||||
act = "likes"
|
||||
end_frag = ""
|
||||
if targetUser.ID == user.ID {
|
||||
area = "you"
|
||||
switch(event) {
|
||||
case "like":
|
||||
if elementType == "user" {
|
||||
act = "likes"
|
||||
end_frag = ""
|
||||
if targetUser.ID == user.ID {
|
||||
area = "you"
|
||||
}
|
||||
} else {
|
||||
act = "liked"
|
||||
}
|
||||
} else {
|
||||
act = "liked"
|
||||
}
|
||||
} else if event == "mention" {
|
||||
if elementType == "user" {
|
||||
act = "mentioned you on"
|
||||
} else {
|
||||
act = "mentioned you in"
|
||||
post_act = ""
|
||||
}
|
||||
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 + `"},`
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
@ -547,7 +553,8 @@ button.username
|
|||
ul { height: 24px; }
|
||||
.menu_left { padding-right: 5px; }
|
||||
.menu_right { padding-right: 5px; }
|
||||
.menu_create_topic { display: none;}
|
||||
.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; }
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -231,7 +232,7 @@ li a
|
|||
background-color: white;
|
||||
}
|
||||
|
||||
/*Clearfix*/
|
||||
/* Clearfix */
|
||||
.formrow:before, .formrow:after {
|
||||
content: " ";
|
||||
display: table;
|
||||
|
@ -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,8 +421,9 @@ 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; }
|
||||
.prev_button, .next_button { top: auto; bottom: 5px; }
|
||||
}
|
||||
|
||||
@media (max-width: 470px) {
|
||||
|
|
Loading…
Reference in New Issue