Skip to content

Commit e3976c3

Browse files
committed
dfeed.web.web: Add "subscribe" action on user profiles
1 parent c537669 commit e3976c3

4 files changed

Lines changed: 44 additions & 4 deletions

File tree

site-defaults/web/static/css/dfeed.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,6 +1747,11 @@ body.frame .post-gravatar {
17471747
margin-bottom: 0.5em;
17481748
}
17491749

1750+
.user-profile-actions {
1751+
margin-left: 0.35em;
1752+
margin-right: 0.35em;
1753+
}
1754+
17501755
.user-profile-stats {
17511756
margin-bottom: 1em;
17521757
}
606 Bytes
Loading

src/dfeed/web/web/request.d

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ import dfeed.web.web.view.search : discussionSearch;
6161
import dfeed.web.web.view.settings;
6262
import dfeed.web.web.view.subscription : discussionSubscriptionPosts, discussionSubscriptionUnsubscribe;
6363
import dfeed.web.web.view.thread : getPostAtThreadIndex, discussionThread, discussionFirstUnread;
64-
import dfeed.web.web.view.userprofile : discussionUserProfile;
64+
import dfeed.web.web.view.userprofile : discussionUserProfile, lookupAuthorByHash;
6565
import dfeed.web.web.view.widgets;
6666

6767
import ae.net.http.common : HttpRequest, HttpResponse, HttpStatusCode;
@@ -74,7 +74,7 @@ import ae.utils.digest;
7474
import ae.utils.exception;
7575
import ae.utils.json : toJson;
7676
import ae.utils.meta : I;
77-
import ae.utils.regex : re;
77+
import ae.utils.regex : re, escapeRE;
7878
import ae.utils.text.html : encodeHtmlEntities;
7979

8080
HttpRequest currentRequest;
@@ -548,6 +548,32 @@ HttpResponse handleRequest(HttpRequest request, HttpServerConnection conn)
548548
breadcrumbs ~= `<a href="/user/` ~ encodeHtmlEntities(profileHash) ~ `">` ~ encodeHtmlEntities(author) ~ `</a>`;
549549
break;
550550
}
551+
case "subscribe-user":
552+
{
553+
enforce(path.length > 1, _!"No user specified");
554+
enforce(user.isLoggedIn(), _!"Please log in to do that");
555+
string profileHash = pathX;
556+
auto authorInfo = lookupAuthorByHash(profileHash);
557+
enforce(authorInfo[0] !is null, _!"User not found");
558+
string authorName = authorInfo[0];
559+
string authorEmail = authorInfo[1];
560+
561+
// Create a content subscription with author name and email filters prefilled
562+
// Use regex mode with escaped strings for exact matching
563+
auto subscription = createSubscription(user.getName(), "content", [
564+
"trigger-content-author-name-enabled" : "on",
565+
"trigger-content-author-name-match-type" : "regex",
566+
"trigger-content-author-name-case-sensitive" : "on",
567+
"trigger-content-author-name-str" : "^" ~ authorName.escapeRE ~ "$",
568+
"trigger-content-author-email-enabled" : "on",
569+
"trigger-content-author-email-match-type" : "regex",
570+
"trigger-content-author-email-case-sensitive" : "on",
571+
"trigger-content-author-email-str" : "^" ~ authorEmail.escapeRE ~ "$",
572+
]);
573+
title = _!"Subscribe to user";
574+
discussionSubscriptionEdit(subscription);
575+
break;
576+
}
551577
case "delete":
552578
case "dodelete":
553579
return response.redirect("/moderate/" ~ path[1..$].join("/"));

src/dfeed/web/web/view/userprofile.d

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import dfeed.web.web.page : html, NotFoundException;
3333
import dfeed.web.web.part.gravatar : getGravatarHash, putGravatar;
3434
import dfeed.web.web.part.profile : getProfileHash, profileUrl;
3535
import dfeed.web.web.part.strings : summarizeTime, formatShortTime;
36+
import dfeed.web.web.statics : staticPath;
3637
import dfeed.web.web.user : user;
3738

3839
/// Look up author name and email from a profile hash.
@@ -102,6 +103,16 @@ void discussionUserProfile(string profileHash, out string title, out string auth
102103
html.put(`<div class="user-profile-avatar">`);
103104
putGravatar(gravatarHash, author, gravatarUrl,
104105
_!`%s's Gravatar profile`.format(author), null, 128);
106+
html.put(`<div class="user-profile-actions">`);
107+
html.put(`<a class="actionlink picturelink" href="`, gravatarUrl, `" title="`, _!`View Gravatar profile`, `">`);
108+
html.put(`<img src="`, staticPath("/images/picture.png"), `">`, _!`Gravatar profile`, `</a>`);
109+
if (user.isLoggedIn())
110+
{
111+
html.put(` `);
112+
html.put(`<a class="actionlink subscribelink" href="/subscribe-user/`, profileHash, `" title="`, _!`Subscribe to this user's posts`, `">`);
113+
html.put(`<img src="`, staticPath("/images/star.png"), `">`, _!`Subscribe`, `</a>`);
114+
}
115+
html.put(`</div>`);
105116
html.put(`</div>`);
106117

107118
// Name and basic info
@@ -145,8 +156,6 @@ void discussionUserProfile(string profileHash, out string title, out string auth
145156

146157
html.put(`</table>`);
147158

148-
html.put(`<p><a href="`, gravatarUrl, `">`, _!`Gravatar profile`, `</a></p>`);
149-
150159
html.put(`</div>`); // user-profile-info
151160
html.put(`</div>`); // user-profile-header
152161

0 commit comments

Comments
 (0)