diff --git a/pkg/config/page_sizes.go b/pkg/config/page_sizes.go
index 236f17f..b1306db 100644
--- a/pkg/config/page_sizes.go
+++ b/pkg/config/page_sizes.go
@@ -18,7 +18,7 @@ var (
PageSizeSiteGallery = 16
PageSizeUserGallery = 16
PageSizeInboxList = 20 // sidebar list
- PageSizeInboxThread = 20 // conversation view
+ PageSizeInboxThread = 10 // conversation view
PageSizeForums = 100 // TODO: for main category index view
PageSizeThreadList = 20 // 20 threads per board, 20 posts per thread
PageSizeForumAdmin = 20
diff --git a/pkg/controller/inbox/delete.go b/pkg/controller/inbox/delete.go
new file mode 100644
index 0000000..ae2da76
--- /dev/null
+++ b/pkg/controller/inbox/delete.go
@@ -0,0 +1,84 @@
+package inbox
+
+import (
+ "net/http"
+ "strconv"
+
+ "code.nonshy.com/nonshy/website/pkg/models"
+ "code.nonshy.com/nonshy/website/pkg/session"
+ "code.nonshy.com/nonshy/website/pkg/templates"
+)
+
+// Delete a new chat coming from a user's profile page.
+func Delete() http.HandlerFunc {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ if r.Method != http.MethodPost {
+ session.FlashError(w, r, "Invalid method.")
+ templates.Redirect(w, "/")
+ return
+ }
+
+ // Parse parameters.
+ var (
+ id uint64
+ idStr = r.FormValue("id")
+ deleteAll = r.FormValue("intent") == "delete-thread"
+ next = r.FormValue("next")
+ )
+
+ if value, err := strconv.Atoi(idStr); err == nil {
+ id = uint64(value)
+ } else {
+ session.FlashError(w, r, "Request error.")
+ templates.Redirect(w, "/")
+ return
+ }
+
+ // The redirect URL must be local.
+ if len(next) == 0 || next[0] != '/' {
+ next = "/"
+ }
+
+ // Get the current user.
+ currentUser, err := session.CurrentUser(r)
+ if err != nil {
+ session.FlashError(w, r, "Error getting the current user: %s", err)
+ templates.Redirect(w, next)
+ return
+ }
+
+ // Lookup the message.
+ message, err := models.GetMessage(id)
+ if err != nil {
+ session.FlashError(w, r, err.Error())
+ templates.Redirect(w, next)
+ }
+
+ // Delete whole thread?
+ if deleteAll {
+ if err := models.DeleteMessageThread(message); err != nil {
+ session.FlashError(w, r, "Error removing thread: %s", err)
+ } else {
+ session.Flash(w, r, "Message thread has been removed.")
+ }
+ templates.Redirect(w, next)
+ return
+ }
+
+ // We should be a party on this message.
+ if message.SourceUserID != currentUser.ID {
+ session.FlashError(w, r, "You did not create that message so you can't delete it.")
+ templates.Redirect(w, next)
+ return
+ }
+
+ // Do the needful.
+ if err := message.Delete(); err != nil {
+ session.FlashError(w, r, "Error deleting the message: %s", err)
+ } else {
+ session.Flash(w, r, "Message deleted!")
+ }
+
+ templates.Redirect(w, next)
+ })
+}
diff --git a/pkg/models/message.go b/pkg/models/message.go
index 1a6dfee..25e7507 100644
--- a/pkg/models/message.go
+++ b/pkg/models/message.go
@@ -75,6 +75,15 @@ func GetMessageThread(sourceUserID, targetUserID uint64, pager *Pagination) ([]*
return m, result.Error
}
+// DeleteMessageThread removes all message history between two people.
+func DeleteMessageThread(message *Message) error {
+ return DB.Where(
+ "(source_user_id = ? AND target_user_id = ?) OR (source_user_id = ? AND target_user_id = ?)",
+ message.SourceUserID, message.TargetUserID,
+ message.TargetUserID, message.SourceUserID,
+ ).Delete(&Message{}).Error
+}
+
// CountUnreadMessages gets the count of unread messages for a user.
func CountUnreadMessages(userID uint64) (int64, error) {
query := DB.Where(
@@ -106,3 +115,8 @@ func (m *Message) Save() error {
result := DB.Save(m)
return result.Error
}
+
+// Delete a message.
+func (m *Message) Delete() error {
+ return DB.Delete(m).Error
+}
diff --git a/pkg/router/router.go b/pkg/router/router.go
index 50998e7..a2f9242 100644
--- a/pkg/router/router.go
+++ b/pkg/router/router.go
@@ -52,6 +52,7 @@ func New() http.Handler {
mux.Handle("/messages", middleware.LoginRequired(inbox.Inbox()))
mux.Handle("/messages/read/", middleware.LoginRequired(inbox.Inbox()))
mux.Handle("/messages/compose", middleware.LoginRequired(inbox.Compose()))
+ mux.Handle("/messages/delete", middleware.LoginRequired(inbox.Delete()))
mux.Handle("/friends", middleware.LoginRequired(friend.Friends()))
mux.Handle("/friends/add", middleware.LoginRequired(friend.AddFriend()))
mux.Handle("/users/block", middleware.LoginRequired(block.BlockUser()))
diff --git a/web/static/css/theme.css b/web/static/css/theme.css
index d1f5ca7..b13db08 100644
--- a/web/static/css/theme.css
+++ b/web/static/css/theme.css
@@ -1,5 +1,9 @@
/* Custom CSS styles */
+abbr {
+ cursor: help;
+}
+
/* Container for large profile pic on user pages */
.profile-photo {
width: 150px;
@@ -10,10 +14,12 @@
padding: 4px;
position: relative;
}
+
.profile-photo img {
max-width: 100%;
height: auto;
}
+
.profile-photo .corner {
position: absolute;
top: 0;
@@ -36,14 +42,17 @@
.has-text-private {
color: #CC00CC;
}
+
.has-text-private-light {
color: #FF99FF;
}
+
.hero.is-private {
background-color: #b748c7;
}
+
.hero.is-private.is-bold {
- background-image: linear-gradient(141deg,#b329b1 0,#9948c7 71%,#7156d2 100%);
+ background-image: linear-gradient(141deg, #b329b1 0, #9948c7 71%, #7156d2 100%);
}
/* Mobile: notification badge near the hamburger menu */
@@ -53,6 +62,7 @@
right: 50px;
z-index: 1000;
}
+
@media screen and (min-width: 1024px) {
.nonshy-mobile-notification {
display: none;
diff --git a/web/templates/account/search.html b/web/templates/account/search.html
index 91ce193..17ace16 100644
--- a/web/templates/account/search.html
+++ b/web/templates/account/search.html
@@ -5,8 +5,11 @@
People
- Explore
+
+
+ People
+
+ Member Directory
- NEW Sept. 9 2022 + I didn't set out to build "just another social network" that allows for random, faceless, anonymous people to sign up - you can do that literally anywhere else. This website was designed specifically to get ahead of what happened with Tumblr, Pornhub and other sites @@ -155,7 +163,6 @@
- NEW Sept. 8 2022 I understand that some nudists need to exercise a degree of discretion and will not want to take a face pic with {{PrettyTitle}}'s name and upload that anywhere at all onto the Internet. For example if you are a teacher or work in law enforcement or the clergy and you need to keep @@ -180,10 +187,31 @@ picture can be marked private or "friends only" if you like; see below.
++ Before you have an approved certification photo, you can mainly only access and edit your + own profile page, and upload a few pictures while you await approval. Your pictures won't + be shown to members on the Site Gallery until you're certified, and most of the website's + features (namely, the Forums, Site Gallery and Member Search Directory) are gated behind + certification. +
+ ++ Certified members may, at their own discretion, be able to find your profile page by + browsing the Member Directory. They may send you a friend request or reach out to you. + Or, if you happen to know a member's profile URL on this site, you (the non-certified + member) can view their profile page and photo gallery (depending on their privacy + settings), send them a friend request or direct message. But basically, it will be + difficult to discover users to interact with until after you are certified - and + this is intentional to help guard against spam bots and creepy people. +
+ +- NEW Sept. 8 2022 You may set your Profile Picture to be "Friends only" or "Private" visibility if you wish to be more discreet about your face pictures.
@@ -207,26 +235,6 @@- Before you have an approved certification photo, you can mainly only access and edit your - own profile page, and upload a few pictures while you await approval. Your pictures won't - be shown to members on the Site Gallery until you're certified, and most of the website's - features (namely, the Forums, Site Gallery and Member Search Directory) are gated behind - certification. -
- -- Certified members may, at their own discretion, be able to find your profile page by - browsing the Member Directory. They may send you a friend request or reach out to you. - Or, if you happen to know a member's profile URL on this site, you (the non-certified - member) can view their profile page and photo gallery (depending on their privacy - settings), send them a friend request or direct message. But basically, it will be - difficult to discover users to interact with until after you are certified - and - this is intentional to help guard against spam bots and creepy people. -
-@@ -258,6 +266,26 @@ +
+ You have two options for deleting your private one-on-one chat messages. +
+ ++ You can delete your own messages by clicking on the "Delete" + button that appears below them. This deletes your message from both of + your threads, and (if unread), will not notify them that they had an unread + message. +
+ ++ You can delete the whole thread by using the "Delete whole thread" + button at the bottom of the conversation. This will remove both of your + chat history with one another and make it like you never exchanged a DM before + at all. +
+{{$SourceUser.NameOrUsername}}
++ {{$SourceUser.NameOrUsername}} + + {{if $SourceUser.IsAdmin}} + + + Admin + + {{end}} +
{{$SourceUser.Username}} @@ -68,13 +81,6 @@ Not Certified! {{end}} - - {{if $SourceUser.IsAdmin}} - - - Admin - - {{end}}