Nossa solução para turbidação de conteúdo NSFW

No fórum da Blender Artists, temos uma política de conteúdo bastante liberal, onde permitimos nudez e violência (até certo ponto). Embora a maioria dos membros esteja confortável com esse tipo de conteúdo, existem, claro, públicos e situações onde isso não é adequado (principalmente escolas e crianças). E como fazemos uso intensivo de galerias em mosaico com o plugin Topic List Preview, precisávamos de uma maneira de tornar esse tipo de conteúdo opt-in e mantê-lo fora da vista por padrão.

A solução foi mais fácil de implementar do que o esperado, e decidi compartilhá-la aqui caso alguém mais possa utilizá-la. Aviso justo: vou vincular a alguns conteúdos NSFW aqui. Vamos lá!

Já exigíamos uma tag #nsfw para qualquer post relevante e temos aplicado isso rigorosamente nos últimos meses. Nosso plugin AdSense está configurado para não exibir anúncios nessas páginas, pois isso (e já aconteceu!) nos colocaria em problemas com o Google. (Muito obrigado ao @neil por adicionar esse recurso!)

Usando algum CSS, adicionamos um desfoque e um texto de sobreposição para todas as mídias dentro desses tópicos. O desfoque será removido ao passar o mouse:

/* exibe desfoque NSFW e texto de sobreposição em qualquer mídia em tópicos #nsfw */
.tag-nsfw { 
	.topic-body .cooked img, 
	.topic-body .cooked iframe, 
	.topic-body .cooked .lazyYT-container, 
	.topic-thumbnail img {
        filter: blur(10px);	
        -webkit-transition: .3s ease-in-out;
        transition: .2s ease-in-out;
	}

	.topic-body:hover .cooked img, 
	.topic-body:hover .cooked iframe,
	.topic-body:hover .cooked .lazyYT-container, 			
	.topic-thumbnail:hover img {
        filter: blur(0);	
        -webkit-transition: .3s ease-in-out;
        transition: .2s ease-in-out;
	}

	.topic-body .cooked a.lightbox:before, 
	.topic-body .cooked iframe:before,
	.topic-thumbnail a:before {
	    z-index:2;
        padding: 5px;
        font-size:1em;
        position:absolute;

        color:#fff;
        content: '⚠️ Conteúdo maduro - Passe o mouse para mostrar';
        background: #e86800;

	}
	
	.topic-body .cooked a.lightbox:before, 
	.topic-body .cooked iframe:before {
        top: 15px;
        left: 10px;
	}

	.topic-thumbnail a:before {
        top: 65px;
        left: 20px;
	}
	
	.topic-body .cooked a.lightbox:hover:before, 
	.topic-body .cooked iframe:hover:before,
	.topic-thumbnail a:hover:before {		
	    display:none;
	}
}

Imagens e vídeos em um tópicos agora aparecem assim:

E em qualquer galeria em mosaico do TLP, temos:

Em seguida, adicionamos uma preferência que permite aos usuários desativar o desfoque para suas contas. Isso acabou sendo mais fácil de implementar do que eu pensava, usando campos personalizados.

Começamos criando um campo personalizado de caixa de seleção:

Depois, reaproveitamos algum código para adicionar a tag ‘nsfw-always-show’ à classe do corpo para esses usuários:

<!-- adiciona as preferências NSFW do usuário atual à tag body -->
<script type="text/discourse-plugin" version="0.8">

// https://meta.discourse.org/t/css-classes-for-group-membership-for-simplified-ui-mode/60838/2
if (window.jQuery) {
    window.jQuery(function ($) {
        var u = Discourse.User.current();

        // sempre mostrar NSFW
        if (u.custom_fields.user_field_2) {
            console.log('mostrar nsfw para o usuário');
            $('body').addClass('nsfw-always-show' );
        }

    });
};

</script>

Um último trecho de CSS remove o desfoque para esses usuários:

/* esconde campos personalizados do formulário de cadastro */

.login-form .user-fields {display:none;}

/* desativa o desfoque NSFW para usuários que definiram isso em suas preferências */

.nsfw-always-show .tag-nsfw {
	.topic-body .cooked img, 
	.topic-body .cooked iframe, 
	.topic-body .cooked .lazyYT-container, 
	.topic-thumbnail img {
        filter: blur(0px);	
	}
	
	.topic-body .cooked a.lightbox:before, 
	.topic-body .cooked iframe:before,
	.topic-thumbnail a:before {
	    display:none;
	    content: none;
	}
}

Um problema conhecido com essa abordagem é que ela ainda não funciona bem em dispositivos móveis, pois :hover não é suportado.

Se você quiser ver isso em ação, pode visitar nossa página da tag #nsfw, mas, bem, você pode ver algum conteúdo NSFW lá :slight_smile:

Espero que isso tenha sido útil para alguém!

55 curtidas

Also, on desktop, if an image take some space on the screen, you can easily hover it by mistake.
Instead of hovering to unblur, what about dynamically add a button “show the nsfw image” on top or under each nsfw image ?

4 curtidas

At krita-artists.org We have slightly modified this to be on click and not on hover. However the setting used in the profile doesn’t work. Even if the user has set to show nsfw content he gets the blurred content. Is there a fix for it?

I can’t edit my OP anymore, but here’s the updated code. Mind sharing your ‘on click’ solution too?

<!-- add current user's nsfw preferences to body tag -->
<script type="text/discourse-plugin" version="0.8.7">

// https://meta.discourse.org/t/css-classes-for-group-membership-for-simplified-ui-mode/60838/2
if (window.jQuery) {
    window.jQuery(function ($) {

        let currentUser = api.getCurrentUser();
        
        if (currentUser) {
            api.container.lookup('store:main').find('user', currentUser.username).then((user) => {

                if (user.user_fields[2]) {
                    $('body').addClass('nsfw-always-show' );
                }
            });
        }
    });
};
</script>
2 curtidas

Our onlick solution is hacky and I think may not be ideal, we just removed blur from hover and added blur by default. The message was also changed to say user has click to go the post. Now the user has to click to go to post and click again to reveal the nsfw image in lightbox. Which is cumbersome but it prevents inadvertent hover and reveal. It might be good to use js to remove blur on click.

/* display nsfw blur and overlay text on any media in #nswf topics */
.tag-nsfw { 
.topic-thumbnail {
    overflow:hidden;
}

	.topic-body .cooked .lightbox img, 
	.topic-body .cooked iframe, 
	.topic-body .cooked .lazyYT-container, 
	.topic-thumbnail img {
    filter: blur(30px);	
    -webkit-transition: .3s ease-in-out;
    transition: .2s ease-in-out;
	}

	.topic-body .cooked a.lightbox:before, 
	.topic-body .cooked iframe:before,
	.topic-thumbnail a:before {
	    z-index:2;
    padding: 5px;
    font-size:1em;
    position:absolute;

    color:#fff;
    content: '⚠️ Mature content - Click to see the picture';
    background: #000;

	}
	
	.topic-body .cooked a.lightbox:before, 
	.topic-body .cooked iframe:before {
    top: 50%;
    left: 10px;
    right: 10px;
    text-align:center;
	}

	.topic-thumbnail a:before {
    top: 65px;
    left: 20px;
	}
	
}

/* hide custom fields from signup form */
.login-form .user-fields {display:none;}

/* disable nsfw blurring for users who set this in their preferences */
.nsfw-always-show .tag-nsfw {
	.topic-body .cooked img, 
	.topic-body .cooked iframe, 
	.topic-body .cooked .lazyYT-container, 
	.topic-thumbnail img {
    filter: blur(0px);	
	}
	
	.topic-body .cooked a.lightbox:before, 
	.topic-body .cooked iframe:before,
	.topic-thumbnail a:before {
	    display:none;
	    content: none;
	}
}

@bartv @Terrapop

If someone wants to take this on, its possible to use Discourse Image Filter - plugin - Discourse Meta to build a auto nsfw blurring plugin.

4 curtidas

Hi there, what would I have to do to remove the blur and instead make the text be hyperlinked as we want to have it link to a donation off-site.

1 curtida

You can’t do that with CSS only I’m afraid; you’ll have to add your own code to do that.

2 curtidas

Just remove the filter: blur(10px); lines from the CSS.

5 curtidas

@bartv I’ve made the first post wiki, please feel free to update it as needed! :pray:

10 curtidas