Public Avatar Consent Page
The nonshy website is changing the policy on profile pictures. From August 30, the square cropped avatar images will need to be publicly viewable to everyone. This implements the first pass of the rollout: * Add the Public Avatar Consent Page which explains the change to users and asks for their acknowledgement. The link is available from their User Settings page, near their Certification Photo link. * When users (with non-public avatars) accept the change: their square cropped avatar will become visible to everybody, instead of showing a placeholder avatar. * Users can change their mind and opt back out, which will again show the placeholder avatar. * The Certification Required middleware will automatically enforce the consent page once the scheduled go-live date arrives. Next steps are: 1. Post an announcement on the forum about the upcoming change and link users to the consent form if they want to check it out early. 2. Update the nonshy site to add banners to places like the User Dashboard for users who will be affected by the change, to link them to the forum post and the consent page.
This commit is contained in:
parent
a82e04b2f8
commit
4f04323d5a
|
@ -118,6 +118,15 @@ const (
|
|||
SiteGalleryRateLimitInterval = 24 * time.Hour
|
||||
)
|
||||
|
||||
// Profile photo "public square cropped version" migration controls.
|
||||
// Previously: a Private or Friends-only profile picture would show a placeholder avatar to users
|
||||
// who couldn't see the full size version. In migration, these square cropped images will move to
|
||||
// be always public (the full-size versions can remain private).
|
||||
// NOTE: search code base for PublicAvatar or "public avatar" for related feature code.
|
||||
var (
|
||||
PublicAvatarEnforcementDate = time.Date(2024, time.August, 30, 12, 0, 0, 0, time.UTC)
|
||||
)
|
||||
|
||||
// Forum settings
|
||||
const (
|
||||
// Only ++ the Views count per user per thread within a small
|
||||
|
|
|
@ -78,7 +78,8 @@ var (
|
|||
SitePreferenceFields = []string{
|
||||
"dm_privacy",
|
||||
"blur_explicit",
|
||||
"site_gallery_default", // default view on site gallery (friends-only or all certified?)
|
||||
"site_gallery_default", // default view on site gallery (friends-only or all certified?)
|
||||
"public_avatar_consent", // Public Avatars consent agreement
|
||||
}
|
||||
|
||||
// Choices for the Contact Us subject
|
||||
|
|
55
pkg/controller/account/public_avatar_consent.go
Normal file
55
pkg/controller/account/public_avatar_consent.go
Normal file
|
@ -0,0 +1,55 @@
|
|||
package account
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"code.nonshy.com/nonshy/website/pkg/session"
|
||||
"code.nonshy.com/nonshy/website/pkg/templates"
|
||||
)
|
||||
|
||||
// Public avatar consent page (/settings/public-avatar-consent)
|
||||
func PublicAvatarConsent() http.HandlerFunc {
|
||||
tmpl := templates.Must("account/public_avatar_consent.html")
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var next = r.FormValue("next")
|
||||
if !strings.HasPrefix(next, "/") {
|
||||
next = "/me"
|
||||
}
|
||||
vars := map[string]interface{}{
|
||||
"NextURL": next,
|
||||
}
|
||||
|
||||
// Load the current user in case of updates.
|
||||
currentUser, err := session.CurrentUser(r)
|
||||
if err != nil {
|
||||
session.FlashError(w, r, "Couldn't get CurrentUser: %s", err)
|
||||
templates.Redirect(w, r.URL.Path)
|
||||
return
|
||||
}
|
||||
|
||||
// Are we POSTing?
|
||||
if r.Method == http.MethodPost {
|
||||
var (
|
||||
accept = r.PostFormValue("accept")
|
||||
)
|
||||
|
||||
currentUser.SetProfileField("public_avatar_consent", accept)
|
||||
|
||||
if accept == "true" {
|
||||
session.Flash(w, r, "Thank you for agreeing to the Public Avatar policy! You may revisit this option from your Account Settings page in the future.")
|
||||
templates.Redirect(w, next)
|
||||
return
|
||||
}
|
||||
|
||||
session.Flash(w, r, "We have noted your non-consent to this change. Your avatar image (if non-public) will show as a placeholder avatar to people who don't have permission to see the full-size photo.")
|
||||
templates.Redirect(w, r.URL.Path)
|
||||
return
|
||||
}
|
||||
|
||||
if err := tmpl.Execute(w, r, vars); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
|
@ -99,13 +99,15 @@ func Landing() http.HandlerFunc {
|
|||
|
||||
// Avatar URL - masked if non-public.
|
||||
avatar := photo.URLPath(currentUser.ProfilePhoto.CroppedFilename)
|
||||
switch currentUser.ProfilePhoto.Visibility {
|
||||
case models.PhotoPrivate:
|
||||
avatar = "/static/img/shy-private.png"
|
||||
case models.PhotoFriends:
|
||||
avatar = "/static/img/shy-friends.png"
|
||||
case models.PhotoInnerCircle:
|
||||
avatar = "/static/img/shy-secret.png"
|
||||
if currentUser.GetProfileField("public_avatar_consent") != "true" {
|
||||
switch currentUser.ProfilePhoto.Visibility {
|
||||
case models.PhotoPrivate:
|
||||
avatar = "/static/img/shy-private.png"
|
||||
case models.PhotoFriends:
|
||||
avatar = "/static/img/shy-friends.png"
|
||||
case models.PhotoInnerCircle:
|
||||
avatar = "/static/img/shy-secret.png"
|
||||
}
|
||||
}
|
||||
|
||||
// Country flag emoji.
|
||||
|
|
|
@ -157,6 +157,11 @@ func CertRequired(handler http.Handler) http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
// Public Avatar consent enforcement?
|
||||
if PublicAvatarConsent(currentUser, w, r) {
|
||||
return
|
||||
}
|
||||
|
||||
handler.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
|
31
pkg/middleware/public_avatar_consent.go
Normal file
31
pkg/middleware/public_avatar_consent.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"code.nonshy.com/nonshy/website/pkg/config"
|
||||
"code.nonshy.com/nonshy/website/pkg/models"
|
||||
"code.nonshy.com/nonshy/website/pkg/templates"
|
||||
)
|
||||
|
||||
// PublicAvatarConsent: part of CertificationRequired that enforces the consent page for affected users.
|
||||
func PublicAvatarConsent(user *models.User, w http.ResponseWriter, r *http.Request) (handled bool) {
|
||||
// Is the enforcement date live?
|
||||
if time.Now().Before(config.PublicAvatarEnforcementDate) {
|
||||
return
|
||||
}
|
||||
|
||||
// If the current user has a non-public avatar and has not consented.
|
||||
if user.ProfilePhoto.ID > 0 && user.ProfilePhoto.Visibility != models.PhotoPublic {
|
||||
if user.GetProfileField("public_avatar_consent") == "true" {
|
||||
return
|
||||
}
|
||||
|
||||
templates.Redirect(w, "/settings/public-avatar-consent?next="+url.QueryEscape(r.URL.String()))
|
||||
return true
|
||||
}
|
||||
|
||||
return
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package models
|
||||
|
||||
// Supplementary functions to do with Shy Accounts.
|
||||
// Supplementary functions to do with Shy Accounts and PublicAvatar consent.
|
||||
|
||||
import "code.nonshy.com/nonshy/website/pkg/log"
|
||||
|
||||
|
@ -96,3 +96,38 @@ func MapShyAccounts(users []*User) ShyMap {
|
|||
func (um ShyMap) Get(id uint64) bool {
|
||||
return um[id]
|
||||
}
|
||||
|
||||
// MapPublicAvatarConsent checks a set of users if they have answered the public avatar consent form.
|
||||
func MapPublicAvatarConsent(users []*User) (map[uint64]bool, error) {
|
||||
var (
|
||||
userIDs = []uint64{}
|
||||
result = map[uint64]bool{}
|
||||
)
|
||||
for _, user := range users {
|
||||
userIDs = append(userIDs, user.ID)
|
||||
result[user.ID] = false
|
||||
}
|
||||
|
||||
type record struct {
|
||||
UserID uint64
|
||||
Value string
|
||||
}
|
||||
var rows = []record{}
|
||||
|
||||
if res := DB.Table(
|
||||
"profile_fields",
|
||||
).Select(
|
||||
"user_id, value",
|
||||
).Where(
|
||||
"user_id IN ? AND name='public_avatar_consent'",
|
||||
userIDs,
|
||||
).Scan(&rows); res.Error != nil {
|
||||
return nil, res.Error
|
||||
}
|
||||
|
||||
for _, row := range rows {
|
||||
result[row.UserID] = row.Value == "true"
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
@ -637,8 +637,12 @@ func (u *User) NameOrUsername() string {
|
|||
//
|
||||
// Expects that UserRelationships are available on the user.
|
||||
func (u *User) VisibleAvatarURL(currentUser *User) string {
|
||||
// Can the viewer see the picture based on its visibility setting?
|
||||
canSee, visibility := u.CanSeeProfilePicture(currentUser)
|
||||
if canSee {
|
||||
|
||||
// Or has the owner consented on the Public Avatar policy?
|
||||
consent := u.GetProfileField("public_avatar_consent") == "true"
|
||||
if canSee || consent {
|
||||
return config.PhotoWebPath + "/" + u.ProfilePhoto.CroppedFilename
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
package models
|
||||
|
||||
import "code.nonshy.com/nonshy/website/pkg/log"
|
||||
|
||||
// UserRelationship fields - how a target User relates to the CurrentUser, especially
|
||||
// with regards to whether the User's friends-only or private profile picture should show.
|
||||
// The zero-values should fail safely: in case the UserRelationship isn't populated correctly,
|
||||
// private profile pics show as private by default.
|
||||
type UserRelationship struct {
|
||||
Computed bool // check whether the SetUserRelationships function has been run
|
||||
IsFriend bool // if true, a friends-only 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
|
||||
Computed bool // check whether the SetUserRelationships function has been run
|
||||
IsFriend bool // if true, a friends-only 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
|
||||
PublicAvatarConsent bool // if true, this user answered the Public Avatar consent form
|
||||
}
|
||||
|
||||
// SetUserRelationships updates a set of User objects to populate their UserRelationships in
|
||||
|
@ -35,6 +38,12 @@ func SetUserRelationships(currentUser *User, users []*User) error {
|
|||
privateMap[id] = nil
|
||||
}
|
||||
|
||||
// Get user PublicAvatar consent maps.
|
||||
consent, err := MapPublicAvatarConsent(users)
|
||||
if err != nil {
|
||||
log.Error("MapPublicAvatarConsent: %s", err)
|
||||
}
|
||||
|
||||
// Inject the UserRelationships.
|
||||
for _, u := range users {
|
||||
u.UserRelationship.IsInnerCirclePeer = isInnerCircle
|
||||
|
@ -53,6 +62,10 @@ func SetUserRelationships(currentUser *User, users []*User) error {
|
|||
if _, ok := privateMap[u.ID]; ok {
|
||||
u.UserRelationship.IsPrivateGranted = true
|
||||
}
|
||||
|
||||
if v, ok := consent[u.ID]; ok {
|
||||
u.UserRelationship.PublicAvatarConsent = v
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ func New() http.Handler {
|
|||
mux.Handle("/me", middleware.LoginRequired(account.Dashboard()))
|
||||
mux.Handle("/settings", middleware.LoginRequired(account.Settings()))
|
||||
mux.Handle("/settings/age-gate", middleware.LoginRequired(account.AgeGate()))
|
||||
mux.Handle("/settings/public-avatar-consent", middleware.LoginRequired(account.PublicAvatarConsent()))
|
||||
mux.Handle("/account/two-factor/setup", middleware.LoginRequired(account.Setup2FA()))
|
||||
mux.Handle("/account/delete", middleware.LoginRequired(account.Delete()))
|
||||
mux.Handle("/account/deactivate", middleware.LoginRequired(account.Deactivate()))
|
||||
|
|
|
@ -23,6 +23,9 @@ func MergeVars(r *http.Request, m map[string]interface{}) {
|
|||
// Integrations
|
||||
m["TurnstileCAPTCHA"] = config.Current.Turnstile
|
||||
|
||||
// Temporary? variables for migration efforts on PublicAvatar consent.
|
||||
m["PublicAvatarEnforcementDate"] = config.PublicAvatarEnforcementDate
|
||||
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
|
|
296
web/templates/account/public_avatar_consent.html
Normal file
296
web/templates/account/public_avatar_consent.html
Normal file
|
@ -0,0 +1,296 @@
|
|||
{{define "title"}}An update about your Default Profile Picture{{end}}
|
||||
{{define "content"}}
|
||||
<div class="container">
|
||||
<section class="hero is-info is-bold">
|
||||
<div class="hero-body">
|
||||
<div class="container">
|
||||
<h1 class="title">
|
||||
An update about your Default Profile Picture
|
||||
</h1>
|
||||
<h2 class="subtitle">
|
||||
Please review the upcoming website change about our Default Profile Picture policy
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="block p-4">
|
||||
<div class="level">
|
||||
<div class="level-item">
|
||||
<div class="card" style="width: 100%; max-width: 800px">
|
||||
<header class="card-header has-background-link">
|
||||
<p class="card-header-title has-text-light">
|
||||
<i class="fa fa-image mr-2"></i>
|
||||
We are updating our Default Profile Picture policy
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
|
||||
<div class="content">
|
||||
<p>
|
||||
This page serves as a notification about an upcoming change to the {{PrettyTitle}} site
|
||||
policy around the visibility of your <strong>square cropped Default Profile Picture</strong>
|
||||
(which we will refer to as your <strong>"Avatar"</strong> for the purpose of this page).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Beginning on <strong>{{.PublicAvatarEnforcementDate.Format "January 2, 2006"}}</strong>,
|
||||
all {{PrettyTitle}} members will be required to make their Avatar (the square cropped,
|
||||
default profile picture which includes your face) visible to all members of the website.
|
||||
After {{.PublicAvatarEnforcementDate.Format "January 2"}}, you will not be permitted to
|
||||
use the chat room, forums, site gallery or other 'certification required' pages until you
|
||||
have responded to this consent form by answering the prompt at the bottom of this page.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#summary">Summary of the change</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#what">What is being changed about our Avatars?</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#fullsize">Your full-size profile picture can still remain private</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#consent">Your consent is requested for this change</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#disagree">What if I disagree with this change?</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3 id="summary">Summary of the change</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
On the {{PrettyTitle}} website, all <strong>square cropped default profile pictures</strong>
|
||||
will become visible to everybody on the site, instead of showing as a yellow or purple
|
||||
placeholder image when your full-size profile picture was set to "Friends-only" or "Private"
|
||||
visibility.
|
||||
</li>
|
||||
<li>
|
||||
The <strong>full size profile photo</strong> on your gallery can remain as "Friends-only" or
|
||||
"Private" if you want; but the square Avatar shown next to your name on most pages of the
|
||||
website will be visible to all logged-in members.
|
||||
</li>
|
||||
<li>
|
||||
The website policy that <strong>your Avatar must show your face</strong> will also be more
|
||||
strictly enforced along with this change. We want to know that <em>everybody</em> on {{PrettyTitle}}
|
||||
has a face that we can all see.
|
||||
</li>
|
||||
<li>
|
||||
<strong class="has-text-success">Your consent is required</strong> for this change. If your
|
||||
profile picture is <em>currently</em> non-public, we <strong>will not</strong> begin showing it
|
||||
to others on the website until you acknowledge and agree to this change in site policy.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3 id="what">What is being changed about our Avatars?</h3>
|
||||
|
||||
<p>
|
||||
Previously, it was possible to set your Default Profile Picture on your gallery page as
|
||||
"Private" or "Friends-only" visibility, and it would cause your <strong>square cropped Avatar</strong>
|
||||
icon to show as a placeholder image to people who were not allowed to see the full-size copy
|
||||
on your gallery.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For example, if your profile picture was set to "Friends-only" then a
|
||||
<img src="/static/img/shy-friends.png" width="16" height="16" alt=""> yellow placeholder avatar
|
||||
would be shown in its place to people who are not on your Friends list, or a
|
||||
<img src="/static/img/shy-private.png" width="16" height="16" alt=""> purple placeholder avatar
|
||||
would stand in for your "Private" profile picture to people who you did not grant access.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Going forward, the square cropped Avatar images will be moved to become
|
||||
<strong>visible to everybody</strong> who is logged-in to the website. Here
|
||||
is an example of how your profile card may look to people before, and after
|
||||
this change:
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<em class="is-size-4">
|
||||
<strong class="has-text-info">Before:</strong>
|
||||
</em>
|
||||
|
||||
<div class="media block mt-2">
|
||||
<div class="media-left">
|
||||
<figure class="image is-48x48 is-inline-block">
|
||||
{{if eq .CurrentUser.ProfilePhoto.Visibility "friends"}}
|
||||
<img src="/static/img/shy-friends.png">
|
||||
{{else if eq .CurrentUser.ProfilePhoto.Visibility "private"}}
|
||||
<img src="/static/img/shy-private.png">
|
||||
{{else if .CurrentUser.ProfilePhoto.ID}}
|
||||
<img src="{{PhotoURL .CurrentUser.ProfilePhoto.CroppedFilename}}">
|
||||
{{else}}
|
||||
<img src="/static/img/shy.png">
|
||||
{{end}}
|
||||
</figure>
|
||||
</div>
|
||||
<div class="media-content">
|
||||
<p class="title is-5">
|
||||
{{.CurrentUser.NameOrUsername}}
|
||||
</p>
|
||||
<p class="subtitle is-6">
|
||||
<span class="icon"><i class="fa fa-user"></i></span>
|
||||
{{.CurrentUser.Username}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<em class="is-size-4">
|
||||
<strong class="has-text-success">After:</strong>
|
||||
</em>
|
||||
|
||||
<div class="media block mt-2">
|
||||
<div class="media-left">
|
||||
<figure class="image is-48x48 is-inline-block">
|
||||
{{if .CurrentUser.ProfilePhoto.ID}}
|
||||
<img src="{{PhotoURL .CurrentUser.ProfilePhoto.CroppedFilename}}">
|
||||
{{else}}
|
||||
<img src="/static/img/shy.png">
|
||||
{{end}}
|
||||
</figure>
|
||||
</div>
|
||||
<div class="media-content">
|
||||
<p class="title is-5">
|
||||
{{.CurrentUser.NameOrUsername}}
|
||||
</p>
|
||||
<p class="subtitle is-6">
|
||||
<span class="icon"><i class="fa fa-user"></i></span>
|
||||
{{.CurrentUser.Username}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Already a public picture -->
|
||||
{{if and (.CurrentUser.ProfilePhoto.ID) (eq .CurrentUser.ProfilePhoto.Visibility "public")}}
|
||||
<div class="notification is-success is-light p-4">
|
||||
<strong>Notice:</strong> your default profile picture is already set to 'Public' visibility,
|
||||
so this change in site policy will not affect you.
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="content">
|
||||
<hr>
|
||||
|
||||
<h3 id="fullsize">Your full-size profile picture can still remain private</h3>
|
||||
|
||||
<p>
|
||||
This change in website policy <strong>only</strong> applies to the
|
||||
<strong>square cropped Avatar image</strong> of your profile picture -- the
|
||||
image shown on the top of your profile page and next to your name on the chat
|
||||
room, forums, and other places around the {{PrettyTitle}} website.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Your <strong>full size default profile photo</strong> can still be kept on "Friends-only"
|
||||
or "Private" visibility. So, for example: if your default profile photo is a full-body nude
|
||||
picture that includes your face, you could crop your Avatar to show only your face (visible
|
||||
to everybody) but you can leave the full-size photo on Private if you don't want everybody
|
||||
to see it.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<h3 id="consent" class="has-text-success">Your consent is requested for this change</h3>
|
||||
|
||||
<p>
|
||||
If your profile picture is currently "Private" or "Friends-only," we <strong>will not</strong>
|
||||
automatically reveal your Avatar to everybody without your consent. We know that for some of
|
||||
you, the ability to hide your face picture from other members on the site is very important.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
While the new policy will go into effect on {{.PublicAvatarEnforcementDate.Format "January 2, 2006"}},
|
||||
you may accept the updated policy early by clicking on the checkbox below.
|
||||
<strong>After {{.PublicAvatarEnforcementDate.Format "January 2"}}</strong>, if you have not yet
|
||||
accepted the new policy, you will be shown this page any time you access the "Certification Required"
|
||||
areas of the website (such as the chat room, forums, gallery and member directory). All members who
|
||||
have a non-public profile picture will need to accept this change after that date to continue using
|
||||
the website.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ .Request.URL.Path }}">
|
||||
<input type="hidden" name="next" value="{{.NextURL}}">
|
||||
{{InputCSRF}}
|
||||
|
||||
<div class="field">
|
||||
<label for="accept" class="label">Acknowledge and accept the new Public Avatar policy</label>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox"
|
||||
name="accept" id="accept"
|
||||
value="true"
|
||||
{{if eq (.CurrentUser.GetProfileField "public_avatar_consent") "true"}}checked{{end}}>
|
||||
I accept the {{PrettyTitle}} Public Avatar policy
|
||||
</label>
|
||||
<p class="help">
|
||||
After accepting this change: if your default profile picture is currently non-public, the
|
||||
square cropped avatar image will become visible for everybody.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="block has-text-centered">
|
||||
<button type="submit" class="button is-primary">Save my Public Avatar Consent setting</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<div class="content">
|
||||
<hr>
|
||||
|
||||
<h3 id="disagree" class="has-text-warning">What if I disagree with this change?</h3>
|
||||
|
||||
<p>
|
||||
After <strong>{{.PublicAvatarEnforcementDate.Format "January 2, 2006"}}</strong>, when this change
|
||||
in website policy goes live, members who have a non-public default profile picture and have
|
||||
<strong>not</strong> consented to the above update will no longer have access to the "Certification
|
||||
Required" areas of the website.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
That is: the Chat Room, Forums, Site Gallery, and Member Directory will no longer be accessible to
|
||||
you from that time. When visiting any of those areas of the website, you will be redirected to
|
||||
this consent page which you will need to agree to before you can continue using the website.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You will still have access to your Friends list, Messages, profile pages and your account settings
|
||||
so that you can make arrangements with your friends to connect on a different platform.
|
||||
If this change in site policy is simply incompatible with you, then we would ask that you
|
||||
<a href="/settings#deactivate">delete your {{PrettyTitle}} account</a>.
|
||||
</p>
|
||||
</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}}
|
|
@ -113,6 +113,15 @@
|
|||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/settings/public-avatar-consent">
|
||||
<strong><i class="fa fa-image-portrait mr-1"></i> Public Avatar Consent</strong>
|
||||
<p class="help">
|
||||
Review and acknowledge the change in default profile picture policy.
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/photo/private">
|
||||
<strong><i class="fa fa-eye mr-1"></i> Private Photos</strong>
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
<figure class="image is-24x24 is-inline-block">
|
||||
<a href="/u/{{.Username}}" class="has-text-dark">
|
||||
{{if .ProfilePhoto.ID}}
|
||||
{{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted)}}
|
||||
{{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted) (not .UserRelationship.PublicAvatarConsent)}}
|
||||
<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) (not .UserRelationship.PublicAvatarConsent)}}
|
||||
<img src="/static/img/shy-friends.png" class="is-rounded">
|
||||
{{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer)}}
|
||||
{{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer) (not .UserRelationship.PublicAvatarConsent)}}
|
||||
<img src="/static/img/shy-secret.png">
|
||||
{{else}}
|
||||
<img src="{{PhotoURL .ProfilePhoto.CroppedFilename}}" class="is-rounded">
|
||||
|
@ -26,11 +26,11 @@
|
|||
<figure class="image is-48x48 is-inline-block">
|
||||
<a href="/u/{{.Username}}" class="has-text-dark">
|
||||
{{if .ProfilePhoto.ID}}
|
||||
{{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted)}}
|
||||
{{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted) (not .UserRelationship.PublicAvatarConsent)}}
|
||||
<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) (not .UserRelationship.PublicAvatarConsent)}}
|
||||
<img src="/static/img/shy-friends.png">
|
||||
{{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer)}}
|
||||
{{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer) (not .UserRelationship.PublicAvatarConsent)}}
|
||||
<img src="/static/img/shy-secret.png">
|
||||
{{else}}
|
||||
<img src="{{PhotoURL .ProfilePhoto.CroppedFilename}}">
|
||||
|
@ -47,11 +47,11 @@
|
|||
<figure class="image is-64x64 is-inline-block">
|
||||
<a href="/u/{{.Username}}" class="has-text-dark">
|
||||
{{if .ProfilePhoto.ID}}
|
||||
{{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted)}}
|
||||
{{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted) (not .UserRelationship.PublicAvatarConsent)}}
|
||||
<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) (not .UserRelationship.PublicAvatarConsent)}}
|
||||
<img src="/static/img/shy-friends.png">
|
||||
{{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer)}}
|
||||
{{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer) (not .UserRelationship.PublicAvatarConsent)}}
|
||||
<img src="/static/img/shy-secret.png">
|
||||
{{else}}
|
||||
<img src="{{PhotoURL .ProfilePhoto.CroppedFilename}}">
|
||||
|
@ -68,11 +68,11 @@
|
|||
<figure class="image is-96x96 is-inline-block">
|
||||
<a href="/u/{{.Username}}" class="has-text-dark">
|
||||
{{if .ProfilePhoto.ID}}
|
||||
{{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted)}}
|
||||
{{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted) (not .UserRelationship.PublicAvatarConsent)}}
|
||||
<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) (not .UserRelationship.PublicAvatarConsent)}}
|
||||
<img src="/static/img/shy-friends.png">
|
||||
{{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer)}}
|
||||
{{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer) (not .UserRelationship.PublicAvatarConsent)}}
|
||||
<img src="/static/img/shy-secret.png">
|
||||
{{else}}
|
||||
<img src="{{PhotoURL .ProfilePhoto.CroppedFilename}}">
|
||||
|
@ -89,11 +89,11 @@
|
|||
<figure class="image is-32x32 is-inline-block">
|
||||
<a href="/u/{{.Username}}" class="has-text-dark">
|
||||
{{if .ProfilePhoto.ID}}
|
||||
{{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted)}}
|
||||
{{if and (eq .ProfilePhoto.Visibility "private") (not .UserRelationship.IsPrivateGranted) (not .UserRelationship.PublicAvatarConsent)}}
|
||||
<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) (not .UserRelationship.PublicAvatarConsent)}}
|
||||
<img class="is-rounded" src="/static/img/shy-friends.png">
|
||||
{{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer)}}
|
||||
{{else if and (eq .ProfilePhoto.Visibility "circle") (not .UserRelationship.IsInnerCirclePeer) (not .UserRelationship.PublicAvatarConsent)}}
|
||||
<img src="/static/img/shy-secret.png">
|
||||
{{else}}
|
||||
<img class="is-rounded" src="{{PhotoURL .ProfilePhoto.CroppedFilename}}">
|
||||
|
|
Loading…
Reference in New Issue
Block a user