Release/ArtigosPDF #21
@ -30,7 +30,11 @@
|
|||||||
"Bash(ssh:*)",
|
"Bash(ssh:*)",
|
||||||
"Bash(cat:*)",
|
"Bash(cat:*)",
|
||||||
"Bash(dig:*)",
|
"Bash(dig:*)",
|
||||||
"Bash(git commit:*)"
|
"Bash(git commit:*)",
|
||||||
|
"Bash(netstat:*)",
|
||||||
|
"Bash(ss:*)",
|
||||||
|
"Bash(lsof:*)",
|
||||||
|
"Bash(dotnet run:*)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"enableAllProjectMcpServers": false
|
"enableAllProjectMcpServers": false
|
||||||
|
|||||||
@ -535,7 +535,7 @@
|
|||||||
var twitterUrl = twitter !=null ? twitter.Url.Replace("https://x.com/","").Replace("https://twitter.com/","").Replace("https://www.twitter.com/","") : "";
|
var twitterUrl = twitter !=null ? twitter.Url.Replace("https://x.com/","").Replace("https://twitter.com/","").Replace("https://www.twitter.com/","") : "";
|
||||||
var whatsappUrl = whatsapp !=null ? whatsapp.Url.Replace("https://wa.me/","").Replace("whatsapp://","") : "";
|
var whatsappUrl = whatsapp !=null ? whatsapp.Url.Replace("https://wa.me/","").Replace("whatsapp://","") : "";
|
||||||
var instagramUrl = instagram !=null ? instagram.Url.Replace("https://instagram.com/","").Replace("https://www.instagram.com/","") : "";
|
var instagramUrl = instagram !=null ? instagram.Url.Replace("https://instagram.com/","").Replace("https://www.instagram.com/","") : "";
|
||||||
var tiktokUrl = tiktok !=null ? tiktok.Url.Replace("https://tiktok.com/@@","").Replace("https://www.tiktok.com/@@","").Replace("https://vm.tiktok.com/","") : "";
|
var tiktokUrl = tiktok !=null ? tiktok.Url.Replace("https://tiktok.com/@","").Replace("https://www.tiktok.com/@","").Replace("https://vm.tiktok.com/","") : "";
|
||||||
var pinterestUrl = pinterest !=null ? pinterest.Url.Replace("https://pinterest.com/","").Replace("https://www.pinterest.com/","").Replace("https://pin.it/","") : "";
|
var pinterestUrl = pinterest !=null ? pinterest.Url.Replace("https://pinterest.com/","").Replace("https://www.pinterest.com/","").Replace("https://pin.it/","") : "";
|
||||||
var discordUrl = discord !=null ? discord.Url.Replace("https://discord.gg/","").Replace("https://discord.com/invite/","") : "";
|
var discordUrl = discord !=null ? discord.Url.Replace("https://discord.gg/","").Replace("https://discord.com/invite/","") : "";
|
||||||
var kawaiUrl = kawai !=null ? kawai.Url.Replace("https://kawai.com/","").Replace("https://www.kawai.com/","") : "";
|
var kawaiUrl = kawai !=null ? kawai.Url.Replace("https://kawai.com/","").Replace("https://www.kawai.com/","") : "";
|
||||||
@ -573,9 +573,12 @@
|
|||||||
<i class="fab fa-whatsapp text-success me-2"></i>
|
<i class="fab fa-whatsapp text-success me-2"></i>
|
||||||
https://wa.me/
|
https://wa.me/
|
||||||
</span>
|
</span>
|
||||||
<input type="text" class="form-control" id="whatsappNumber" placeholder="5511999999999">
|
<input type="text" class="form-control" id="whatsappNumber" placeholder="11987654321">
|
||||||
</div>
|
</div>
|
||||||
<small class="form-text text-muted">Exemplo: 5511999999999 (código do país + DDD + número)</small>
|
<small class="form-text text-muted">
|
||||||
|
<strong>Brasil:</strong> Digite apenas DDD + número (ex: 11987654321). O código 55 será adicionado automaticamente.<br>
|
||||||
|
<strong>Outros países:</strong> Digite o código do país + número completo.
|
||||||
|
</small>
|
||||||
<input asp-for="WhatsAppNumber" type="hidden" value="@(whatsappUrl ?? "")">
|
<input asp-for="WhatsAppNumber" type="hidden" value="@(whatsappUrl ?? "")">
|
||||||
<span asp-validation-for="WhatsAppNumber" class="text-danger"></span>
|
<span asp-validation-for="WhatsAppNumber" class="text-danger"></span>
|
||||||
</div>
|
</div>
|
||||||
@ -1204,14 +1207,22 @@
|
|||||||
checkServerImageErrors();
|
checkServerImageErrors();
|
||||||
|
|
||||||
// Garantir que campos não marcados sejam string vazia ao submeter
|
// Garantir que campos não marcados sejam string vazia ao submeter
|
||||||
$('form').on('submit', function() {
|
$('form').on('submit', function(e) {
|
||||||
ensureUncheckedFieldsAreEmpty();
|
ensureUncheckedFieldsAreEmpty();
|
||||||
|
|
||||||
|
// Validar URLs de redes sociais antes de submeter
|
||||||
|
const validationResult = validateSocialMediaUrls();
|
||||||
|
if (!validationResult.valid) {
|
||||||
|
e.preventDefault();
|
||||||
|
alert('Erro de validação:\n\n' + validationResult.errors.join('\n'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Debug: Verificar quais campos de links estão sendo enviados
|
// Debug: Verificar quais campos de links estão sendo enviados
|
||||||
console.log('=== DEBUG FORM SUBMISSION ===');
|
console.log('=== DEBUG FORM SUBMISSION ===');
|
||||||
const formData = new FormData(this);
|
const formData = new FormData(this);
|
||||||
for (let [key, value] of formData.entries()) {
|
for (let [key, value] of formData.entries()) {
|
||||||
if (key.includes('Links[')) {
|
if (key.includes('Links[') || key.includes('Url') || key.includes('Number')) {
|
||||||
console.log(`${key}: ${value}`);
|
console.log(`${key}: ${value}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2022,6 +2033,82 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validar URLs de redes sociais antes de submeter o formulário
|
||||||
|
function validateSocialMediaUrls() {
|
||||||
|
const errors = [];
|
||||||
|
const userLang = navigator.language || navigator.userLanguage;
|
||||||
|
const isBrazil = userLang.startsWith('pt-BR') || userLang.startsWith('pt');
|
||||||
|
|
||||||
|
// Validar WhatsApp
|
||||||
|
if ($('#enableWhatsApp').is(':checked')) {
|
||||||
|
const whatsappValue = $('input[name="WhatsAppNumber"]').val().trim();
|
||||||
|
if (whatsappValue && whatsappValue !== ' ') {
|
||||||
|
const cleanNumber = whatsappValue.replace('https://wa.me/', '').replace(/\D/g, '');
|
||||||
|
|
||||||
|
if (isBrazil) {
|
||||||
|
// Brasil: deve ter 13 dígitos (55 + DDD + número)
|
||||||
|
if (cleanNumber.length !== 13 || !cleanNumber.startsWith('55')) {
|
||||||
|
errors.push('⚠️ WhatsApp: Número brasileiro deve ter 13 dígitos (55 + DDD + número).\nExemplo: 5511987654321');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Outros países: validar entre 10 e 15 dígitos
|
||||||
|
if (cleanNumber.length < 10 || cleanNumber.length > 15) {
|
||||||
|
errors.push('⚠️ WhatsApp: Número deve ter entre 10 e 15 dígitos (incluindo código do país).');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validar Facebook
|
||||||
|
if ($('#enableFacebook').is(':checked')) {
|
||||||
|
const facebookValue = $('input[name="FacebookUrl"]').val().trim();
|
||||||
|
if (facebookValue && facebookValue !== ' ') {
|
||||||
|
const cleanUrl = facebookValue.replace('https://facebook.com/', '').replace('https://www.facebook.com/', '');
|
||||||
|
if (cleanUrl.length < 3) {
|
||||||
|
errors.push('⚠️ Facebook: Nome de usuário deve ter pelo menos 3 caracteres.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validar Instagram
|
||||||
|
if ($('#enableInstagram').is(':checked')) {
|
||||||
|
const instagramValue = $('input[name="InstagramUrl"]').val().trim();
|
||||||
|
if (instagramValue && instagramValue !== ' ') {
|
||||||
|
const cleanUrl = instagramValue.replace('https://instagram.com/', '').replace('https://www.instagram.com/', '');
|
||||||
|
if (cleanUrl.length < 3) {
|
||||||
|
errors.push('⚠️ Instagram: Nome de usuário deve ter pelo menos 3 caracteres.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validar Twitter
|
||||||
|
if ($('#enableTwitter').is(':checked')) {
|
||||||
|
const twitterValue = $('input[name="TwitterUrl"]').val().trim();
|
||||||
|
if (twitterValue && twitterValue !== ' ') {
|
||||||
|
const cleanUrl = twitterValue.replace('https://x.com/', '').replace('https://twitter.com/', '');
|
||||||
|
if (cleanUrl.length < 3) {
|
||||||
|
errors.push('⚠️ Twitter/X: Nome de usuário deve ter pelo menos 3 caracteres.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validar TikTok
|
||||||
|
if ($('#enableTiktok').is(':checked')) {
|
||||||
|
const tiktokValue = $('input[name="TiktokUrl"]').val().trim();
|
||||||
|
if (tiktokValue && tiktokValue !== ' ') {
|
||||||
|
const cleanUrl = tiktokValue.replace('https://tiktok.com/@@', '').replace('https://www.tiktok.com/@@', '');
|
||||||
|
if (cleanUrl.length < 3) {
|
||||||
|
errors.push('⚠️ TikTok: Nome de usuário deve ter pelo menos 3 caracteres.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
valid: errors.length === 0,
|
||||||
|
errors: errors
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Social Media Functions
|
// Social Media Functions
|
||||||
function cleanSocialPrefix(value, socialType) {
|
function cleanSocialPrefix(value, socialType) {
|
||||||
const prefixes = {
|
const prefixes = {
|
||||||
@ -2039,10 +2126,16 @@
|
|||||||
|
|
||||||
for (let prefix of typePrefixes) {
|
for (let prefix of typePrefixes) {
|
||||||
if (value.startsWith(prefix)) {
|
if (value.startsWith(prefix)) {
|
||||||
return value.replace(prefix, '');
|
value = value.replace(prefix, '');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TikTok: remover @@ do início (o prefixo já tem @@)
|
||||||
|
if (socialType === 'Tiktok' && value.startsWith('@@')) {
|
||||||
|
value = value.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2124,6 +2217,16 @@
|
|||||||
if (isWhatsApp) {
|
if (isWhatsApp) {
|
||||||
// WhatsApp: apenas números
|
// WhatsApp: apenas números
|
||||||
value = value.replace(/\D/g, '');
|
value = value.replace(/\D/g, '');
|
||||||
|
|
||||||
|
// Auto-adicionar código +55 para números brasileiros (11 dígitos sem código país)
|
||||||
|
// Detecta cultura pt-BR para aplicar validação BR
|
||||||
|
const userLang = navigator.language || navigator.userLanguage;
|
||||||
|
const isBrazil = userLang.startsWith('pt-BR') || userLang.startsWith('pt');
|
||||||
|
|
||||||
|
if (isBrazil && value.length === 11 && !value.startsWith('55')) {
|
||||||
|
value = '55' + value;
|
||||||
|
}
|
||||||
|
|
||||||
$(this).val(value);
|
$(this).val(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2146,11 +2249,25 @@
|
|||||||
if (!value) return;
|
if (!value) return;
|
||||||
|
|
||||||
if (isWhatsApp) {
|
if (isWhatsApp) {
|
||||||
// Validar WhatsApp (mínimo 10 dígitos)
|
// Validar WhatsApp com detecção de idioma
|
||||||
if (value.length >= 10) {
|
const userLang = navigator.language || navigator.userLanguage;
|
||||||
input.addClass('is-valid');
|
const isBrazil = userLang.startsWith('pt-BR') || userLang.startsWith('pt');
|
||||||
|
|
||||||
|
if (isBrazil) {
|
||||||
|
// Brasil: validar 13 dígitos (55 + DDD + número)
|
||||||
|
if (value.length === 13 && value.startsWith('55')) {
|
||||||
|
input.addClass('is-valid');
|
||||||
|
} else if (value.length >= 10) {
|
||||||
|
// Ainda está digitando ou formato incorreto
|
||||||
|
input.addClass('is-invalid');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
input.addClass('is-invalid');
|
// Outros países: validar mínimo 10 dígitos (genérico)
|
||||||
|
if (value.length >= 10 && value.length <= 15) {
|
||||||
|
input.addClass('is-valid');
|
||||||
|
} else if (value.length > 0) {
|
||||||
|
input.addClass('is-invalid');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Validar username (mínimo 3 caracteres, sem espaços)
|
// Validar username (mínimo 3 caracteres, sem espaços)
|
||||||
|
|||||||
@ -10,6 +10,84 @@
|
|||||||
Layout = isPreview ? "_PreviewLayout" : "_UserPageLayout";
|
Layout = isPreview ? "_PreviewLayout" : "_UserPageLayout";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@functions {
|
||||||
|
/// <summary>
|
||||||
|
/// Normaliza URLs de redes sociais para garantir que sempre tenham protocolo HTTPS
|
||||||
|
/// Corrige URLs que foram salvas sem prefixo HTTP(S)
|
||||||
|
/// </summary>
|
||||||
|
string NormalizeSocialUrl(string url, string icon)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(url)) return "#";
|
||||||
|
|
||||||
|
// Se já tem protocolo, retorna direto
|
||||||
|
if (url.StartsWith("http://") || url.StartsWith("https://"))
|
||||||
|
return url;
|
||||||
|
|
||||||
|
// WhatsApp - garantir prefixo wa.me
|
||||||
|
if (!string.IsNullOrEmpty(icon) && icon.Contains("whatsapp"))
|
||||||
|
{
|
||||||
|
// Remove qualquer prefixo parcial que possa existir
|
||||||
|
var cleanUrl = url.Replace("wa.me/", "").Replace("whatsapp://", "");
|
||||||
|
return $"https://wa.me/{cleanUrl}";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Facebook
|
||||||
|
if (!string.IsNullOrEmpty(icon) && icon.Contains("facebook"))
|
||||||
|
{
|
||||||
|
var cleanUrl = url.Replace("facebook.com/", "").Replace("fb.com/", "");
|
||||||
|
return $"https://facebook.com/{cleanUrl}";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instagram
|
||||||
|
if (!string.IsNullOrEmpty(icon) && icon.Contains("instagram"))
|
||||||
|
{
|
||||||
|
var cleanUrl = url.Replace("instagram.com/", "").Replace("instagr.am/", "");
|
||||||
|
return $"https://instagram.com/{cleanUrl}";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Twitter/X
|
||||||
|
if (!string.IsNullOrEmpty(icon) && (icon.Contains("twitter") || icon.Contains("x-twitter")))
|
||||||
|
{
|
||||||
|
var cleanUrl = url.Replace("x.com/", "").Replace("twitter.com/", "");
|
||||||
|
return $"https://x.com/{cleanUrl}";
|
||||||
|
}
|
||||||
|
|
||||||
|
// TikTok
|
||||||
|
if (!string.IsNullOrEmpty(icon) && icon.Contains("tiktok"))
|
||||||
|
{
|
||||||
|
var cleanUrl = url.Replace("tiktok.com/", "").Replace("tiktok.com/@", "");
|
||||||
|
// Se não tem @, adiciona
|
||||||
|
if (!cleanUrl.StartsWith("@"))
|
||||||
|
cleanUrl = "@" + cleanUrl;
|
||||||
|
return $"https://tiktok.com/{cleanUrl}";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pinterest
|
||||||
|
if (!string.IsNullOrEmpty(icon) && icon.Contains("pinterest"))
|
||||||
|
{
|
||||||
|
var cleanUrl = url.Replace("pinterest.com/", "").Replace("pin.it/", "");
|
||||||
|
return $"https://pinterest.com/{cleanUrl}";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Discord
|
||||||
|
if (!string.IsNullOrEmpty(icon) && icon.Contains("discord"))
|
||||||
|
{
|
||||||
|
var cleanUrl = url.Replace("discord.gg/", "").Replace("discord.com/invite/", "");
|
||||||
|
return $"https://discord.gg/{cleanUrl}";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kawai ou qualquer outra rede não identificada
|
||||||
|
// Se contém domínio, apenas adiciona https://
|
||||||
|
if (url.Contains(".") || url.Contains("/"))
|
||||||
|
{
|
||||||
|
return $"https://{url.TrimStart('/')}";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: assume que é uma URL completa que está faltando protocolo
|
||||||
|
return $"https://{url}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@section Head {
|
@section Head {
|
||||||
@if (isLivePage)
|
@if (isLivePage)
|
||||||
{
|
{
|
||||||
@ -233,7 +311,7 @@
|
|||||||
(link.Type == BCards.Web.Models.LinkType.Product && !string.IsNullOrEmpty(link.ProductDescription)));
|
(link.Type == BCards.Web.Models.LinkType.Product && !string.IsNullOrEmpty(link.ProductDescription)));
|
||||||
|
|
||||||
<div class="universal-link" data-link-id="@i">
|
<div class="universal-link" data-link-id="@i">
|
||||||
<a href="@link.Url"
|
<a href="@NormalizeSocialUrl(link.Url, link.Icon)"
|
||||||
class="universal-link-header"
|
class="universal-link-header"
|
||||||
onclick="recordClick('@Model.Id', @i)"
|
onclick="recordClick('@Model.Id', @i)"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user