Delete the inner circle
This commit is contained in:
parent
1936bcde37
commit
e70ede301f
|
@ -6,11 +6,9 @@ const (
|
||||||
// - Chat: have operator controls in the chat room
|
// - Chat: have operator controls in the chat room
|
||||||
// - Forum: ability to edit and delete user posts
|
// - Forum: ability to edit and delete user posts
|
||||||
// - Photo: omniscient view of all gallery photos, can edit/delete photos
|
// - Photo: omniscient view of all gallery photos, can edit/delete photos
|
||||||
// - Inner circle: ability to remove users from it
|
ScopeChatModerator = "social.moderator.chat"
|
||||||
ScopeChatModerator = "social.moderator.chat"
|
ScopeForumModerator = "social.moderator.forum"
|
||||||
ScopeForumModerator = "social.moderator.forum"
|
ScopePhotoModerator = "social.moderator.photo"
|
||||||
ScopePhotoModerator = "social.moderator.photo"
|
|
||||||
ScopeCircleModerator = "social.moderator.inner-circle"
|
|
||||||
|
|
||||||
// Certification photo management
|
// Certification photo management
|
||||||
// - Approve: ability to respond to pending certification pics
|
// - Approve: ability to respond to pending certification pics
|
||||||
|
@ -48,9 +46,6 @@ const (
|
||||||
// Admins with this scope can not be blocked by users.
|
// Admins with this scope can not be blocked by users.
|
||||||
ScopeUnblockable = "admin.unblockable"
|
ScopeUnblockable = "admin.unblockable"
|
||||||
|
|
||||||
// Special scope to mark an admin automagically in the Inner Circle
|
|
||||||
ScopeIsInnerCircle = "admin.override.inner-circle"
|
|
||||||
|
|
||||||
// The global wildcard scope gets all available permissions.
|
// The global wildcard scope gets all available permissions.
|
||||||
ScopeSuperuser = "*"
|
ScopeSuperuser = "*"
|
||||||
)
|
)
|
||||||
|
@ -60,7 +55,6 @@ var AdminScopeDescriptions = map[string]string{
|
||||||
ScopeChatModerator: "Have operator controls in the chat room (can mark cameras as explicit, or kick/ban people from chat).",
|
ScopeChatModerator: "Have operator controls in the chat room (can mark cameras as explicit, or kick/ban people from chat).",
|
||||||
ScopeForumModerator: "Ability to moderate the forum (edit or delete posts).",
|
ScopeForumModerator: "Ability to moderate the forum (edit or delete posts).",
|
||||||
ScopePhotoModerator: "Ability to moderate photo galleries (can see all private or friends-only photos, and edit or delete them).",
|
ScopePhotoModerator: "Ability to moderate photo galleries (can see all private or friends-only photos, and edit or delete them).",
|
||||||
ScopeCircleModerator: "Ability to remove members from the inner circle.",
|
|
||||||
ScopeCertificationApprove: "Ability to see pending certification pictures and approve or reject them.",
|
ScopeCertificationApprove: "Ability to see pending certification pictures and approve or reject them.",
|
||||||
ScopeCertificationList: "Ability to see existing certification pictures that have already been approved or rejected.",
|
ScopeCertificationList: "Ability to see existing certification pictures that have already been approved or rejected.",
|
||||||
ScopeCertificationView: "Ability to see and double check a specific user's certification picture on demand.",
|
ScopeCertificationView: "Ability to see and double check a specific user's certification picture on demand.",
|
||||||
|
@ -78,7 +72,6 @@ var AdminScopeDescriptions = map[string]string{
|
||||||
ScopeChangeLog: "Ability to see website change logs (e.g. history of a certification photo, gallery photo settings, etc.)",
|
ScopeChangeLog: "Ability to see website change logs (e.g. history of a certification photo, gallery photo settings, etc.)",
|
||||||
ScopeUserNotes: "Ability to see all notes written about a user, or to see all notes written by admins.",
|
ScopeUserNotes: "Ability to see all notes written about a user, or to see all notes written by admins.",
|
||||||
ScopeUnblockable: "This admin can not be added to user block lists.",
|
ScopeUnblockable: "This admin can not be added to user block lists.",
|
||||||
ScopeIsInnerCircle: "This admin is automatically part of the inner circle.",
|
|
||||||
ScopeSuperuser: "This admin has access to ALL admin features on the website.",
|
ScopeSuperuser: "This admin has access to ALL admin features on the website.",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +87,6 @@ func ListAdminScopes() []string {
|
||||||
ScopeChatModerator,
|
ScopeChatModerator,
|
||||||
ScopeForumModerator,
|
ScopeForumModerator,
|
||||||
ScopePhotoModerator,
|
ScopePhotoModerator,
|
||||||
ScopeCircleModerator,
|
|
||||||
ScopeCertificationApprove,
|
ScopeCertificationApprove,
|
||||||
ScopeCertificationList,
|
ScopeCertificationList,
|
||||||
ScopeCertificationView,
|
ScopeCertificationView,
|
||||||
|
@ -112,7 +104,6 @@ func ListAdminScopes() []string {
|
||||||
ScopeChangeLog,
|
ScopeChangeLog,
|
||||||
ScopeUserNotes,
|
ScopeUserNotes,
|
||||||
ScopeUnblockable,
|
ScopeUnblockable,
|
||||||
ScopeIsInnerCircle,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,9 +107,6 @@ const (
|
||||||
PhotoQuotaUncertified = 6
|
PhotoQuotaUncertified = 6
|
||||||
PhotoQuotaCertified = 100
|
PhotoQuotaCertified = 100
|
||||||
|
|
||||||
// Min number of public photos for inner circle members to see the prompt to invite.
|
|
||||||
InnerCircleMinimumPublicPhotos = 5
|
|
||||||
|
|
||||||
// Rate limit for too many Site Gallery pictures.
|
// Rate limit for too many Site Gallery pictures.
|
||||||
// Some users sign up and immediately max out their gallery and spam
|
// Some users sign up and immediately max out their gallery and spam
|
||||||
// the Site Gallery page. These limits can ensure only a few Site Gallery
|
// the Site Gallery page. These limits can ensure only a few Site Gallery
|
||||||
|
|
|
@ -106,7 +106,6 @@ var (
|
||||||
// Default forum categories for forum landing page.
|
// Default forum categories for forum landing page.
|
||||||
ForumCategories = []string{
|
ForumCategories = []string{
|
||||||
"Rules and Announcements",
|
"Rules and Announcements",
|
||||||
"The Inner Circle",
|
|
||||||
"Nudists",
|
"Nudists",
|
||||||
"Exhibitionists",
|
"Exhibitionists",
|
||||||
"Photo Boards",
|
"Photo Boards",
|
||||||
|
|
|
@ -1,216 +0,0 @@
|
||||||
package account
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"code.nonshy.com/nonshy/website/pkg/config"
|
|
||||||
"code.nonshy.com/nonshy/website/pkg/log"
|
|
||||||
"code.nonshy.com/nonshy/website/pkg/models"
|
|
||||||
"code.nonshy.com/nonshy/website/pkg/session"
|
|
||||||
"code.nonshy.com/nonshy/website/pkg/templates"
|
|
||||||
)
|
|
||||||
|
|
||||||
// InnerCircle is the landing page for inner circle members only.
|
|
||||||
func InnerCircle() http.HandlerFunc {
|
|
||||||
tmpl := templates.Must("account/inner_circle.html")
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
currentUser, err := session.CurrentUser(r)
|
|
||||||
if err != nil || !currentUser.IsInnerCircle() {
|
|
||||||
templates.NotFoundPage(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var vars = map[string]interface{}{
|
|
||||||
"InnerCircleMinimumPublicPhotos": config.InnerCircleMinimumPublicPhotos,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := tmpl.Execute(w, r, vars); err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// InviteCircle is the landing page to invite a user into the circle.
|
|
||||||
func InviteCircle() http.HandlerFunc {
|
|
||||||
tmpl := templates.Must("account/invite_circle.html")
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
currentUser, err := session.CurrentUser(r)
|
|
||||||
if err != nil || !currentUser.IsInnerCircle() {
|
|
||||||
templates.NotFoundPage(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invite whom?
|
|
||||||
username := r.FormValue("to")
|
|
||||||
user, err := models.FindUser(username)
|
|
||||||
if err != nil {
|
|
||||||
templates.NotFoundPage(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if currentUser.ID == user.ID && currentUser.InnerCircle {
|
|
||||||
session.FlashError(w, r, "You are already part of the inner circle.")
|
|
||||||
templates.Redirect(w, "/inner-circle")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Any blocking?
|
|
||||||
if models.IsBlocking(currentUser.ID, user.ID) && !currentUser.IsAdmin {
|
|
||||||
session.FlashError(w, r, "You are blocked from inviting this user to the circle.")
|
|
||||||
templates.Redirect(w, "/inner-circle")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// POSTing?
|
|
||||||
if r.Method == http.MethodPost {
|
|
||||||
var (
|
|
||||||
confirm = r.FormValue("intent") == "confirm"
|
|
||||||
)
|
|
||||||
|
|
||||||
if !confirm {
|
|
||||||
templates.Redirect(w, "/u/"+username)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add them!
|
|
||||||
if err := models.AddToInnerCircle(user); err != nil {
|
|
||||||
session.FlashError(w, r, "Couldn't add to the inner circle: %s", err)
|
|
||||||
} else {
|
|
||||||
session.Flash(w, r, "%s has been added to the inner circle!", user.Username)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("InnerCircle: %s adds %s to the inner circle", currentUser.Username, user.Username)
|
|
||||||
|
|
||||||
templates.Redirect(w, "/u/"+user.Username+"/photos")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var vars = map[string]interface{}{
|
|
||||||
"User": user,
|
|
||||||
}
|
|
||||||
if err := tmpl.Execute(w, r, vars); err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveCircle is the admin-only page to remove a member from the circle.
|
|
||||||
func RemoveCircle() http.HandlerFunc {
|
|
||||||
tmpl := templates.Must("account/remove_circle.html")
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
currentUser, err := session.CurrentUser(r)
|
|
||||||
if err != nil || !currentUser.IsInnerCircle() {
|
|
||||||
templates.NotFoundPage(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove whom?
|
|
||||||
username := r.FormValue("to")
|
|
||||||
user, err := models.FindUser(username)
|
|
||||||
if err != nil {
|
|
||||||
templates.NotFoundPage(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// POSTing?
|
|
||||||
if r.Method == http.MethodPost {
|
|
||||||
var (
|
|
||||||
confirm = r.FormValue("intent") == "confirm"
|
|
||||||
)
|
|
||||||
|
|
||||||
if !confirm {
|
|
||||||
templates.Redirect(w, "/u/"+username)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Admin (with the correct scope): remove them now.
|
|
||||||
if currentUser.HasAdminScope(config.ScopeCircleModerator) {
|
|
||||||
if err := models.RemoveFromInnerCircle(user); err != nil {
|
|
||||||
session.FlashError(w, r, "Couldn't remove from the inner circle: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
session.Flash(w, r, "%s has been removed from the inner circle!", user.Username)
|
|
||||||
} else {
|
|
||||||
// Non-admin user: request removal only.
|
|
||||||
fb := &models.Feedback{
|
|
||||||
Intent: "report.circle",
|
|
||||||
Subject: "Inner Circle Removal Request",
|
|
||||||
TableName: "users",
|
|
||||||
TableID: user.ID,
|
|
||||||
Message: fmt.Sprintf(
|
|
||||||
"An inner circle member has flagged that **%s** no longer qualifies to be a part of the inner circle and should be removed.",
|
|
||||||
user.Username,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := models.CreateFeedback(fb); err != nil {
|
|
||||||
session.FlashError(w, r, "Couldn't create admin notification: %s", err)
|
|
||||||
} else {
|
|
||||||
session.Flash(w, r, "A request to remove %s from the inner circle has been sent to the site admin.", user.Username)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
templates.Redirect(w, "/u/"+user.Username)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var vars = map[string]interface{}{
|
|
||||||
"User": user,
|
|
||||||
}
|
|
||||||
if err := tmpl.Execute(w, r, vars); err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// LeaveCircle allows users to remove themself from the circle.
|
|
||||||
func LeaveCircle() http.HandlerFunc {
|
|
||||||
tmpl := templates.Must("account/leave_circle.html")
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
currentUser, err := session.CurrentUser(r)
|
|
||||||
if err != nil || !currentUser.IsInnerCircle() {
|
|
||||||
templates.NotFoundPage(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Submitting the form?
|
|
||||||
if r.Method == http.MethodPost {
|
|
||||||
var (
|
|
||||||
confirm = r.PostFormValue("confirm") == "true"
|
|
||||||
dontReinvite = r.PostFormValue("dont_reinvite") == "true"
|
|
||||||
)
|
|
||||||
|
|
||||||
if !confirm {
|
|
||||||
templates.Redirect(w, r.URL.Path)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove them from the circle now.
|
|
||||||
if err := models.RemoveFromInnerCircle(currentUser); err != nil {
|
|
||||||
session.FlashError(w, r, "Error updating your inner circle status: %s", err)
|
|
||||||
templates.Redirect(w, r.URL.Path)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Confirmation message, + don't reinvite again?
|
|
||||||
if dontReinvite {
|
|
||||||
currentUser.SetProfileField("inner_circle_optout", "true")
|
|
||||||
session.Flash(w, r, "You have been removed from the inner circle, and you WILL NOT be invited again in the future.")
|
|
||||||
} else {
|
|
||||||
session.Flash(w, r, "You have been removed from the inner circle.")
|
|
||||||
}
|
|
||||||
|
|
||||||
templates.Redirect(w, "/me")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := tmpl.Execute(w, r, nil); err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -159,7 +159,6 @@ func Search() http.HandlerFunc {
|
||||||
Certified: certifiedOnly,
|
Certified: certifiedOnly,
|
||||||
NearCity: city,
|
NearCity: city,
|
||||||
NotCertified: isCertified == "false",
|
NotCertified: isCertified == "false",
|
||||||
InnerCircle: isCertified == "circle",
|
|
||||||
ShyAccounts: isCertified == "shy",
|
ShyAccounts: isCertified == "shy",
|
||||||
IsBanned: isCertified == "banned",
|
IsBanned: isCertified == "banned",
|
||||||
IsDisabled: isCertified == "disabled",
|
IsDisabled: isCertified == "disabled",
|
||||||
|
|
|
@ -50,12 +50,7 @@ func Feedback() http.HandlerFunc {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
session.FlashError(w, r, "Couldn't visit user %d: %s", fb.TableID, err)
|
session.FlashError(w, r, "Couldn't visit user %d: %s", fb.TableID, err)
|
||||||
} else {
|
} else {
|
||||||
// If this is an "inner circle removal" report, go to their gallery and filter pics by Public.
|
templates.Redirect(w, "/u/"+user.Username)
|
||||||
if fb.Intent == "report.circle" {
|
|
||||||
templates.Redirect(w, "/u/"+user.Username+"/photos?visibility=public")
|
|
||||||
} else {
|
|
||||||
templates.Redirect(w, "/u/"+user.Username)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case "photos":
|
case "photos":
|
||||||
|
|
|
@ -104,8 +104,6 @@ func Landing() http.HandlerFunc {
|
||||||
avatar = "/static/img/shy-private.png"
|
avatar = "/static/img/shy-private.png"
|
||||||
case models.PhotoFriends:
|
case models.PhotoFriends:
|
||||||
avatar = "/static/img/shy-friends.png"
|
avatar = "/static/img/shy-friends.png"
|
||||||
case models.PhotoInnerCircle:
|
|
||||||
avatar = "/static/img/shy-secret.png"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Country flag emoji.
|
// Country flag emoji.
|
||||||
|
@ -125,7 +123,6 @@ func Landing() http.HandlerFunc {
|
||||||
// Create the JWT claims.
|
// Create the JWT claims.
|
||||||
claims := Claims{
|
claims := Claims{
|
||||||
IsAdmin: currentUser.HasAdminScope(config.ScopeChatModerator),
|
IsAdmin: currentUser.HasAdminScope(config.ScopeChatModerator),
|
||||||
VIP: currentUser.IsInnerCircle(),
|
|
||||||
Avatar: avatar,
|
Avatar: avatar,
|
||||||
ProfileURL: "/u/" + currentUser.Username,
|
ProfileURL: "/u/" + currentUser.Username,
|
||||||
Nickname: currentUser.NameOrUsername(),
|
Nickname: currentUser.NameOrUsername(),
|
||||||
|
|
|
@ -64,7 +64,6 @@ func AddEdit() http.HandlerFunc {
|
||||||
isExplicit = r.PostFormValue("explicit") == "true"
|
isExplicit = r.PostFormValue("explicit") == "true"
|
||||||
isPrivileged = r.PostFormValue("privileged") == "true"
|
isPrivileged = r.PostFormValue("privileged") == "true"
|
||||||
isPermitPhotos = r.PostFormValue("permit_photos") == "true"
|
isPermitPhotos = r.PostFormValue("permit_photos") == "true"
|
||||||
isInnerCircle = r.PostFormValue("inner_circle") == "true"
|
|
||||||
isPrivate = r.PostFormValue("private") == "true"
|
isPrivate = r.PostFormValue("private") == "true"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -84,7 +83,6 @@ func AddEdit() http.HandlerFunc {
|
||||||
models.NewFieldDiff("Explicit", forum.Explicit, isExplicit),
|
models.NewFieldDiff("Explicit", forum.Explicit, isExplicit),
|
||||||
models.NewFieldDiff("Privileged", forum.Privileged, isPrivileged),
|
models.NewFieldDiff("Privileged", forum.Privileged, isPrivileged),
|
||||||
models.NewFieldDiff("PermitPhotos", forum.PermitPhotos, isPermitPhotos),
|
models.NewFieldDiff("PermitPhotos", forum.PermitPhotos, isPermitPhotos),
|
||||||
models.NewFieldDiff("InnerCircle", forum.InnerCircle, isInnerCircle),
|
|
||||||
models.NewFieldDiff("Private", forum.Private, isPrivate),
|
models.NewFieldDiff("Private", forum.Private, isPrivate),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +92,6 @@ func AddEdit() http.HandlerFunc {
|
||||||
forum.Explicit = isExplicit
|
forum.Explicit = isExplicit
|
||||||
forum.Privileged = isPrivileged
|
forum.Privileged = isPrivileged
|
||||||
forum.PermitPhotos = isPermitPhotos
|
forum.PermitPhotos = isPermitPhotos
|
||||||
forum.InnerCircle = isInnerCircle
|
|
||||||
forum.Private = isPrivate
|
forum.Private = isPrivate
|
||||||
|
|
||||||
// Save it.
|
// Save it.
|
||||||
|
@ -131,7 +128,6 @@ func AddEdit() http.HandlerFunc {
|
||||||
Explicit: isExplicit,
|
Explicit: isExplicit,
|
||||||
Privileged: isPrivileged,
|
Privileged: isPrivileged,
|
||||||
PermitPhotos: isPermitPhotos,
|
PermitPhotos: isPermitPhotos,
|
||||||
InnerCircle: isInnerCircle,
|
|
||||||
Private: isPrivate,
|
Private: isPrivate,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +145,6 @@ func AddEdit() http.HandlerFunc {
|
||||||
"* Explicit: %v\n"+
|
"* Explicit: %v\n"+
|
||||||
"* Privileged: %v\n"+
|
"* Privileged: %v\n"+
|
||||||
"* Photos: %v\n"+
|
"* Photos: %v\n"+
|
||||||
"* Inner Circle: %v\n"+
|
|
||||||
"* Private: %v",
|
"* Private: %v",
|
||||||
forum.Category,
|
forum.Category,
|
||||||
forum.Title,
|
forum.Title,
|
||||||
|
@ -158,7 +153,6 @@ func AddEdit() http.HandlerFunc {
|
||||||
forum.Explicit,
|
forum.Explicit,
|
||||||
forum.Privileged,
|
forum.Privileged,
|
||||||
forum.PermitPhotos,
|
forum.PermitPhotos,
|
||||||
forum.InnerCircle,
|
|
||||||
forum.Private,
|
forum.Private,
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
|
@ -35,12 +35,6 @@ func Forum() http.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is it an inner circle forum?
|
|
||||||
if forum.InnerCircle && !currentUser.IsInnerCircle() {
|
|
||||||
templates.NotFoundPage(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is it a private forum?
|
// Is it a private forum?
|
||||||
if forum.Private && !currentUser.IsAdmin {
|
if forum.Private && !currentUser.IsAdmin {
|
||||||
templates.NotFoundPage(w, r)
|
templates.NotFoundPage(w, r)
|
||||||
|
|
|
@ -51,12 +51,6 @@ func Thread() http.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is it an inner circle forum?
|
|
||||||
if forum.InnerCircle && !currentUser.IsInnerCircle() {
|
|
||||||
templates.NotFoundPage(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is it a private forum?
|
// Is it a private forum?
|
||||||
if forum.Private && !currentUser.IsAdmin {
|
if forum.Private && !currentUser.IsAdmin {
|
||||||
templates.NotFoundPage(w, r)
|
templates.NotFoundPage(w, r)
|
||||||
|
|
|
@ -83,9 +83,8 @@ func Edit() http.HandlerFunc {
|
||||||
setProfilePic = r.FormValue("intent") == "profile-pic"
|
setProfilePic = r.FormValue("intent") == "profile-pic"
|
||||||
crop = pphoto.ParseCropCoords(r.FormValue("crop"))
|
crop = pphoto.ParseCropCoords(r.FormValue("crop"))
|
||||||
|
|
||||||
// Are we GOING private or changing to Inner Circle?
|
// Are we GOING private?
|
||||||
goingPrivate = visibility == models.PhotoPrivate && visibility != photo.Visibility
|
goingPrivate = visibility == models.PhotoPrivate && visibility != photo.Visibility
|
||||||
goingCircle = visibility == models.PhotoInnerCircle && visibility != photo.Visibility
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(altText) > config.AltTextMaxLength {
|
if len(altText) > config.AltTextMaxLength {
|
||||||
|
@ -164,7 +163,7 @@ func Edit() http.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this picture has moved to Private, revoke any notification we gave about it before.
|
// If this picture has moved to Private, revoke any notification we gave about it before.
|
||||||
if goingPrivate || goingCircle {
|
if goingPrivate {
|
||||||
log.Info("The picture is GOING PRIVATE (to %s), revoke any notifications about it", photo.Visibility)
|
log.Info("The picture is GOING PRIVATE (to %s), revoke any notifications about it", photo.Visibility)
|
||||||
models.RemoveNotification("photos", photo.ID)
|
models.RemoveNotification("photos", photo.ID)
|
||||||
}
|
}
|
||||||
|
@ -241,13 +240,6 @@ func Delete() http.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inner circle warning: if this deletion would drop them below the 5 public picture
|
|
||||||
// threshold, warn them they will be removed from the circle if they continue.
|
|
||||||
var innerCircleWarning bool
|
|
||||||
if currentUser.IsInnerCircle() && photo.Visibility == models.PhotoPublic && models.CountPublicPhotos(currentUser.ID) <= 5 {
|
|
||||||
innerCircleWarning = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Confirm deletion?
|
// Confirm deletion?
|
||||||
if r.Method == http.MethodPost {
|
if r.Method == http.MethodPost {
|
||||||
confirm := r.PostFormValue("confirm") == "true"
|
confirm := r.PostFormValue("confirm") == "true"
|
||||||
|
@ -291,15 +283,6 @@ func Delete() http.HandlerFunc {
|
||||||
// Log the change.
|
// Log the change.
|
||||||
models.LogDeleted(currentUser, requestUser, "photos", photo.ID, "Deleted the photo.", photo)
|
models.LogDeleted(currentUser, requestUser, "photos", photo.ID, "Deleted the photo.", photo)
|
||||||
|
|
||||||
// Remove them from the inner circle?
|
|
||||||
if innerCircleWarning {
|
|
||||||
if err := models.RemoveFromInnerCircle(currentUser); err != nil {
|
|
||||||
session.FlashError(w, r, "Couldn't remove from the inner circle: %s", err)
|
|
||||||
} else {
|
|
||||||
session.Flash(w, r, "You have been removed from the inner circle because your count of public photos has dropped below 5.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
session.Flash(w, r, "Photo deleted!")
|
session.Flash(w, r, "Photo deleted!")
|
||||||
|
|
||||||
// Maybe kick them from chat if this deletion makes them into a Shy Account.
|
// Maybe kick them from chat if this deletion makes them into a Shy Account.
|
||||||
|
@ -313,8 +296,7 @@ func Delete() http.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
var vars = map[string]interface{}{
|
var vars = map[string]interface{}{
|
||||||
"Photo": photo,
|
"Photo": photo,
|
||||||
"InnerCircleWarning": innerCircleWarning,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := tmpl.Execute(w, r, vars); err != nil {
|
if err := tmpl.Execute(w, r, vars); err != nil {
|
||||||
|
|
|
@ -222,15 +222,6 @@ func notifyFriendsNewPhoto(photo *models.Photo, currentUser *models.User) {
|
||||||
notifyUserIDs = models.PrivateGranteeUserIDs(currentUser.ID)
|
notifyUserIDs = models.PrivateGranteeUserIDs(currentUser.ID)
|
||||||
log.Info("Notify %d private grantees about the new photo by %s", len(notifyUserIDs), currentUser.Username)
|
log.Info("Notify %d private grantees about the new photo by %s", len(notifyUserIDs), currentUser.Username)
|
||||||
}
|
}
|
||||||
} else if photo.Visibility == models.PhotoInnerCircle {
|
|
||||||
// Inner circle members. If the pic is also Explicit, further narrow to explicit friend IDs.
|
|
||||||
if photo.Explicit {
|
|
||||||
notifyUserIDs = models.FriendIDsInCircleAreExplicit(currentUser.ID)
|
|
||||||
log.Info("Notify %d EXPLICIT circle friends about the new photo by %s", len(notifyUserIDs), currentUser.Username)
|
|
||||||
} else {
|
|
||||||
notifyUserIDs = models.FriendIDsInCircle(currentUser.ID)
|
|
||||||
log.Info("Notify %d circle friends about the new photo by %s", len(notifyUserIDs), currentUser.Username)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Friends only: we will notify exactly the friends we selected above.
|
// Friends only: we will notify exactly the friends we selected above.
|
||||||
notifyUserIDs = friendIDs
|
notifyUserIDs = friendIDs
|
||||||
|
|
|
@ -32,9 +32,6 @@ func UserPhotos() http.HandlerFunc {
|
||||||
filterVisibility = r.FormValue("visibility")
|
filterVisibility = r.FormValue("visibility")
|
||||||
sort = r.FormValue("sort")
|
sort = r.FormValue("sort")
|
||||||
sortOK bool
|
sortOK bool
|
||||||
|
|
||||||
// Inner circle invite view?
|
|
||||||
innerCircleInvite = r.FormValue("intent") == "inner_circle"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Sort options.
|
// Sort options.
|
||||||
|
@ -73,11 +70,6 @@ func UserPhotos() http.HandlerFunc {
|
||||||
isShyFrom = !isOwnPhotos && (currentUser.IsShyFrom(user) || (isShy && !areFriends))
|
isShyFrom = !isOwnPhotos && (currentUser.IsShyFrom(user) || (isShy && !areFriends))
|
||||||
)
|
)
|
||||||
|
|
||||||
// Inner circle invite: not if we are not in the circle ourselves.
|
|
||||||
if innerCircleInvite && !currentUser.IsInnerCircle() {
|
|
||||||
innerCircleInvite = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bail early if we are shy from this user.
|
// Bail early if we are shy from this user.
|
||||||
if isShy && isShyFrom {
|
if isShy && isShyFrom {
|
||||||
var vars = map[string]interface{}{
|
var vars = map[string]interface{}{
|
||||||
|
@ -126,11 +118,6 @@ func UserPhotos() http.HandlerFunc {
|
||||||
visibility = append(visibility, models.PhotoFriends)
|
visibility = append(visibility, models.PhotoFriends)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inner circle photos.
|
|
||||||
if currentUser.IsInnerCircle() {
|
|
||||||
visibility = append(visibility, models.PhotoInnerCircle)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we are Filtering by Visibility, ensure the target visibility is accessible to us.
|
// If we are Filtering by Visibility, ensure the target visibility is accessible to us.
|
||||||
if filterVisibility != "" {
|
if filterVisibility != "" {
|
||||||
var isOK bool
|
var isOK bool
|
||||||
|
@ -220,14 +207,11 @@ func UserPhotos() http.HandlerFunc {
|
||||||
"NoteCount": models.CountNotesAboutUser(currentUser, user),
|
"NoteCount": models.CountNotesAboutUser(currentUser, user),
|
||||||
"FriendCount": models.CountFriends(user.ID),
|
"FriendCount": models.CountFriends(user.ID),
|
||||||
"PublicPhotoCount": models.CountPublicPhotos(user.ID),
|
"PublicPhotoCount": models.CountPublicPhotos(user.ID),
|
||||||
"InnerCircleMinimumPublicPhotos": config.InnerCircleMinimumPublicPhotos,
|
|
||||||
"Pager": pager,
|
"Pager": pager,
|
||||||
"LikeMap": likeMap,
|
"LikeMap": likeMap,
|
||||||
"CommentMap": commentMap,
|
"CommentMap": commentMap,
|
||||||
"ViewStyle": viewStyle,
|
"ViewStyle": viewStyle,
|
||||||
"ExplicitCount": explicitCount,
|
"ExplicitCount": explicitCount,
|
||||||
"InnerCircleOptOut": user.GetProfileField("inner_circle_optout") == "true",
|
|
||||||
"InnerCircleInviteView": innerCircleInvite,
|
|
||||||
|
|
||||||
// Search filters
|
// Search filters
|
||||||
"Sort": sort,
|
"Sort": sort,
|
||||||
|
|
|
@ -55,12 +55,6 @@ func View() http.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is this a circle photo?
|
|
||||||
if photo.Visibility == models.PhotoInnerCircle && !currentUser.IsInnerCircle() {
|
|
||||||
templates.NotFoundPage(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is this user private and we're not friends?
|
// Is this user private and we're not friends?
|
||||||
var (
|
var (
|
||||||
areFriends = models.AreFriends(user.ID, currentUser.ID)
|
areFriends = models.AreFriends(user.ID, currentUser.ID)
|
||||||
|
|
|
@ -20,7 +20,6 @@ type Forum struct {
|
||||||
Explicit bool `gorm:"index"`
|
Explicit bool `gorm:"index"`
|
||||||
Privileged bool
|
Privileged bool
|
||||||
PermitPhotos bool
|
PermitPhotos bool
|
||||||
InnerCircle bool `gorm:"index"`
|
|
||||||
Private bool `gorm:"index"`
|
Private bool `gorm:"index"`
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
|
@ -97,11 +96,6 @@ func PaginateForums(user *User, categories []string, pager *Pagination) ([]*Foru
|
||||||
wheres = append(wheres, "explicit = false")
|
wheres = append(wheres, "explicit = false")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide circle forums if the user isn't in the circle.
|
|
||||||
if !user.IsInnerCircle() {
|
|
||||||
wheres = append(wheres, "inner_circle is not true")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide private forums except for admins.
|
// Hide private forums except for admins.
|
||||||
if !user.IsAdmin {
|
if !user.IsAdmin {
|
||||||
wheres = append(wheres, "private is not true")
|
wheres = append(wheres, "private is not true")
|
||||||
|
|
|
@ -47,11 +47,6 @@ func PaginateRecentPosts(user *User, categories []string, allComments bool, page
|
||||||
wheres = append(wheres, "forums.explicit = false")
|
wheres = append(wheres, "forums.explicit = false")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Circle membership.
|
|
||||||
if !user.IsInnerCircle() {
|
|
||||||
wheres = append(wheres, "forums.inner_circle is not true")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private forums.
|
// Private forums.
|
||||||
if !user.IsAdmin {
|
if !user.IsAdmin {
|
||||||
wheres = append(wheres, "forums.private is not true")
|
wheres = append(wheres, "forums.private is not true")
|
||||||
|
|
|
@ -95,11 +95,6 @@ func SearchForum(user *User, search *Search, filters ForumSearchFilters, pager *
|
||||||
wheres = append(wheres, "forums.explicit = false")
|
wheres = append(wheres, "forums.explicit = false")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Circle membership.
|
|
||||||
if !user.IsInnerCircle() {
|
|
||||||
wheres = append(wheres, "forums.inner_circle is not true")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private forums.
|
// Private forums.
|
||||||
if !user.IsAdmin {
|
if !user.IsAdmin {
|
||||||
wheres = append(wheres, "forums.private is not true")
|
wheres = append(wheres, "forums.private is not true")
|
||||||
|
|
|
@ -45,7 +45,6 @@ const (
|
||||||
NotificationCertApproved NotificationType = "cert_approved"
|
NotificationCertApproved NotificationType = "cert_approved"
|
||||||
NotificationPrivatePhoto NotificationType = "private_photo" // private photo grants
|
NotificationPrivatePhoto NotificationType = "private_photo" // private photo grants
|
||||||
NotificationNewPhoto NotificationType = "new_photo"
|
NotificationNewPhoto NotificationType = "new_photo"
|
||||||
NotificationInnerCircle NotificationType = "inner_circle"
|
|
||||||
NotificationCustom NotificationType = "custom" // custom message pushed
|
NotificationCustom NotificationType = "custom" // custom message pushed
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ type NotificationFilter struct {
|
||||||
NewPhotos bool `json:"photos"`
|
NewPhotos bool `json:"photos"`
|
||||||
AlsoCommented bool `json:"replies"` // also_comment and also_posted
|
AlsoCommented bool `json:"replies"` // also_comment and also_posted
|
||||||
PrivatePhoto bool `json:"private"`
|
PrivatePhoto bool `json:"private"`
|
||||||
Misc bool `json:"misc"` // friendship_approved, cert_approved, cert_rejected, inner_circle, custom
|
Misc bool `json:"misc"` // friendship_approved, cert_approved, cert_rejected, custom
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultNotificationFilter = NotificationFilter{
|
var defaultNotificationFilter = NotificationFilter{
|
||||||
|
|
|
@ -33,10 +33,9 @@ type Photo struct {
|
||||||
type PhotoVisibility string
|
type PhotoVisibility string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PhotoPublic PhotoVisibility = "public" // on profile page and/or public gallery
|
PhotoPublic PhotoVisibility = "public" // on profile page and/or public gallery
|
||||||
PhotoFriends PhotoVisibility = "friends" // only friends can see it
|
PhotoFriends PhotoVisibility = "friends" // only friends can see it
|
||||||
PhotoPrivate PhotoVisibility = "private" // private
|
PhotoPrivate PhotoVisibility = "private" // private
|
||||||
PhotoInnerCircle PhotoVisibility = "circle" // inner circle
|
|
||||||
|
|
||||||
// Special visibility in case, on User Gallery view, user applies a filter
|
// Special visibility in case, on User Gallery view, user applies a filter
|
||||||
// for friends-only picture but they are not friends with the user.
|
// for friends-only picture but they are not friends with the user.
|
||||||
|
@ -51,14 +50,6 @@ var (
|
||||||
PhotoPrivate,
|
PhotoPrivate,
|
||||||
}
|
}
|
||||||
|
|
||||||
// "All" but also for Inner Circle members.
|
|
||||||
PhotoVisibilityCircle = []PhotoVisibility{
|
|
||||||
PhotoPublic,
|
|
||||||
PhotoFriends,
|
|
||||||
PhotoPrivate,
|
|
||||||
PhotoInnerCircle,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Site Gallery visibility for when your friends show up in the gallery.
|
// Site Gallery visibility for when your friends show up in the gallery.
|
||||||
// Or: "Friends + Gallery" photos can appear to your friends in the Site Gallery.
|
// Or: "Friends + Gallery" photos can appear to your friends in the Site Gallery.
|
||||||
PhotoVisibilityFriends = []string{
|
PhotoVisibilityFriends = []string{
|
||||||
|
@ -273,11 +264,6 @@ func CountPhotosICanSee(user *User, viewer *User) int64 {
|
||||||
PhotoPublic,
|
PhotoPublic,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is the viewer in the inner circle?
|
|
||||||
if viewer.IsInnerCircle() {
|
|
||||||
visibilities = append(visibilities, PhotoInnerCircle)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is the viewer friends with the target?
|
// Is the viewer friends with the target?
|
||||||
if AreFriends(user.ID, viewer.ID) {
|
if AreFriends(user.ID, viewer.ID) {
|
||||||
visibilities = append(visibilities, PhotoFriends)
|
visibilities = append(visibilities, PhotoFriends)
|
||||||
|
@ -350,7 +336,6 @@ func MapPhotoCounts(users []*User, viewer *User) PhotoCountMap {
|
||||||
// User ID filters for the viewer's context.
|
// User ID filters for the viewer's context.
|
||||||
myFriendIDs = FriendIDs(viewer.ID)
|
myFriendIDs = FriendIDs(viewer.ID)
|
||||||
myPrivateGrantedIDs = PrivateGrantedUserIDs(viewer.ID)
|
myPrivateGrantedIDs = PrivateGrantedUserIDs(viewer.ID)
|
||||||
isInnerCircle = viewer.IsInnerCircle()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Define "all photos visibilities"
|
// Define "all photos visibilities"
|
||||||
|
@ -367,10 +352,6 @@ func MapPhotoCounts(users []*User, viewer *User) PhotoCountMap {
|
||||||
PhotoPrivate,
|
PhotoPrivate,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if isInnerCircle {
|
|
||||||
photosPublic = append(photosPublic, PhotoInnerCircle)
|
|
||||||
photosFriends = append(photosFriends, PhotoInnerCircle)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flatten the userIDs of all passed in users.
|
// Flatten the userIDs of all passed in users.
|
||||||
for _, user := range users {
|
for _, user := range users {
|
||||||
|
@ -445,7 +426,7 @@ func CountExplicitPhotos(userID uint64, visibility []PhotoVisibility) (int64, er
|
||||||
return count, result.Error
|
return count, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// CountPublicPhotos returns the number of public photos on a user's page (to control whether the "invite to circle" prompt can appear).
|
// CountPublicPhotos returns the number of public photos on a user's page.
|
||||||
func CountPublicPhotos(userID uint64) int64 {
|
func CountPublicPhotos(userID uint64) int64 {
|
||||||
query := DB.Where(
|
query := DB.Where(
|
||||||
"user_id = ? AND visibility = ?",
|
"user_id = ? AND visibility = ?",
|
||||||
|
@ -541,10 +522,6 @@ func PaginateGalleryPhotos(user *User, conf Gallery, pager *Pagination) ([]*Phot
|
||||||
PhotoPrivate,
|
PhotoPrivate,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if user.IsInnerCircle() {
|
|
||||||
photosPublic = append(photosPublic, PhotoInnerCircle)
|
|
||||||
photosFriends = append(photosFriends, PhotoInnerCircle)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Admins see everything on the site (only an admin user can get an admin view).
|
// Admins see everything on the site (only an admin user can get an admin view).
|
||||||
adminView = user.HasAdminScope(config.ScopePhotoModerator) && adminView
|
adminView = user.HasAdminScope(config.ScopePhotoModerator) && adminView
|
||||||
|
|
|
@ -28,7 +28,6 @@ type User struct {
|
||||||
Birthdate time.Time
|
Birthdate time.Time
|
||||||
Certified bool
|
Certified bool
|
||||||
Explicit bool `gorm:"index"` // user has opted-in to see explicit content
|
Explicit bool `gorm:"index"` // user has opted-in to see explicit content
|
||||||
InnerCircle bool `gorm:"index"` // user is in the inner circle
|
|
||||||
CreatedAt time.Time `gorm:"index"`
|
CreatedAt time.Time `gorm:"index"`
|
||||||
UpdatedAt time.Time `gorm:"index"`
|
UpdatedAt time.Time `gorm:"index"`
|
||||||
LastLoginAt time.Time `gorm:"index"`
|
LastLoginAt time.Time `gorm:"index"`
|
||||||
|
@ -262,7 +261,6 @@ type UserSearch struct {
|
||||||
NearCity *WorldCities
|
NearCity *WorldCities
|
||||||
Certified bool
|
Certified bool
|
||||||
NotCertified bool
|
NotCertified bool
|
||||||
InnerCircle bool
|
|
||||||
ShyAccounts bool
|
ShyAccounts bool
|
||||||
IsBanned bool
|
IsBanned bool
|
||||||
IsDisabled bool
|
IsDisabled bool
|
||||||
|
@ -436,11 +434,6 @@ func SearchUsers(user *User, search *UserSearch, pager *Pagination) ([]*User, er
|
||||||
wheres = append(wheres, "is_admin = true")
|
wheres = append(wheres, "is_admin = true")
|
||||||
}
|
}
|
||||||
|
|
||||||
if search.InnerCircle {
|
|
||||||
wheres = append(wheres, "inner_circle = ?")
|
|
||||||
placeholders = append(placeholders, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
if search.ShyAccounts {
|
if search.ShyAccounts {
|
||||||
a, b := WhereClauseShyAccounts()
|
a, b := WhereClauseShyAccounts()
|
||||||
wheres = append(wheres, a)
|
wheres = append(wheres, a)
|
||||||
|
@ -655,8 +648,6 @@ func (u *User) VisibleAvatarURL(currentUser *User) string {
|
||||||
switch visibility {
|
switch visibility {
|
||||||
case PhotoPrivate:
|
case PhotoPrivate:
|
||||||
return "/static/img/shy-private.png"
|
return "/static/img/shy-private.png"
|
||||||
case PhotoInnerCircle:
|
|
||||||
return "/static/img/shy-secret.png"
|
|
||||||
case PhotoFriends:
|
case PhotoFriends:
|
||||||
return "/static/img/shy-friends.png"
|
return "/static/img/shy-friends.png"
|
||||||
}
|
}
|
||||||
|
@ -681,9 +672,6 @@ func (u *User) CanSeeProfilePicture(currentUser *User) (bool, PhotoVisibility) {
|
||||||
} else if visibility == PhotoFriends && !u.UserRelationship.IsFriend {
|
} else if visibility == PhotoFriends && !u.UserRelationship.IsFriend {
|
||||||
// Friends only
|
// Friends only
|
||||||
return false, visibility
|
return false, visibility
|
||||||
} else if visibility == PhotoInnerCircle && currentUser != nil && !currentUser.IsInnerCircle() {
|
|
||||||
// Inner circle only
|
|
||||||
return false, visibility
|
|
||||||
} else if u.ProfilePhoto.CroppedFilename != "" {
|
} else if u.ProfilePhoto.CroppedFilename != "" {
|
||||||
// Happy path
|
// Happy path
|
||||||
return true, visibility
|
return true, visibility
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"code.nonshy.com/nonshy/website/pkg/config"
|
|
||||||
"code.nonshy.com/nonshy/website/pkg/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Helper functions relating to the inner circle.
|
|
||||||
|
|
||||||
// IsInnerCircle returns whether the user is in the inner circle (including if the user is an admin, who is always in the inner circle).
|
|
||||||
func (u *User) IsInnerCircle() bool {
|
|
||||||
return u.InnerCircle || u.HasAdminScope(config.ScopeIsInnerCircle)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddToInnerCircle adds a user to the circle, sending them a notification in the process.
|
|
||||||
func AddToInnerCircle(u *User) error {
|
|
||||||
if u.InnerCircle {
|
|
||||||
return errors.New("already a part of the inner circle")
|
|
||||||
}
|
|
||||||
|
|
||||||
u.InnerCircle = true
|
|
||||||
if err := u.Save(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send them a notification.
|
|
||||||
notif := &Notification{
|
|
||||||
UserID: u.ID,
|
|
||||||
AboutUserID: &u.ID,
|
|
||||||
Type: NotificationInnerCircle,
|
|
||||||
Link: "/inner-circle",
|
|
||||||
TableName: "__inner_circle",
|
|
||||||
TableID: u.ID,
|
|
||||||
}
|
|
||||||
if err := CreateNotification(notif); err != nil {
|
|
||||||
log.Error("AddToInnerCircle: couldn't create notification: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveFromInnerCircle kicks a user from the inner circle. Any photo they
|
|
||||||
// had that was marked circle-only is updated to public.
|
|
||||||
func RemoveFromInnerCircle(u *User) error {
|
|
||||||
if !u.InnerCircle {
|
|
||||||
return errors.New("is not a part of the inner circle")
|
|
||||||
}
|
|
||||||
|
|
||||||
u.InnerCircle = false
|
|
||||||
if err := u.Save(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update their circle-only photos to public.
|
|
||||||
if err := DB.Model(&Photo{}).Where(
|
|
||||||
"user_id = ? AND visibility = ?",
|
|
||||||
u.ID, PhotoInnerCircle,
|
|
||||||
).Update("visibility", PhotoPrivate); err != nil {
|
|
||||||
log.Error("RemoveFromInnerCircle: couldn't update photo visibility: %s", err.Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Revoke any historic notification about the circle.
|
|
||||||
RemoveNotification("__inner_circle", u.ID)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -5,10 +5,9 @@ package models
|
||||||
// The zero-values should fail safely: in case the UserRelationship isn't populated correctly,
|
// The zero-values should fail safely: in case the UserRelationship isn't populated correctly,
|
||||||
// private profile pics show as private by default.
|
// private profile pics show as private by default.
|
||||||
type UserRelationship struct {
|
type UserRelationship struct {
|
||||||
Computed bool // check whether the SetUserRelationships function has been run
|
Computed bool // check whether the SetUserRelationships function has been run
|
||||||
IsFriend bool // if true, a friends-only profile pic can show
|
IsFriend bool // if true, a friends-only profile pic can show
|
||||||
IsPrivateGranted bool // if true, a private profile pic can show
|
IsPrivateGranted bool // if true, a private profile pic can show
|
||||||
IsInnerCirclePeer bool // if true, the current user is in the inner circle so may see circle-only profile picture
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetUserRelationships updates a set of User objects to populate their UserRelationships in
|
// SetUserRelationships updates a set of User objects to populate their UserRelationships in
|
||||||
|
@ -18,7 +17,6 @@ func SetUserRelationships(currentUser *User, users []*User) error {
|
||||||
var (
|
var (
|
||||||
friendIDs = FriendIDs(currentUser.ID)
|
friendIDs = FriendIDs(currentUser.ID)
|
||||||
privateGrants = PrivateGrantedUserIDs(currentUser.ID)
|
privateGrants = PrivateGrantedUserIDs(currentUser.ID)
|
||||||
isInnerCircle = currentUser.IsInnerCircle()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Map them for easier lookup.
|
// Map them for easier lookup.
|
||||||
|
@ -37,8 +35,6 @@ func SetUserRelationships(currentUser *User, users []*User) error {
|
||||||
|
|
||||||
// Inject the UserRelationships.
|
// Inject the UserRelationships.
|
||||||
for _, u := range users {
|
for _, u := range users {
|
||||||
u.UserRelationship.IsInnerCirclePeer = isInnerCircle
|
|
||||||
|
|
||||||
if u.ID == currentUser.ID {
|
if u.ID == currentUser.ID {
|
||||||
// Current user - set both bools to true - you can always see your own profile pic.
|
// Current user - set both bools to true - you can always see your own profile pic.
|
||||||
u.UserRelationship.IsFriend = true
|
u.UserRelationship.IsFriend = true
|
||||||
|
|
|
@ -78,9 +78,6 @@ func New() http.Handler {
|
||||||
mux.Handle("/comments", middleware.LoginRequired(comment.PostComment()))
|
mux.Handle("/comments", middleware.LoginRequired(comment.PostComment()))
|
||||||
mux.Handle("GET /comments/subscription", middleware.LoginRequired(comment.Subscription()))
|
mux.Handle("GET /comments/subscription", middleware.LoginRequired(comment.Subscription()))
|
||||||
mux.Handle("GET /admin/unimpersonate", middleware.LoginRequired(admin.Unimpersonate()))
|
mux.Handle("GET /admin/unimpersonate", middleware.LoginRequired(admin.Unimpersonate()))
|
||||||
mux.Handle("GET /inner-circle", middleware.LoginRequired(account.InnerCircle()))
|
|
||||||
mux.Handle("/inner-circle/invite", middleware.LoginRequired(account.InviteCircle()))
|
|
||||||
mux.Handle("/inner-circle/leave", middleware.LoginRequired(account.LeaveCircle()))
|
|
||||||
mux.Handle("GET /admin/transparency/{username}", middleware.LoginRequired(admin.Transparency()))
|
mux.Handle("GET /admin/transparency/{username}", middleware.LoginRequired(admin.Transparency()))
|
||||||
|
|
||||||
// Certification Required. Pages that only full (verified) members can access.
|
// Certification Required. Pages that only full (verified) members can access.
|
||||||
|
@ -105,7 +102,6 @@ func New() http.Handler {
|
||||||
mux.Handle("/admin/add-user", middleware.AdminRequired(config.ScopeUserCreate, admin.AddUser()))
|
mux.Handle("/admin/add-user", middleware.AdminRequired(config.ScopeUserCreate, admin.AddUser()))
|
||||||
mux.Handle("/forum/admin", middleware.AdminRequired(config.ScopeForumAdmin, forum.Manage()))
|
mux.Handle("/forum/admin", middleware.AdminRequired(config.ScopeForumAdmin, forum.Manage()))
|
||||||
mux.Handle("/forum/admin/edit", middleware.AdminRequired(config.ScopeForumAdmin, forum.AddEdit()))
|
mux.Handle("/forum/admin/edit", middleware.AdminRequired(config.ScopeForumAdmin, forum.AddEdit()))
|
||||||
mux.Handle("/inner-circle/remove", middleware.LoginRequired(account.RemoveCircle()))
|
|
||||||
mux.Handle("/admin/photo/mark-explicit", middleware.AdminRequired("", admin.MarkPhotoExplicit()))
|
mux.Handle("/admin/photo/mark-explicit", middleware.AdminRequired("", admin.MarkPhotoExplicit()))
|
||||||
mux.Handle("GET /admin/changelog", middleware.AdminRequired(config.ScopeChangeLog, admin.ChangeLog()))
|
mux.Handle("GET /admin/changelog", middleware.AdminRequired(config.ScopeChangeLog, admin.ChangeLog()))
|
||||||
|
|
||||||
|
|
|
@ -52,11 +52,6 @@ func TemplateFuncs(r *http.Request) template.FuncMap {
|
||||||
`<strong style="color: #FF77FF">s</strong>`,
|
`<strong style="color: #FF77FF">s</strong>`,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
"PrettyCircle": func() template.HTML {
|
|
||||||
return template.HTML(
|
|
||||||
`<span style="color: #0077ff">I</span><span style="color: #1c77ff">n</span><span style="color: #3877ff">n</span><span style="color: #5477ff">e</span><span style="color: #7077ff">r</span><span style="color: #8c77ff"> </span><span style="color: #aa77ff">c</span><span style="color: #b877ff">i</span><span style="color: #c677ff">r</span><span style="color: #d477ff">c</span><span style="color: #e277ff">l</span><span style="color: #f077ff">e</span>`,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
"Pluralize": Pluralize[int],
|
"Pluralize": Pluralize[int],
|
||||||
"Pluralize64": Pluralize[int64],
|
"Pluralize64": Pluralize[int64],
|
||||||
"PluralizeU64": Pluralize[uint64],
|
"PluralizeU64": Pluralize[uint64],
|
||||||
|
|
|
@ -94,10 +94,6 @@ img {
|
||||||
background-image: linear-gradient(141deg, #b329b1 0, #9948c7 71%, #7156d2 100%);
|
background-image: linear-gradient(141deg, #b329b1 0, #9948c7 71%, #7156d2 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero.is-inner-circle {
|
|
||||||
background-image: linear-gradient(141deg, #294eb3 0, #9948c7 71%, #d256d2 100%)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mobile: notification badge near the hamburger menu */
|
/* Mobile: notification badge near the hamburger menu */
|
||||||
.nonshy-mobile-notification {
|
.nonshy-mobile-notification {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
@ -194,10 +194,6 @@
|
||||||
your naked journey.
|
your naked journey.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
|
||||||
The <strong>most</strong> {{PrettyTitle}} of our members may be rewarded with access to exclusive features.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Check out the full <a href="/features"><strong>Features List</strong></a> for more details.
|
Check out the full <a href="/features"><strong>Features List</strong></a> for more details.
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -218,14 +218,6 @@
|
||||||
Edit Profile & Settings
|
Edit Profile & Settings
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{{if .CurrentUser.IsInnerCircle}}
|
|
||||||
<li>
|
|
||||||
<a href="/inner-circle">
|
|
||||||
<span class="icon"><img src="/static/img/circle-16.png"></span>
|
|
||||||
{{PrettyCircle}}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{{end}}
|
|
||||||
<li>
|
<li>
|
||||||
<a href="/photo/certification">
|
<a href="/photo/certification">
|
||||||
<span class="icon"><i class="fa fa-certificate"></i></span>
|
<span class="icon"><i class="fa fa-certificate"></i></span>
|
||||||
|
@ -574,8 +566,6 @@
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
{{if and $Body.Photo (eq $Body.Photo.Visibility "private")}}
|
{{if and $Body.Photo (eq $Body.Photo.Visibility "private")}}
|
||||||
<i class="fa fa-eye {{if $Body.Photo.Explicit}}has-text-danger{{else}}has-text-private{{end}}"></i>
|
<i class="fa fa-eye {{if $Body.Photo.Explicit}}has-text-danger{{else}}has-text-private{{end}}"></i>
|
||||||
{{else if and $Body.Photo (eq $Body.Photo.Visibility "circle")}}
|
|
||||||
<img src="/static/img/circle-16.png">
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<i class="fa fa-image {{if $Body.Photo.Explicit}}has-text-danger{{else}}has-text-link{{end}}"></i>
|
<i class="fa fa-image {{if $Body.Photo.Explicit}}has-text-danger{{else}}has-text-link{{end}}"></i>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -604,15 +594,6 @@
|
||||||
<span>
|
<span>
|
||||||
Your <strong>certification photo</strong> was rejected!
|
Your <strong>certification photo</strong> was rejected!
|
||||||
</span>
|
</span>
|
||||||
{{else if eq .Type "inner_circle"}}
|
|
||||||
<span class="icon"><img src="/static/img/circle-16.png"></span>
|
|
||||||
<span>
|
|
||||||
You have been added to the {{PrettyCircle}} of nonshy.
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<div class="block content mt-2">
|
|
||||||
<a href="/inner-circle">Click to learn more</a> about the inner circle.
|
|
||||||
</div>
|
|
||||||
{{else}}
|
{{else}}
|
||||||
{{.AboutUser.Username}} {{.Type}} {{.TableName}} {{.TableID}}
|
{{.AboutUser.Username}} {{.Type}} {{.TableName}} {{.TableID}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -116,9 +116,6 @@
|
||||||
{{else}}
|
{{else}}
|
||||||
{{.NameOrUsername}}
|
{{.NameOrUsername}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if and $Root.CurrentUser.IsInnerCircle .InnerCircle}}
|
|
||||||
<img src="/static/img/circle-16.png">
|
|
||||||
{{end}}
|
|
||||||
</a>
|
</a>
|
||||||
{{if eq .Visibility "private"}}
|
{{if eq .Visibility "private"}}
|
||||||
<sup class="fa fa-mask is-size-7" title="Private Profile"></sup>
|
<sup class="fa fa-mask is-size-7" title="Private Profile"></sup>
|
||||||
|
|
|
@ -1,220 +0,0 @@
|
||||||
{{define "title"}}The inner circle{{end}}
|
|
||||||
{{define "content"}}
|
|
||||||
<div class="block">
|
|
||||||
<section class="hero is-inner-circle is-bold">
|
|
||||||
<div class="hero-body">
|
|
||||||
<div class="container">
|
|
||||||
<h1 class="title has-text-light">
|
|
||||||
<img src="/static/img/circle-24.png" class="mr-1">
|
|
||||||
The inner circle
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="block p-4">
|
|
||||||
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column is-one-quarter">
|
|
||||||
<!-- Quick Links -->
|
|
||||||
<div class="card block">
|
|
||||||
<header class="card-header has-background-link">
|
|
||||||
<p class="card-header-title has-text-light">
|
|
||||||
<span class="icon mr-1"><img src="/static/img/circle-16.png"></span>
|
|
||||||
<span>Quick Links</span>
|
|
||||||
</p>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div class="card-content">
|
|
||||||
<p class="block">
|
|
||||||
Some quick links to {{PrettyCircle}}-only views mentioned
|
|
||||||
in the description on this page:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<aside class="menu">
|
|
||||||
<ul class="menu-list block">
|
|
||||||
<li>
|
|
||||||
<a href="/photo/gallery?visibility=circle">
|
|
||||||
<i class="fa fa-image mr-1"></i>
|
|
||||||
Gallery (circle-only photos)
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="/members?certified=circle">
|
|
||||||
<i class="fa fa-people-group mr-1"></i>
|
|
||||||
Inner circle members
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="/f/circle">
|
|
||||||
<i class="fa fa-comments mr-1"></i>
|
|
||||||
Forum (Circle Chat)
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
{{if .CurrentUser.Explicit}}
|
|
||||||
<li>
|
|
||||||
<a href="/f/circle-jerk">
|
|
||||||
<i class="fa fa-comments mr-1"></i>
|
|
||||||
Forum (Circle Jerk) <small class="fa fa-fire has-text-danger" title="Explicit"></small>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{{end}}
|
|
||||||
</ul>
|
|
||||||
</aside>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="column content">
|
|
||||||
<p>
|
|
||||||
Congratulations! You have been added to the <strong>{{PrettyCircle}}</strong> because you
|
|
||||||
exemplify what it truly means to be a {{PrettyTitle}} nudist.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>What is the inner circle?</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The inner circle is for {{PrettyTitle}} members who <em>actually</em> share a lot of nude pictures,
|
|
||||||
<strong>with face</strong>, of themselves on their profile page. It is "the party inside the party"
|
|
||||||
designed only for members who truly embrace the spirit of the {{PrettyTitle}} website by boldly
|
|
||||||
sharing nude pics with face for other nonshy nudists to see.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
As a member of the inner circle, you can see who else on the website is a part of the circle. Look
|
|
||||||
for the <img src="/static/img/circle-16.png" alt="Inner circle"> icon on profile pages, the
|
|
||||||
member directory, forums or the chat room. You may find that some of your {{PrettyTitle}} friends
|
|
||||||
were already in the circle! People who are <em>not</em> in the circle won't see these indicators
|
|
||||||
anywhere on the website.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>What can I do for being in the inner circle?</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
As a part of the inner circle, you have access to the following new features:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
When
|
|
||||||
<a href="/photo/upload"><strong><i class="fa fa-upload mr-1"></i> Uploading a photo</strong></a> you
|
|
||||||
have a new Visibility option for "<strong>{{PrettyCircle}}</strong> <img src="/static/img/circle-16.png">"
|
|
||||||
so that only members of the inner circle can see those pictures.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
On the
|
|
||||||
<a href="/photo/gallery"><strong><i class="fa fa-image mr-1"></i> Site Gallery</strong></a>
|
|
||||||
you can filter for <a href="/photo/gallery?visibility=circle">Inner Circle-only photos</a> shared
|
|
||||||
by other members of the circle.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
On the
|
|
||||||
<a href="/members"><strong><i class="fa fa-people-group mr-1"></i> Member Directory</strong></a>
|
|
||||||
you can see who else is <a href="/members?certified=circle">in the inner circle.</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
On the
|
|
||||||
<a href="/f/circle"><strong><i class="fa fa-comments mr-1"></i> Forums</strong></a>
|
|
||||||
you can access exclusive inner circle-only boards.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
On the
|
|
||||||
<a href="/chat"><strong><i class="fa fa-message"></i> Chat Room</strong></a> you have access
|
|
||||||
to the exclusive Circle Chat channel, and you can see who else in the chat room is a part of
|
|
||||||
the inner circle. People outside the circle can't see who the inner circle members are!
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
On your <a href="/u/{{.CurrentUser.Username}}">profile page</a> you get an "Inner circle" badge near your
|
|
||||||
Certified status. This badge is <strong>only</strong> visible to members of the inner circle.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
You may <strong>invite</strong> other members to join the inner circle.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2 id="qualify">How does one qualify to be part of the inner circle?</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The minimum qualifications for somebody to be in the inner circle include:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
On <strong>public</strong> visibility, they have at least <strong>5 (five)</strong> photos
|
|
||||||
that show their <strong>face</strong> <em>and</em> <strong>nude body</strong> together.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If you see an inner circle member who had dropped below that threshold later (e.g., they moved
|
|
||||||
all of their pictures to private or they deleted them all from their page), you may
|
|
||||||
<strong>request removal</strong> from the circle when viewing their photo gallery page. Help
|
|
||||||
us keep the integrity of the inner circle by requesting removals when you see somebody who
|
|
||||||
should no longer qualify to be in the circle. <strong>Removal requests are anonymous!</strong>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>How do I invite others to join the inner circle?</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
When you are viewing a <strong>member's photo gallery</strong> page, look for the prompt at the top of the
|
|
||||||
page.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If a member posts several <small>(e.g. {{.InnerCircleMinimumPublicPhotos}}+)</small> nude pics <strong>including face</strong> you should invite them to join
|
|
||||||
the inner circle. All members of the circle are allowed to invite new members to join. We trust your
|
|
||||||
judgment: please only invite like-minded nudists who <em>actually</em> share nudes <em>with face</em>
|
|
||||||
to join the inner circle.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<strong>Notice:</strong> the prompt to invite them to the circle will not be visible if they do not have
|
|
||||||
<em>at least</em> <strong>{{.InnerCircleMinimumPublicPhotos}}</strong> public photos on their page at all.
|
|
||||||
Those public photos aren't necessarily nudes, but hiding the prompt unless they have {{.InnerCircleMinimumPublicPhotos}}
|
|
||||||
photos can help reduce the risk of inviting somebody on accident.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Please keep the existence of the inner circle a secret</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The inner circle is not publicly advertised on the site. This is to help ensure that "bad actors" won't
|
|
||||||
try and game the system (e.g., by begging somebody to invite them into the circle, or uploading a bare
|
|
||||||
minimum of nude pics for somebody to invite them only for them to delete their nudes and try and stay
|
|
||||||
in the inner circle). Plus, it adds an air of exclusivity to keep the existence of the circle on the
|
|
||||||
down low.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Still continue to share at least <em>some</em> nudes on "public"</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
With the new Photo visibility option for "inner circle only" you may tag your best nudes for only members
|
|
||||||
of the inner circle to see. However, you should still continue to share at least <em>some</em> photos on
|
|
||||||
"Public" as you were doing previously. This is for a couple of reasons:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
Members who are <em>not</em> in the circle won't see your circle-only photos. If for example you
|
|
||||||
placed <em>all</em> of your nudes on circle-only you would appear to look the same as someone who
|
|
||||||
uploaded no nudes at all.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
The "<a href="/faq#shy-faqs">Shy Account</a>" system of the main website still applies: if you have
|
|
||||||
not one public photo on your page you may be marked as a Shy Account and be limited from some site
|
|
||||||
features such as the Chat Room.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>Leave the inner circle</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If you would like to opt-out and leave the inner circle, you may do so by clicking
|
|
||||||
<a href="/inner-circle/leave">here</a>.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
|
@ -1,110 +0,0 @@
|
||||||
{{define "title"}}Invite to the inner circle{{end}}
|
|
||||||
{{define "content"}}
|
|
||||||
<div class="container">
|
|
||||||
<section class="hero is-inner-circle is-bold">
|
|
||||||
<div class="hero-body">
|
|
||||||
<div class="container">
|
|
||||||
<h1 class="title has-text-light">
|
|
||||||
<img src="/static/img/circle-24.png">
|
|
||||||
Invite to the inner circle
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<div class="block p-4">
|
|
||||||
<div class="columns is-centered">
|
|
||||||
<div class="column is-half">
|
|
||||||
|
|
||||||
<div class="card" style="width: 100%; max-width: 640px">
|
|
||||||
<header class="card-header has-background-link">
|
|
||||||
<p class="card-header-title has-text-light">
|
|
||||||
<span class="icon"><img src="/static/img/circle-16.png"></span>
|
|
||||||
Invite to the inner circle
|
|
||||||
</p>
|
|
||||||
</header>
|
|
||||||
<div class="card-content">
|
|
||||||
|
|
||||||
<div class="media block">
|
|
||||||
<div class="media-left">
|
|
||||||
{{template "avatar-64x64" .User}}
|
|
||||||
</div>
|
|
||||||
<div class="media-content">
|
|
||||||
<p class="title is-4">{{.User.NameOrUsername}}</p>
|
|
||||||
<p class="subtitle is-6">
|
|
||||||
<span class="icon"><i class="fa fa-user"></i></span>
|
|
||||||
<a href="/u/{{.User.Username}}" target="_blank">{{.User.Username}}</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="content">
|
|
||||||
<p>
|
|
||||||
Do you want to invite <strong>{{.User.Username}}</strong> to join the
|
|
||||||
{{PrettyCircle}}? Please review the following notes:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
The inner circle is designed for {{PrettyTitle}} members who <em>actually</em> post
|
|
||||||
several nude photos <strong>with face</strong> on their profile page.
|
|
||||||
If {{.User.Username}} only has clothed selfies on their page, or keeps
|
|
||||||
their face hidden or cropped out of their nudes, please <strong>do not</strong>
|
|
||||||
invite them to join the inner circle.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
We especially want people who post such pics <strong>on public</strong> visibility.
|
|
||||||
If {{.User.Username}} has <strong>several</strong> public nude pics with face (e.g.
|
|
||||||
at least 5 or so pictures), invite them into the circle!
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
All members of the inner circle are allowed to invite others to join the
|
|
||||||
circle. We trust your judgment -- help ensure that the inner circle is only
|
|
||||||
made up of truly non-shy nudists who show their whole body on their profile
|
|
||||||
page.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Note: while we use the word "invite" they will actually be added to the inner circle
|
|
||||||
immediately and receive a notification that they had been added. They won't know that
|
|
||||||
it was <em>you</em> who invited them to join the circle.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
To proceed, please <strong>double check that they have 5 Public photos</strong>
|
|
||||||
that include their face and nude body.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field has-text-centered">
|
|
||||||
<a href="/u/{{.User.Username}}/photos?visibility=public&intent=inner_circle"
|
|
||||||
class="button is-success">
|
|
||||||
Continue to their Public gallery...
|
|
||||||
</a>
|
|
||||||
<a href="/u/{{.User.Username}}" class="button is-warning ml-1">
|
|
||||||
Cancel
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
window.addEventListener("DOMContentLoaded", (event) => {
|
|
||||||
let $file = document.querySelector("#file"),
|
|
||||||
$fileName = document.querySelector("#fileName");
|
|
||||||
|
|
||||||
$file.addEventListener("change", function() {
|
|
||||||
let file = this.files[0];
|
|
||||||
$fileName.innerHTML = file.name;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{{end}}
|
|
|
@ -1,87 +0,0 @@
|
||||||
{{define "title"}}Leave the Inner Circle{{end}}
|
|
||||||
{{define "content"}}
|
|
||||||
<div class="container">
|
|
||||||
<section class="hero is-inner-circle is-bold">
|
|
||||||
<div class="hero-body">
|
|
||||||
<div class="container">
|
|
||||||
<h1 class="title has-text-light">
|
|
||||||
<img src="/static/img/circle-24.png" class="mr-1">
|
|
||||||
Leave the Inner Circle
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<div class="block p-4">
|
|
||||||
<div class="level">
|
|
||||||
<div class="level-item">
|
|
||||||
<div class="card" style="max-width: 512px">
|
|
||||||
<header class="card-header has-background-link">
|
|
||||||
<p class="card-header-title has-text-light">
|
|
||||||
<img src="/static/img/circle-16.png" class="mr-2">
|
|
||||||
Leave the Inner Circle
|
|
||||||
</p>
|
|
||||||
</header>
|
|
||||||
<div class="card-content content">
|
|
||||||
<form id="leave_circle" method="POST" action="/inner-circle/leave">
|
|
||||||
{{InputCSRF}}
|
|
||||||
<input type="hidden" name="confirm" value="true">
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Are you sure that you want to <strong>leave the {{PrettyCircle}}?</strong>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This action can not be un-done easily; after leaving the inner circle, the only
|
|
||||||
way back in is for somebody in the circle to invite you again.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
In case you <strong>do not want</strong> to be invited into the circle again,
|
|
||||||
you can check the box below.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<label class="checkbox mb-4 has-text-warning">
|
|
||||||
<input type="checkbox"
|
|
||||||
name="dont_reinvite"
|
|
||||||
id="dont_reinvite"
|
|
||||||
value="true">
|
|
||||||
Don't let anyone invite me to the {{PrettyCircle}} again.
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<div class="block has-text-center">
|
|
||||||
<button type="submit" class="button is-danger">Leave the Inner Circle</button>
|
|
||||||
<button type="button" class="button is-success" onclick="history.back()">Cancel</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
{{define "scripts"}}
|
|
||||||
<script>
|
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
|
||||||
let $form = document.querySelector("#leave_circle"),
|
|
||||||
$cb = document.querySelector("#dont_reinvite");
|
|
||||||
|
|
||||||
$form.addEventListener("submit", (e) => {
|
|
||||||
if ($cb.checked) {
|
|
||||||
if (!window.confirm(
|
|
||||||
"Are you sure you want to leave the circle, permanently?\n\n" +
|
|
||||||
"You have requested that nobody can re-invite you into the circle again in the future. " +
|
|
||||||
"This action CAN NOT be undone!\n\n" +
|
|
||||||
"If you want to leave open the possibility to be re-invited in the future, click Cancel " +
|
|
||||||
"and un-check that box."
|
|
||||||
)) {
|
|
||||||
e.preventDefault();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{{end}}
|
|
|
@ -120,17 +120,6 @@
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if and .CurrentUser.IsInnerCircle .User.IsInnerCircle}}
|
|
||||||
<div class="pt-1">
|
|
||||||
<div class="icon-text has-text-danger">
|
|
||||||
<span class="icon">
|
|
||||||
<img src="/static/img/circle-16.png">
|
|
||||||
</span>
|
|
||||||
<strong>{{PrettyCircle}}</strong>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{if .User.IsAdmin}}
|
{{if .User.IsAdmin}}
|
||||||
<div class="pt-1">
|
<div class="pt-1">
|
||||||
<div class="icon-text has-text-danger">
|
<div class="icon-text has-text-danger">
|
||||||
|
|
|
@ -1,116 +0,0 @@
|
||||||
{{define "title"}}Remove from the inner circle{{end}}
|
|
||||||
{{define "content"}}
|
|
||||||
<div class="container">
|
|
||||||
<section class="hero is-inner-circle is-bold">
|
|
||||||
<div class="hero-body">
|
|
||||||
<div class="container">
|
|
||||||
<h1 class="title has-text-light">
|
|
||||||
<img src="/static/img/circle-24.png">
|
|
||||||
Remove from the inner circle
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<div class="block p-4">
|
|
||||||
<div class="columns is-centered">
|
|
||||||
<div class="column is-half">
|
|
||||||
|
|
||||||
<div class="card" style="width: 100%; max-width: 640px">
|
|
||||||
<header class="card-header has-background-warning">
|
|
||||||
<p class="card-header-title has-text-black">
|
|
||||||
<span class="icon"><img src="/static/img/circle-16.png"></span>
|
|
||||||
Remove from the inner circle
|
|
||||||
</p>
|
|
||||||
</header>
|
|
||||||
<div class="card-content">
|
|
||||||
|
|
||||||
<div class="media block">
|
|
||||||
<div class="media-left">
|
|
||||||
{{template "avatar-64x64" .User}}
|
|
||||||
</div>
|
|
||||||
<div class="media-content">
|
|
||||||
<p class="title is-4">{{.User.NameOrUsername}}</p>
|
|
||||||
<p class="subtitle is-6">
|
|
||||||
<span class="icon"><i class="fa fa-user"></i></span>
|
|
||||||
<a href="/u/{{.User.Username}}" target="_blank">{{.User.Username}}</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form action="/inner-circle/remove" method="POST">
|
|
||||||
{{InputCSRF}}
|
|
||||||
<input type="hidden" name="to" value="{{.User.Username}}">
|
|
||||||
|
|
||||||
{{if .CurrentUser.HasAdminScope "social.moderator.inner-circle"}}
|
|
||||||
<div class="content">
|
|
||||||
<p>
|
|
||||||
Do you want to <strong class="has-text-danger">remove</strong> {{.User.Username}} from
|
|
||||||
the {{PrettyCircle}}? Doing so will:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
Unset their inner circle flag, removing them from all inner circle features.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Set any photo they had for "inner circle only" to be "public" instead.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Clean up any notification they once received about being invited to the inner circle.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
{{else}}
|
|
||||||
<div class="content">
|
|
||||||
<p>
|
|
||||||
Do you want to <strong class="has-text-danger">request removal</strong> of {{.User.Username}}
|
|
||||||
from the {{PrettyCircle}}?
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If {{.User.Username}} should no longer <a href="/inner-circle#qualify">qualify</a> to be a
|
|
||||||
part of the inner circle, you may flag them to be removed from the circle. For example: to
|
|
||||||
be invited into the circle someone should need to have <strong>at least 5 (five) pictures</strong>
|
|
||||||
that are on <strong>public</strong> visibility and which show their <strong>face and nude body</strong>
|
|
||||||
together. But if they have taken down their pictures and should no longer qualify to remain in
|
|
||||||
the {{PrettyCircle}}, you may request them to be removed and an admin will check them out.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Note: removal requests are <strong>completely anonymous</strong>: we trust your judgment when
|
|
||||||
inviting others to join the circle so we also trust you to help maintain the integrity of the
|
|
||||||
circle when flagging people for removal.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
<div class="field has-text-centered">
|
|
||||||
<button type="submit" name="intent" value="confirm" class="button is-danger">
|
|
||||||
{{if .CurrentUser.IsAdmin}}Remove{{else}}Request removal{{end}} from the inner circle
|
|
||||||
</button>
|
|
||||||
<button type="submit" name="intent" value="cancel" class="button is-warning ml-1">
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
window.addEventListener("DOMContentLoaded", (event) => {
|
|
||||||
let $file = document.querySelector("#file"),
|
|
||||||
$fileName = document.querySelector("#fileName");
|
|
||||||
|
|
||||||
$file.addEventListener("change", function() {
|
|
||||||
let file = this.files[0];
|
|
||||||
$fileName.innerHTML = file.name;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{{end}}
|
|
|
@ -142,9 +142,6 @@
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup label="Profile Status">
|
<optgroup label="Profile Status">
|
||||||
<option value="shy"{{if eq $Root.Certified "shy"}} selected{{end}}>Shy Accounts</option>
|
<option value="shy"{{if eq $Root.Certified "shy"}} selected{{end}}>Shy Accounts</option>
|
||||||
{{if .CurrentUser.IsInnerCircle}}
|
|
||||||
<option value="circle"{{if eq $Root.Certified "circle"}} selected{{end}}>Inner circle only</option>
|
|
||||||
{{end}}
|
|
||||||
<option value="admin"{{if eq $Root.Certified "admin"}} selected{{end}}>Website administrators</option>
|
<option value="admin"{{if eq $Root.Certified "admin"}} selected{{end}}>Website administrators</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
{{if .CurrentUser.HasAdminScope "admin.user.ban"}}
|
{{if .CurrentUser.HasAdminScope "admin.user.ban"}}
|
||||||
|
@ -377,9 +374,6 @@
|
||||||
{{else}}
|
{{else}}
|
||||||
{{.NameOrUsername}}
|
{{.NameOrUsername}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if and $Root.CurrentUser.IsInnerCircle .InnerCircle}}
|
|
||||||
<img src="/static/img/circle-16.png">
|
|
||||||
{{end}}
|
|
||||||
</a>
|
</a>
|
||||||
{{if eq .Visibility "private"}}
|
{{if eq .Visibility "private"}}
|
||||||
<sup class="fa fa-mask is-size-7" title="Private Profile"></sup>
|
<sup class="fa fa-mask is-size-7" title="Private Profile"></sup>
|
||||||
|
|
|
@ -201,12 +201,6 @@
|
||||||
<span class="icon"><i class="fa fa-pen-to-square"></i></span>
|
<span class="icon"><i class="fa fa-pen-to-square"></i></span>
|
||||||
<span>My User Notes</span>
|
<span>My User Notes</span>
|
||||||
</a>
|
</a>
|
||||||
{{if .CurrentUser.IsInnerCircle}}
|
|
||||||
<a class="navbar-item" href="/inner-circle">
|
|
||||||
<span class="icon"><img src="/static/img/circle-16.png"></span>
|
|
||||||
<span>Inner circle</span>
|
|
||||||
</a>
|
|
||||||
{{end}}
|
|
||||||
<a class="navbar-item" href="/settings">
|
<a class="navbar-item" href="/settings">
|
||||||
<span class="icon"><i class="fa fa-gear"></i></span>
|
<span class="icon"><i class="fa fa-gear"></i></span>
|
||||||
<span>Settings</span>
|
<span>Settings</span>
|
||||||
|
|
|
@ -419,22 +419,6 @@
|
||||||
<a href="/photo/private">granted access</a> to see your
|
<a href="/photo/private">granted access</a> to see your
|
||||||
private photos.
|
private photos.
|
||||||
</li>
|
</li>
|
||||||
{{if and .LoggedIn .CurrentUser.IsInnerCircle}}
|
|
||||||
<li>
|
|
||||||
<strong>{{PrettyCircle}}</strong>
|
|
||||||
<img src="/static/img/circle-24.png" width="16" height="16">:
|
|
||||||
your profile pic displays as a gradient
|
|
||||||
<img src="/static/img/shy-secret.png" width="16" height="16">
|
|
||||||
placeholder image for members outside the inner circle.
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<strong>Note:</strong> only {{PrettyCircle}} members see this info on the FAQ page.
|
|
||||||
Members outside the circle will see the gradient avatar, but be told that it means
|
|
||||||
"Private."
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
{{end}}
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
|
@ -128,19 +128,6 @@
|
||||||
</p>
|
</p>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if .CurrentUser.IsAdmin}}
|
|
||||||
<label class="checkbox mt-3">
|
|
||||||
<input type="checkbox"
|
|
||||||
name="inner_circle"
|
|
||||||
value="true"
|
|
||||||
{{if and .EditForum .EditForum.InnerCircle}}checked{{end}}>
|
|
||||||
Inner circle <img src="/static/img/circle-16.png" class="ml-1">
|
|
||||||
</label>
|
|
||||||
<p class="help">
|
|
||||||
This forum is only available to inner circle members.
|
|
||||||
</p>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{if .CurrentUser.IsAdmin}}
|
{{if .CurrentUser.IsAdmin}}
|
||||||
<label class="checkbox mt-3">
|
<label class="checkbox mt-3">
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
|
|
|
@ -59,13 +59,6 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
{{if .InnerCircle}}
|
|
||||||
<div class="tag is-info is-light">
|
|
||||||
<span class="icon"><img src="/static/img/circle-10.png" width="9" height="9"></span>
|
|
||||||
InnerCircle
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{if .Explicit}}
|
{{if .Explicit}}
|
||||||
<div class="tag is-danger is-light">
|
<div class="tag is-danger is-light">
|
||||||
<span class="icon"><i class="fa fa-fire"></i></span>
|
<span class="icon"><i class="fa fa-fire"></i></span>
|
||||||
|
|
|
@ -69,7 +69,6 @@
|
||||||
<div class="column is-3 pt-0 pb-1">
|
<div class="column is-3 pt-0 pb-1">
|
||||||
|
|
||||||
<h2 class="is-size-4">
|
<h2 class="is-size-4">
|
||||||
{{if .InnerCircle}}<img src="/static/img/circle-24.png" width="20" height="20" class="mr-1">{{end}}
|
|
||||||
<strong><a href="/f/{{.Fragment}}">{{.Title}}</a></strong>
|
<strong><a href="/f/{{.Fragment}}">{{.Title}}</a></strong>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
<img class="is-rounded" src="/static/img/shy-private.png">
|
<img class="is-rounded" src="/static/img/shy-private.png">
|
||||||
{{else if and (eq $User.ProfilePhoto.Visibility "friends") (not $User.UserRelationship.IsFriend)}}
|
{{else if and (eq $User.ProfilePhoto.Visibility "friends") (not $User.UserRelationship.IsFriend)}}
|
||||||
<img class="is-rounded" src="/static/img/shy-friends.png">
|
<img class="is-rounded" src="/static/img/shy-friends.png">
|
||||||
{{else if and (eq $User.ProfilePhoto.Visibility "circle") (not $User.UserRelationship.IsInnerCirclePeer)}}
|
|
||||||
<img class="is-rounded" src="/static/img/shy-secret.png">
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<img class="is-rounded" src="{{PhotoURL $User.ProfilePhoto.CroppedFilename}}">
|
<img class="is-rounded" src="{{PhotoURL $User.ProfilePhoto.CroppedFilename}}">
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
<img src="/static/img/shy-private.png" class="is-rounded">
|
<img src="/static/img/shy-private.png" class="is-rounded">
|
||||||
{{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend)}}
|
{{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend)}}
|
||||||
<img src="/static/img/shy-friends.png" class="is-rounded">
|
<img src="/static/img/shy-friends.png" class="is-rounded">
|
||||||
{{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer)}}
|
|
||||||
<img src="/static/img/shy-secret.png">
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<img src="{{PhotoURL .ProfilePhoto.CroppedFilename}}" class="is-rounded">
|
<img src="{{PhotoURL .ProfilePhoto.CroppedFilename}}" class="is-rounded">
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -30,8 +28,6 @@
|
||||||
<img src="/static/img/shy-private.png">
|
<img src="/static/img/shy-private.png">
|
||||||
{{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend)}}
|
{{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend)}}
|
||||||
<img src="/static/img/shy-friends.png">
|
<img src="/static/img/shy-friends.png">
|
||||||
{{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer)}}
|
|
||||||
<img src="/static/img/shy-secret.png">
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<img src="{{PhotoURL .ProfilePhoto.CroppedFilename}}">
|
<img src="{{PhotoURL .ProfilePhoto.CroppedFilename}}">
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -51,8 +47,6 @@
|
||||||
<img src="/static/img/shy-private.png">
|
<img src="/static/img/shy-private.png">
|
||||||
{{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend)}}
|
{{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend)}}
|
||||||
<img src="/static/img/shy-friends.png">
|
<img src="/static/img/shy-friends.png">
|
||||||
{{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer)}}
|
|
||||||
<img src="/static/img/shy-secret.png">
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<img src="{{PhotoURL .ProfilePhoto.CroppedFilename}}">
|
<img src="{{PhotoURL .ProfilePhoto.CroppedFilename}}">
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -72,8 +66,6 @@
|
||||||
<img src="/static/img/shy-private.png">
|
<img src="/static/img/shy-private.png">
|
||||||
{{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend)}}
|
{{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend)}}
|
||||||
<img src="/static/img/shy-friends.png">
|
<img src="/static/img/shy-friends.png">
|
||||||
{{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer)}}
|
|
||||||
<img src="/static/img/shy-secret.png">
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<img src="{{PhotoURL .ProfilePhoto.CroppedFilename}}">
|
<img src="{{PhotoURL .ProfilePhoto.CroppedFilename}}">
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -93,8 +85,6 @@
|
||||||
<img class="is-rounded" src="/static/img/shy-private.png">
|
<img class="is-rounded" src="/static/img/shy-private.png">
|
||||||
{{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend)}}
|
{{else if and (eq .ProfilePhoto.Visibility "friends") (not .UserRelationship.IsFriend)}}
|
||||||
<img class="is-rounded" src="/static/img/shy-friends.png">
|
<img class="is-rounded" src="/static/img/shy-friends.png">
|
||||||
{{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer)}}
|
|
||||||
<img src="/static/img/shy-secret.png">
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<img class="is-rounded" src="{{PhotoURL .ProfilePhoto.CroppedFilename}}">
|
<img class="is-rounded" src="{{PhotoURL .ProfilePhoto.CroppedFilename}}">
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -40,30 +40,6 @@
|
||||||
<div class="block">
|
<div class="block">
|
||||||
Are you sure you want to delete this photo?
|
Are you sure you want to delete this photo?
|
||||||
</div>
|
</div>
|
||||||
{{if .InnerCircleWarning}}
|
|
||||||
<div class="notification has-background-danger-light">
|
|
||||||
<strong class="has-text-danger">
|
|
||||||
<i class="fa fa-exclamation-triangle mr-1"></i>
|
|
||||||
Important
|
|
||||||
{{PrettyCircle}}
|
|
||||||
<img src="/static/img/circle-10.png" alt="Inner circle icon">
|
|
||||||
Information
|
|
||||||
</strong>
|
|
||||||
|
|
||||||
<div class="mt-2">
|
|
||||||
When you delete this photo, your count of <strong>public</strong> photos will drop below 5 (five)
|
|
||||||
and you will be immediately <strong>removed from the inner circle.</strong>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-2">
|
|
||||||
If you wish to avoid this, please upload a new <strong>public</strong> photo
|
|
||||||
before deleting this one. {{PrettyCircle}} members are expected to maintain at
|
|
||||||
least 5 nudes with face on their public gallery — it's what qualified you
|
|
||||||
to be invited to the inner circle in the first place!
|
|
||||||
<a href="/inner-circle" target="_blank">Learn more <i class="fa fa-external-link"></i></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
<div class="block has-text-center">
|
<div class="block has-text-center">
|
||||||
<button type="submit" class="button is-danger">Delete Photo</button>
|
<button type="submit" class="button is-danger">Delete Photo</button>
|
||||||
<button type="button" class="button" onclick="history.back()">Cancel</button>
|
<button type="button" class="button" onclick="history.back()">Cancel</button>
|
||||||
|
|
|
@ -47,15 +47,6 @@
|
||||||
Friends
|
Friends
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
{{else if eq .Visibility "circle"}}
|
|
||||||
<span class="tag is-info is-light">
|
|
||||||
<span class="icon">
|
|
||||||
<img src="/static/img/circle-10.png" width="9" height="9">
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
{{PrettyCircle}}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<span class="tag is-private is-light">
|
<span class="tag is-private is-light">
|
||||||
<span class="icon"><i class="fa fa-lock"></i></span>
|
<span class="icon"><i class="fa fa-lock"></i></span>
|
||||||
|
@ -217,9 +208,6 @@
|
||||||
{{if eq .ProfilePictureHiddenVisibility "friends"}}
|
{{if eq .ProfilePictureHiddenVisibility "friends"}}
|
||||||
<img src="/static/img/shy-friends.png" width="16" height="16">
|
<img src="/static/img/shy-friends.png" width="16" height="16">
|
||||||
<strong class="has-text-warning">Friends only</strong>
|
<strong class="has-text-warning">Friends only</strong>
|
||||||
{{else if eq .ProfilePictureHiddenVisibility "circle"}}
|
|
||||||
<img src="/static/img/shy-secret.png" width="16" height="16">
|
|
||||||
<strong class="has-text-private">Private</strong>
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<img src="/static/img/shy-private.png" width="16" height="16">
|
<img src="/static/img/shy-private.png" width="16" height="16">
|
||||||
<strong class="has-text-private">Private</strong>
|
<strong class="has-text-private">Private</strong>
|
||||||
|
@ -229,31 +217,6 @@
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<!-- Inner circle invite notice -->
|
|
||||||
{{if .InnerCircleInviteView}}
|
|
||||||
<div class="notification is-info is-light content">
|
|
||||||
<p>
|
|
||||||
<img src="/static/img/circle-24.png" width="16" height="16">
|
|
||||||
<strong class="ml-2">{{PrettyCircle}} invitation</strong>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
You are now viewing @{{.User.Username}}'s <strong>Public gallery photos</strong> to verify
|
|
||||||
they should be invited to the {{PrettyCircle}}.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Please take a look and see if they have at least <strong>five (5) photos</strong> that clearly show
|
|
||||||
their <strong>face</strong> as well as their full nude body together.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If they qualify to join the {{PrettyCircle}}, the button to invite them will be at
|
|
||||||
<strong>the bottom of this page</strong>.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<div class="level mb-2">
|
<div class="level mb-2">
|
||||||
<div class="level-left">
|
<div class="level-left">
|
||||||
|
@ -426,9 +389,6 @@
|
||||||
<select id="visibility" name="visibility">
|
<select id="visibility" name="visibility">
|
||||||
<option value="">All photos</option>
|
<option value="">All photos</option>
|
||||||
<option value="public"{{if eq .FilterVisibility "public"}} selected{{end}}>Public only</option>
|
<option value="public"{{if eq .FilterVisibility "public"}} selected{{end}}>Public only</option>
|
||||||
{{if .CurrentUser.IsInnerCircle}}
|
|
||||||
<option value="circle"{{if eq .FilterVisibility "circle"}} selected{{end}}>Inner circle only</option>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
<!-- Friends & Private: always show on Site Gallery, show if available on User Gallery -->
|
<!-- Friends & Private: always show on Site Gallery, show if available on User Gallery -->
|
||||||
{{if or .IsSiteGallery .AreFriends .IsOwnPhotos}}
|
{{if or .IsSiteGallery .AreFriends .IsOwnPhotos}}
|
||||||
|
@ -519,26 +479,6 @@
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<!-- Inner circle invitation -->
|
|
||||||
{{if and (not .IsSiteGallery) (not .InnerCircleOptOut)}}
|
|
||||||
{{if and (.CurrentUser.IsInnerCircle) (not .User.InnerCircle) (ne .CurrentUser.Username .User.Username) (ge .PublicPhotoCount .InnerCircleMinimumPublicPhotos)}}
|
|
||||||
<div class="block mt-0">
|
|
||||||
<span class="icon"><img src="/static/img/circle-16.png"></span>
|
|
||||||
Does <strong>{{.User.Username}}</strong> show a lot of nudity? Consider
|
|
||||||
<a href="/inner-circle/invite?to={{.User.Username}}">inviting them to join the {{PrettyCircle}}</a>.
|
|
||||||
</div>
|
|
||||||
{{else if (and .CurrentUser.IsInnerCircle .User.IsInnerCircle)}}
|
|
||||||
<div class="block mt-0">
|
|
||||||
<span class="icon"><img src="/static/img/circle-16.png"></span>
|
|
||||||
<strong>{{.User.Username}}</strong> is a part of the {{PrettyCircle}}.
|
|
||||||
Do they <a href="/inner-circle#qualify">still qualify</a> to be in the circle?
|
|
||||||
<a href="/inner-circle/remove?to={{.User.Username}}" class="has-text-danger">
|
|
||||||
<ins>Request removal</ins>
|
|
||||||
</a> if they do not.
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{SimplePager .Pager}}
|
{{SimplePager .Pager}}
|
||||||
|
|
||||||
<!-- "Full" view style? (blog style) -->
|
<!-- "Full" view style? (blog style) -->
|
||||||
|
@ -567,8 +507,6 @@
|
||||||
<i class="fa fa-user-group has-text-warning" title="Friends"></i>
|
<i class="fa fa-user-group has-text-warning" title="Friends"></i>
|
||||||
{{else if eq .Visibility "private"}}
|
{{else if eq .Visibility "private"}}
|
||||||
<i class="fa fa-lock has-text-private-light" title="Private"></i>
|
<i class="fa fa-lock has-text-private-light" title="Private"></i>
|
||||||
{{else if eq .Visibility "circle"}}
|
|
||||||
<img src="/static/img/circle-16.png">
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<i class="fa fa-eye has-text-link-light" title="Public"></i>
|
<i class="fa fa-eye has-text-link-light" title="Public"></i>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -702,8 +640,6 @@
|
||||||
<i class="fa fa-user-group has-text-warning" title="Friends"></i>
|
<i class="fa fa-user-group has-text-warning" title="Friends"></i>
|
||||||
{{else if eq .Visibility "private"}}
|
{{else if eq .Visibility "private"}}
|
||||||
<i class="fa fa-lock has-text-private-light" title="Private"></i>
|
<i class="fa fa-lock has-text-private-light" title="Private"></i>
|
||||||
{{else if eq .Visibility "circle"}}
|
|
||||||
<img src="/static/img/circle-16.png">
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<i class="fa fa-eye has-text-link-light" title="Public"></i>
|
<i class="fa fa-eye has-text-link-light" title="Public"></i>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -814,34 +750,6 @@
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<!-- Inner circle invite notice -->
|
|
||||||
{{if .InnerCircleInviteView}}
|
|
||||||
<div class="notification is-info is-light content">
|
|
||||||
<p>
|
|
||||||
<img src="/static/img/circle-24.png" width="16" height="16">
|
|
||||||
<strong class="ml-2">{{PrettyCircle}} invitation</strong>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If <strong>@{{.User.Username}}</strong> shows at least 5 nude photos <strong>with face</strong>
|
|
||||||
on their public gallery, click on the button below to add them to the {{PrettyCircle}}.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<form action="/inner-circle/invite" method="POST">
|
|
||||||
{{InputCSRF}}
|
|
||||||
<input type="hidden" name="to" value="{{.User.Username}}">
|
|
||||||
|
|
||||||
<button type="submit" name="intent" value="confirm" class="button is-link">
|
|
||||||
Add to the inner circle
|
|
||||||
</button>
|
|
||||||
<button type="submit" name="intent" value="cancel" class="button is-warning ml-1">
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -298,27 +298,6 @@
|
||||||
Gallery if that option is enabled, below.
|
Gallery if that option is enabled, below.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{{if .CurrentUser.IsInnerCircle}}
|
|
||||||
<div>
|
|
||||||
<label class="radio">
|
|
||||||
<input type="radio"
|
|
||||||
name="visibility"
|
|
||||||
value="circle"
|
|
||||||
{{if eq .EditPhoto.Visibility "circle"}}checked{{end}}>
|
|
||||||
<strong class="has-text-link ml-1">
|
|
||||||
<span>{{PrettyCircle}}</span>
|
|
||||||
<span class="icon">
|
|
||||||
<img src="/static/img/circle-16.png">
|
|
||||||
</span>
|
|
||||||
</strong>
|
|
||||||
</label>
|
|
||||||
<p class="help">
|
|
||||||
Only members of the <a href="/inner-circle">inner circle</a> will see this photo. This is
|
|
||||||
like the "Public" visibility except only people in the inner circle will see it on your
|
|
||||||
profile page or on the Site Gallery (if that option is enabled, below).
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
<div>
|
<div>
|
||||||
<label class="radio">
|
<label class="radio">
|
||||||
<input type="radio"
|
<input type="radio"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user