207 lines
14 KiB
HTML
207 lines
14 KiB
HTML
{% extends "template.html" %}
|
|
|
|
{% block content %}
|
|
<div class="mb-8">
|
|
<h1 class="text-3xl font-bold text-gray-900 dark:text-white mb-4">Patreon — Notifications de posts</h1>
|
|
{% if request.args.get('msg') %}
|
|
{% set msg_type = request.args.get('type') %}
|
|
<div class="mb-4 p-4 rounded-lg {% if msg_type == 'success' %}bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 text-green-700 dark:text-green-300{% elif msg_type == 'error' %}bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 text-red-700 dark:text-red-300{% else %}bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 text-blue-700 dark:text-blue-300{% endif %}">
|
|
{{ request.args.get('msg') }}
|
|
</div>
|
|
{% endif %}
|
|
<div class="bg-orange-50 dark:bg-orange-900/20 border border-orange-200 dark:border-orange-800 rounded-lg p-4">
|
|
<p class="text-gray-700 dark:text-gray-300">
|
|
Notifications des nouveaux posts Patreon via le flux RSS public. Renseignez le nom du créateur Patreon
|
|
et choisissez le canal Discord de destination. Le bot vérifie le flux environ toutes les 10 minutes.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6">
|
|
<div class="flex items-center gap-3 mb-6">
|
|
<svg class="w-8 h-8 text-orange-500" fill="currentColor" viewBox="0 0 24 24"><path d="M14.82 2.41c3.96 0 7.18 3.24 7.18 7.21 0 3.96-3.22 7.18-7.18 7.18-2.56 0-4.81-1.34-6.09-3.36L2 20.6h3.12l2.6-2.63 1.38 2.63h3.36l-2.75-5.23c.27-.39.51-.8.71-1.24l4.82 6.47h3.76l-6.47-8.67c.19-.76.29-1.55.29-2.37 0-1.32-.28-2.58-.78-3.71h3.63L14.82 2.41zM14.82 4.92c2.57 0 4.67 2.09 4.67 4.7 0 2.57-2.1 4.67-4.67 4.67-2.58 0-4.68-2.1-4.68-4.67 0-2.61 2.1-4.7 4.68-4.7z"/></svg>
|
|
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">Configuration Patreon</h2>
|
|
</div>
|
|
|
|
<form action="{{ url_for('updatePatreon') }}" method="POST" class="space-y-6">
|
|
<div class="bg-gray-50 dark:bg-gray-700/50 rounded-lg p-4 space-y-4">
|
|
<label class="flex items-center gap-2 cursor-pointer">
|
|
<input type="checkbox" name="patreon_enable" {% if configuration.getValue('patreon_enable') %}checked{% endif %}
|
|
class="w-5 h-5 rounded border-gray-300 dark:border-gray-600 text-orange-600 focus:ring-orange-500 dark:bg-gray-700">
|
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Activer les notifications Patreon</span>
|
|
</label>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="patreon_creator" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Nom du créateur Patreon</label>
|
|
<input type="text" name="patreon_creator" id="patreon_creator"
|
|
value="{{ configuration.getValue('patreon_creator') or '' }}"
|
|
placeholder="ex: nom_du_createur"
|
|
class="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-orange-500 focus:border-transparent transition-all">
|
|
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Le nom tel qu'il apparaît dans l'URL : patreon.com/<strong>nom_du_createur</strong></p>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="patreon_channel_id" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Canal Discord pour les notifications</label>
|
|
<select name="patreon_channel_id" id="patreon_channel_id"
|
|
class="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-orange-500 focus:border-transparent transition-all">
|
|
<option value="">— Choisir un canal —</option>
|
|
{% for channel in channels %}
|
|
<option value="{{ channel.id }}" {% if configuration.getIntValue('patreon_channel_id') == channel.id %}selected{% endif %}>{{ channel.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
|
|
<div class="bg-gray-50 dark:bg-gray-700/50 rounded-lg p-4 space-y-4">
|
|
<h3 class="font-medium text-gray-800 dark:text-gray-200">Mentions (optionnel)</h3>
|
|
<p class="text-sm text-gray-600 dark:text-gray-400">Choisissez qui mentionner au début du message (avant l'embed).</p>
|
|
<div class="flex flex-wrap gap-4">
|
|
<label class="flex items-center gap-2 cursor-pointer">
|
|
<input type="checkbox" name="patreon_mention_everyone" {% if mention_everyone %}checked{% endif %}
|
|
class="w-4 h-4 rounded border-gray-300 dark:border-gray-600 text-orange-600 focus:ring-orange-500 dark:bg-gray-700">
|
|
<span class="text-sm text-gray-700 dark:text-gray-300">@everyone</span>
|
|
</label>
|
|
<label class="flex items-center gap-2 cursor-pointer">
|
|
<input type="checkbox" name="patreon_mention_here" {% if mention_here %}checked{% endif %}
|
|
class="w-4 h-4 rounded border-gray-300 dark:border-gray-600 text-orange-600 focus:ring-orange-500 dark:bg-gray-700">
|
|
<span class="text-sm text-gray-700 dark:text-gray-300">@here</span>
|
|
</label>
|
|
</div>
|
|
{% if roles %}
|
|
<div>
|
|
<p class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Rôles à mentionner</p>
|
|
{% if roles|length > 1 %}
|
|
<div class="flex flex-wrap gap-1 border-b border-gray-200 dark:border-gray-600 mb-3">
|
|
{% for guild_data in roles %}
|
|
<button type="button" class="patreon-role-tab px-4 py-2 text-sm font-medium rounded-t-lg transition-colors {% if loop.first %}bg-gray-200 dark:bg-gray-600 text-gray-900 dark:text-white{% else %}bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-600{% endif %}"
|
|
data-tab="patreon-roles-{{ guild_data.guild_id }}" {% if loop.first %}data-default{% endif %}>
|
|
{{ guild_data.guild_name }}
|
|
</button>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
{% for guild_data in roles %}
|
|
<div id="patreon-roles-{{ guild_data.guild_id }}" class="patreon-role-panel {% if not loop.first %}hidden{% endif %} max-h-48 overflow-y-auto border border-gray-200 dark:border-gray-600 rounded-lg p-3 space-y-2">
|
|
{% for role in guild_data.roles %}
|
|
<label class="flex items-center gap-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-600/50 p-1 rounded">
|
|
<input type="checkbox" name="patreon_mention_roles" value="{{ role.id }}"
|
|
{% if role.id|string in mention_role_ids %}checked{% endif %}
|
|
class="w-4 h-4 rounded border-gray-300 dark:border-gray-600 text-orange-600 focus:ring-orange-500 dark:bg-gray-700">
|
|
{% if role.color is defined and role.color is not none and role.color.value != 0 %}
|
|
<span class="w-3 h-3 rounded-full flex-shrink-0" style="background-color:#{{ '%06x'|format(role.color.value) }}"></span>
|
|
{% else %}
|
|
<span class="w-3 h-3 rounded-full flex-shrink-0 bg-gray-400"></span>
|
|
{% endif %}
|
|
<span class="text-sm text-gray-700 dark:text-gray-300">{{ role.name }}</span>
|
|
</label>
|
|
{% endfor %}
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<button type="submit"
|
|
class="px-6 py-2.5 bg-orange-600 hover:bg-orange-700 text-white font-medium rounded-lg transition-colors focus:ring-2 focus:ring-orange-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800">
|
|
Enregistrer
|
|
</button>
|
|
</form>
|
|
|
|
<div class="mt-8 pt-8 border-t border-gray-200 dark:border-gray-700">
|
|
<h3 class="font-medium text-gray-800 dark:text-gray-200 mb-3">Aperçu de l'embed Discord</h3>
|
|
<p class="text-sm text-gray-600 dark:text-gray-400 mb-4">Exemple du message envoyé dans le canal lors d'un nouveau post Patreon.</p>
|
|
<div class="inline-block rounded-r-lg overflow-hidden border border-gray-300 dark:border-gray-600 bg-[#2f3136] max-w-lg shadow-lg" style="border-left: 4px solid #F96854;">
|
|
<div class="p-4">
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<img src="https://c5.patreon.com/external/favicon/favicon-32x32.png" alt="" class="w-6 h-6 rounded-full">
|
|
<span class="text-[#dcddde] text-sm font-medium">Nom du créateur</span>
|
|
</div>
|
|
<a href="#" class="text-[#00a8fc] hover:underline font-semibold text-base block mb-2">Titre du post Patreon</a>
|
|
<p class="text-[#dcddde] text-sm leading-relaxed mb-3">Ceci est un aperçu de la description du post Patreon. Le contenu HTML est automatiquement nettoyé et tronqué pour l'embed Discord...</p>
|
|
<div class="rounded overflow-hidden bg-[#202225] aspect-video flex items-center justify-center my-2">
|
|
<svg class="w-12 h-12 text-gray-500" fill="currentColor" viewBox="0 0 24 24"><path d="M14.82 2.41c3.96 0 7.18 3.24 7.18 7.21 0 3.96-3.22 7.18-7.18 7.18-2.56 0-4.81-1.34-6.09-3.36L2 20.6h3.12l2.6-2.63 1.38 2.63h3.36l-2.75-5.23c.27-.39.51-.8.71-1.24l4.82 6.47h3.76l-6.47-8.67c.19-.76.29-1.55.29-2.37 0-1.32-.28-2.58-.78-3.71h3.63L14.82 2.41zM14.82 4.92c2.57 0 4.67 2.09 4.67 4.7 0 2.57-2.1 4.67-4.67 4.67-2.58 0-4.68-2.1-4.68-4.67 0-2.61 2.1-4.7 4.68-4.7z"/></svg>
|
|
</div>
|
|
<p class="text-xs text-[#72767d] pt-1">MamieHenriette • Patreon</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% if posts %}
|
|
<div class="mt-8">
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden">
|
|
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
|
|
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">Historique des posts Patreon</h2>
|
|
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">{{ posts|length }} post{{ 's' if posts|length > 1 else '' }} enregistré{{ 's' if posts|length > 1 else '' }}</p>
|
|
</div>
|
|
<div class="p-6">
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
{% for post in posts %}
|
|
<article class="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden hover:shadow-md transition-shadow flex flex-col">
|
|
<div class="p-4 flex flex-col flex-1">
|
|
<div class="flex items-start justify-between gap-2 mb-2">
|
|
<h3 class="font-semibold text-gray-900 dark:text-white line-clamp-2 flex-1" title="{{ post.title or 'Sans titre' }}">
|
|
{% if post.link %}
|
|
<a href="{{ post.link }}" target="_blank" rel="noopener noreferrer" class="hover:text-orange-600 dark:hover:text-orange-400 transition-colors">{{ post.title or 'Sans titre' }}</a>
|
|
{% else %}
|
|
{{ post.title or 'Sans titre' }}
|
|
{% endif %}
|
|
</h3>
|
|
{% if post.notified %}
|
|
<span class="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-300 flex-shrink-0">
|
|
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg>
|
|
Notifié
|
|
</span>
|
|
{% else %}
|
|
<span class="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 flex-shrink-0">
|
|
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01"></path></svg>
|
|
Non notifié
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
{% if post.description %}
|
|
<p class="text-sm text-gray-600 dark:text-gray-400 mb-3 line-clamp-3">{{ post.description|striptags|truncate(150) }}</p>
|
|
{% endif %}
|
|
{% if post.published_formatted %}
|
|
<p class="text-xs text-gray-500 dark:text-gray-500 mb-3">{{ post.published_formatted }}</p>
|
|
{% endif %}
|
|
<div class="mt-auto">
|
|
<form action="{{ url_for('sendPatreonToDiscord') }}" method="POST" class="w-full">
|
|
<input type="hidden" name="guid" value="{{ post.guid }}">
|
|
<button type="submit" class="w-full inline-flex items-center justify-center gap-2 px-3 py-2 text-sm font-medium rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white transition-colors focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800">
|
|
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24"><path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03z"/></svg>
|
|
{% if post.notified %}Re-notifier{% else %}Envoyer sur Discord{% endif %}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="mt-8 p-4 rounded-lg bg-white dark:bg-gray-800 shadow-sm border border-gray-200 dark:border-gray-700">
|
|
<p class="text-gray-600 dark:text-gray-400 text-sm">Aucun post Patreon enregistré. Les posts apparaîtront ici après la première vérification du flux RSS.</p>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<script>
|
|
document.querySelectorAll('.patreon-role-tab').forEach(btn => {
|
|
btn.addEventListener('click', function() {
|
|
var tabId = this.getAttribute('data-tab');
|
|
document.querySelectorAll('.patreon-role-panel').forEach(p => p.classList.add('hidden'));
|
|
document.querySelectorAll('.patreon-role-tab').forEach(b => {
|
|
b.classList.remove('bg-gray-200', 'dark:bg-gray-600', 'text-gray-900', 'dark:text-white');
|
|
b.classList.add('bg-gray-100', 'dark:bg-gray-700', 'text-gray-600', 'dark:text-gray-400');
|
|
});
|
|
document.getElementById(tabId).classList.remove('hidden');
|
|
this.classList.remove('bg-gray-100', 'dark:bg-gray-700', 'text-gray-600', 'dark:text-gray-400');
|
|
this.classList.add('bg-gray-200', 'dark:bg-gray-600', 'text-gray-900', 'dark:text-white');
|
|
});
|
|
});
|
|
document.querySelector('.patreon-role-tab[data-default]')?.click();
|
|
</script>
|
|
{% endblock %}
|