Add script to create channels per tournament, pools and teams. Put channels in categories
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
parent
784002c085
commit
a5c210e9b6
|
@ -8,8 +8,8 @@ from .models import Channel, Message
|
||||||
|
|
||||||
@admin.register(Channel)
|
@admin.register(Channel)
|
||||||
class ChannelAdmin(admin.ModelAdmin):
|
class ChannelAdmin(admin.ModelAdmin):
|
||||||
list_display = ('name', 'read_access', 'write_access', 'tournament', 'pool', 'team', 'private',)
|
list_display = ('name', 'category', 'read_access', 'write_access', 'tournament', 'private',)
|
||||||
list_filter = ('read_access', 'write_access', 'tournament', 'private',)
|
list_filter = ('category', 'read_access', 'write_access', 'tournament', 'private',)
|
||||||
search_fields = ('name', 'tournament__name', 'team__name', 'team__trigram',)
|
search_fields = ('name', 'tournament__name', 'team__name', 'team__trigram',)
|
||||||
autocomplete_fields = ('tournament', 'pool', 'team', 'invited', )
|
autocomplete_fields = ('tournament', 'pool', 'team', 'invited', )
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
from channels.generic.websocket import AsyncJsonWebsocketConsumer
|
from channels.generic.websocket import AsyncJsonWebsocketConsumer
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from participation.models import Team, Pool, Tournament
|
|
||||||
from registration.models import Registration
|
from registration.models import Registration
|
||||||
|
|
||||||
from .models import Channel, Message
|
from .models import Channel, Message
|
||||||
|
@ -78,6 +77,7 @@ class ChatConsumer(AsyncJsonWebsocketConsumer):
|
||||||
{
|
{
|
||||||
'id': channel.id,
|
'id': channel.id,
|
||||||
'name': channel.name,
|
'name': channel.name,
|
||||||
|
'category': channel.category,
|
||||||
'read_access': True,
|
'read_access': True,
|
||||||
'write_access': await write_channels.acontains(channel),
|
'write_access': await write_channels.acontains(channel),
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
# Copyright (C) 2024 by Animath
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
from django.core.management import BaseCommand
|
||||||
|
from django.utils.translation import activate
|
||||||
|
|
||||||
|
from participation.models import Team, Tournament
|
||||||
|
from tfjm.permissions import PermissionType
|
||||||
|
|
||||||
|
from ...models import Channel
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
def handle(self, *args, **kwargs):
|
||||||
|
activate('fr')
|
||||||
|
|
||||||
|
Channel.objects.update_or_create(
|
||||||
|
name="Annonces",
|
||||||
|
defaults=dict(
|
||||||
|
category=Channel.ChannelCategory.GENERAL,
|
||||||
|
read_access=PermissionType.AUTHENTICATED,
|
||||||
|
write_access=PermissionType.ADMIN,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
Channel.objects.update_or_create(
|
||||||
|
name="Aide jurys et orgas",
|
||||||
|
defaults=dict(
|
||||||
|
category=Channel.ChannelCategory.GENERAL,
|
||||||
|
read_access=PermissionType.VOLUNTEER,
|
||||||
|
write_access=PermissionType.VOLUNTEER,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
Channel.objects.update_or_create(
|
||||||
|
name="Général",
|
||||||
|
defaults=dict(
|
||||||
|
category=Channel.ChannelCategory.GENERAL,
|
||||||
|
read_access=PermissionType.AUTHENTICATED,
|
||||||
|
write_access=PermissionType.AUTHENTICATED,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
Channel.objects.update_or_create(
|
||||||
|
name="Je cherche une équipe",
|
||||||
|
defaults=dict(
|
||||||
|
category=Channel.ChannelCategory.GENERAL,
|
||||||
|
read_access=PermissionType.AUTHENTICATED,
|
||||||
|
write_access=PermissionType.AUTHENTICATED,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
Channel.objects.update_or_create(
|
||||||
|
name="Détente",
|
||||||
|
defaults=dict(
|
||||||
|
category=Channel.ChannelCategory.GENERAL,
|
||||||
|
read_access=PermissionType.AUTHENTICATED,
|
||||||
|
write_access=PermissionType.AUTHENTICATED,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
for tournament in Tournament.objects.all():
|
||||||
|
Channel.objects.update_or_create(
|
||||||
|
name=f"{tournament.name} - Annonces",
|
||||||
|
defaults=dict(
|
||||||
|
category=Channel.ChannelCategory.TOURNAMENT,
|
||||||
|
read_access=PermissionType.TOURNAMENT_MEMBER,
|
||||||
|
write_access=PermissionType.TOURNAMENT_ORGANIZER,
|
||||||
|
tournament=tournament,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
Channel.objects.update_or_create(
|
||||||
|
name=f"{tournament.name} - Général",
|
||||||
|
defaults=dict(
|
||||||
|
category=Channel.ChannelCategory.TOURNAMENT,
|
||||||
|
read_access=PermissionType.TOURNAMENT_MEMBER,
|
||||||
|
write_access=PermissionType.TOURNAMENT_MEMBER,
|
||||||
|
tournament=tournament,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
Channel.objects.update_or_create(
|
||||||
|
name=f"{tournament.name} - Détente",
|
||||||
|
defaults=dict(
|
||||||
|
category=Channel.ChannelCategory.TOURNAMENT,
|
||||||
|
read_access=PermissionType.TOURNAMENT_MEMBER,
|
||||||
|
write_access=PermissionType.TOURNAMENT_MEMBER,
|
||||||
|
tournament=tournament,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
Channel.objects.update_or_create(
|
||||||
|
name=f"{tournament.name} - Juré⋅es",
|
||||||
|
defaults=dict(
|
||||||
|
category=Channel.ChannelCategory.TOURNAMENT,
|
||||||
|
read_access=PermissionType.JURY_MEMBER,
|
||||||
|
write_access=PermissionType.JURY_MEMBER,
|
||||||
|
tournament=tournament,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
if tournament.remote:
|
||||||
|
Channel.objects.update_or_create(
|
||||||
|
name=f"{tournament.name} - Président⋅es de jury",
|
||||||
|
defaults=dict(
|
||||||
|
category=Channel.ChannelCategory.TOURNAMENT,
|
||||||
|
read_access=PermissionType.TOURNAMENT_JURY_PRESIDENT,
|
||||||
|
write_access=PermissionType.TOURNAMENT_JURY_PRESIDENT,
|
||||||
|
tournament=tournament,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
for pool in tournament.pools.all():
|
||||||
|
Channel.objects.update_or_create(
|
||||||
|
name=f"{tournament.name} - Poule {pool.short_name}",
|
||||||
|
defaults=dict(
|
||||||
|
category=Channel.ChannelCategory.TOURNAMENT,
|
||||||
|
read_access=PermissionType.POOL_MEMBER,
|
||||||
|
write_access=PermissionType.POOL_MEMBER,
|
||||||
|
pool=pool,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
Channel.objects.update_or_create(
|
||||||
|
name=f"{tournament.name} - Poule {pool.short_name} - Jury",
|
||||||
|
defaults=dict(
|
||||||
|
category=Channel.ChannelCategory.TOURNAMENT,
|
||||||
|
read_access=PermissionType.JURY_MEMBER,
|
||||||
|
write_access=PermissionType.JURY_MEMBER,
|
||||||
|
pool=pool,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
for team in Team.objects.filter(participation__valid=True).all():
|
||||||
|
Channel.objects.update_or_create(
|
||||||
|
name=f"Équipe {team.trigram}",
|
||||||
|
defaults=dict(
|
||||||
|
category=Channel.ChannelCategory.TEAM,
|
||||||
|
read_access=PermissionType.TEAM_MEMBER,
|
||||||
|
write_access=PermissionType.TEAM_MEMBER,
|
||||||
|
team=team,
|
||||||
|
),
|
||||||
|
)
|
|
@ -0,0 +1,36 @@
|
||||||
|
# Generated by Django 5.0.3 on 2024-04-28 11:08
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("chat", "0001_initial"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name="channel",
|
||||||
|
options={
|
||||||
|
"ordering": ("category", "name"),
|
||||||
|
"verbose_name": "channel",
|
||||||
|
"verbose_name_plural": "channels",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="channel",
|
||||||
|
name="category",
|
||||||
|
field=models.CharField(
|
||||||
|
choices=[
|
||||||
|
("general", "General channels"),
|
||||||
|
("tournament", "Tournament channels"),
|
||||||
|
("team", "Team channels"),
|
||||||
|
("private", "Private channels"),
|
||||||
|
],
|
||||||
|
default="general",
|
||||||
|
max_length=255,
|
||||||
|
verbose_name="category",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -13,11 +13,24 @@ from tfjm.permissions import PermissionType
|
||||||
|
|
||||||
|
|
||||||
class Channel(models.Model):
|
class Channel(models.Model):
|
||||||
|
class ChannelCategory(models.TextChoices):
|
||||||
|
GENERAL = 'general', _("General channels")
|
||||||
|
TOURNAMENT = 'tournament', _("Tournament channels")
|
||||||
|
TEAM = 'team', _("Team channels")
|
||||||
|
PRIVATE = 'private', _("Private channels")
|
||||||
|
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=255,
|
max_length=255,
|
||||||
verbose_name=_("name"),
|
verbose_name=_("name"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
category = models.CharField(
|
||||||
|
max_length=255,
|
||||||
|
verbose_name=_("category"),
|
||||||
|
choices=ChannelCategory,
|
||||||
|
default=ChannelCategory.GENERAL,
|
||||||
|
)
|
||||||
|
|
||||||
read_access = models.CharField(
|
read_access = models.CharField(
|
||||||
max_length=16,
|
max_length=16,
|
||||||
verbose_name=_("read permission"),
|
verbose_name=_("read permission"),
|
||||||
|
@ -90,7 +103,7 @@ class Channel(models.Model):
|
||||||
return Channel.objects.filter(**{permission_type: PermissionType.ANONYMOUS})
|
return Channel.objects.filter(**{permission_type: PermissionType.ANONYMOUS})
|
||||||
|
|
||||||
qs |= Channel.objects.filter(**{permission_type: PermissionType.AUTHENTICATED})
|
qs |= Channel.objects.filter(**{permission_type: PermissionType.AUTHENTICATED})
|
||||||
registration = await Registration.objects.aget(user_id=user.id)
|
registration = await Registration.objects.prefetch_related('user').aget(user_id=user.id)
|
||||||
|
|
||||||
if registration.is_admin:
|
if registration.is_admin:
|
||||||
return Channel.objects.all()
|
return Channel.objects.all()
|
||||||
|
@ -147,7 +160,7 @@ class Channel(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("channel")
|
verbose_name = _("channel")
|
||||||
verbose_name_plural = _("channels")
|
verbose_name_plural = _("channels")
|
||||||
ordering = ('name',)
|
ordering = ('category', 'name',)
|
||||||
|
|
||||||
|
|
||||||
class Message(models.Model):
|
class Message(models.Model):
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
const MAX_MESSAGES = 50
|
const MAX_MESSAGES = 50
|
||||||
|
|
||||||
|
const channel_categories = ['general', 'tournament', 'team', 'private']
|
||||||
let channels = {}
|
let channels = {}
|
||||||
let messages = {}
|
let messages = {}
|
||||||
let selected_channel_id = null
|
let selected_channel_id = null
|
||||||
|
@ -62,20 +63,27 @@ function sendMessage() {
|
||||||
|
|
||||||
function setChannels(new_channels) {
|
function setChannels(new_channels) {
|
||||||
channels = {}
|
channels = {}
|
||||||
let navTab = document.getElementById('nav-channels-tab')
|
let categoryLists = {}
|
||||||
navTab.innerHTML = ''
|
for (let category of channel_categories) {
|
||||||
|
categoryLists[category] = document.getElementById(`nav-${category}-channels-tab`)
|
||||||
|
categoryLists[category].innerHTML = ''
|
||||||
|
categoryLists[category].parentElement.classList.add('d-none')
|
||||||
|
}
|
||||||
|
|
||||||
for (let channel of new_channels) {
|
for (let channel of new_channels) {
|
||||||
channels[channel['id']] = channel
|
channels[channel['id']] = channel
|
||||||
if (!messages[channel['id']])
|
if (!messages[channel['id']])
|
||||||
messages[channel['id']] = new Map()
|
messages[channel['id']] = new Map()
|
||||||
|
|
||||||
|
let categoryList = categoryLists[channel['category']]
|
||||||
|
categoryList.parentElement.classList.remove('d-none')
|
||||||
|
|
||||||
let navItem = document.createElement('li')
|
let navItem = document.createElement('li')
|
||||||
navItem.classList.add('list-group-item')
|
navItem.classList.add('list-group-item')
|
||||||
navItem.id = `tab-channel-${channel['id']}`
|
navItem.id = `tab-channel-${channel['id']}`
|
||||||
navItem.setAttribute('data-bs-dismiss', 'offcanvas')
|
navItem.setAttribute('data-bs-dismiss', 'offcanvas')
|
||||||
navItem.onclick = () => selectChannel(channel['id'])
|
navItem.onclick = () => selectChannel(channel['id'])
|
||||||
navTab.appendChild(navItem)
|
categoryList.appendChild(navItem)
|
||||||
|
|
||||||
let channelButton = document.createElement('button')
|
let channelButton = document.createElement('button')
|
||||||
channelButton.classList.add('nav-link')
|
channelButton.classList.add('nav-link')
|
||||||
|
|
|
@ -3,13 +3,30 @@
|
||||||
<noscript>
|
<noscript>
|
||||||
{% trans "JavaScript must be enabled on your browser to access chat." %}
|
{% trans "JavaScript must be enabled on your browser to access chat." %}
|
||||||
</noscript>
|
</noscript>
|
||||||
<div class="offcanvas offcanvas-start" tabindex="-1" id="channelSelector" aria-labelledby="offcanvasExampleLabel">
|
<div class="offcanvas offcanvas-start" tabindex="-1" id="channelSelector" aria-labelledby="offcanvasTitle">
|
||||||
<div class="offcanvas-header">
|
<div class="offcanvas-header">
|
||||||
<h4 class="offcanvas-title" id="offcanvasExampleLabel">{% trans "Chat channels" %}</h4>
|
<h3 class="offcanvas-title" id="offcanvasTitle">{% trans "Chat channels" %}</h3>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="offcanvas-body">
|
<div class="offcanvas-body">
|
||||||
<ul class="list-group list-group-flush" id="nav-channels-tab"></ul>
|
<ul class="list-group list-group-flush" id="nav-channels-tab">
|
||||||
|
<li class="list-group-item d-none">
|
||||||
|
<h4>{% trans "General channels" %}</h4>
|
||||||
|
<ul class="list-group list-group-flush" id="nav-general-channels-tab"></ul>
|
||||||
|
</li>
|
||||||
|
<li class="list-group-item d-none">
|
||||||
|
<h4>{% trans "Tournament channels" %}</h4>
|
||||||
|
<ul class="list-group list-group-flush" id="nav-tournament-channels-tab"></ul>
|
||||||
|
</li>
|
||||||
|
<li class="list-group-item d-none">
|
||||||
|
<h4>{% trans "Team channels" %}</h4>
|
||||||
|
<ul class="list-group list-group-flush" id="nav-team-channels-tab"></ul>
|
||||||
|
</li>
|
||||||
|
<li class="list-group-item d-none">
|
||||||
|
<h4>{% trans "Private channels" %}</h4>
|
||||||
|
<ul class="list-group list-group-flush" id="nav-private-channels-tab"></ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: TFJM\n"
|
"Project-Id-Version: TFJM\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-04-28 11:56+0200\n"
|
"POT-Creation-Date: 2024-04-28 13:08+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
|
"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -21,20 +21,40 @@ msgstr ""
|
||||||
msgid "API"
|
msgid "API"
|
||||||
msgstr "API"
|
msgstr "API"
|
||||||
|
|
||||||
#: chat/models.py:18 participation/models.py:35 participation/models.py:263
|
#: chat/models.py:17
|
||||||
|
msgid "General channels"
|
||||||
|
msgstr "Canaux généraux"
|
||||||
|
|
||||||
|
#: chat/models.py:18
|
||||||
|
msgid "Tournament channels"
|
||||||
|
msgstr "Canaux de tournois"
|
||||||
|
|
||||||
|
#: chat/models.py:19
|
||||||
|
msgid "Team channels"
|
||||||
|
msgstr "Canaux d'équipes"
|
||||||
|
|
||||||
|
#: chat/models.py:20
|
||||||
|
msgid "Private channels"
|
||||||
|
msgstr "Messages privés"
|
||||||
|
|
||||||
|
#: chat/models.py:24 participation/models.py:35 participation/models.py:263
|
||||||
#: participation/tables.py:18 participation/tables.py:34
|
#: participation/tables.py:18 participation/tables.py:34
|
||||||
msgid "name"
|
msgid "name"
|
||||||
msgstr "nom"
|
msgstr "nom"
|
||||||
|
|
||||||
#: chat/models.py:23
|
#: chat/models.py:29
|
||||||
|
msgid "category"
|
||||||
|
msgstr "catégorie"
|
||||||
|
|
||||||
|
#: chat/models.py:36
|
||||||
msgid "read permission"
|
msgid "read permission"
|
||||||
msgstr "permission de lecture"
|
msgstr "permission de lecture"
|
||||||
|
|
||||||
#: chat/models.py:29
|
#: chat/models.py:42
|
||||||
msgid "write permission"
|
msgid "write permission"
|
||||||
msgstr "permission d'écriture"
|
msgstr "permission d'écriture"
|
||||||
|
|
||||||
#: chat/models.py:39 draw/admin.py:53 draw/admin.py:71 draw/admin.py:88
|
#: chat/models.py:52 draw/admin.py:53 draw/admin.py:71 draw/admin.py:88
|
||||||
#: draw/models.py:26 participation/admin.py:79 participation/admin.py:140
|
#: draw/models.py:26 participation/admin.py:79 participation/admin.py:140
|
||||||
#: participation/admin.py:171 participation/models.py:693
|
#: participation/admin.py:171 participation/models.py:693
|
||||||
#: participation/models.py:717 participation/models.py:935
|
#: participation/models.py:717 participation/models.py:935
|
||||||
|
@ -43,7 +63,7 @@ msgstr "permission d'écriture"
|
||||||
msgid "tournament"
|
msgid "tournament"
|
||||||
msgstr "tournoi"
|
msgstr "tournoi"
|
||||||
|
|
||||||
#: chat/models.py:41
|
#: chat/models.py:54
|
||||||
msgid ""
|
msgid ""
|
||||||
"For a permission that concerns a tournament, indicates what is the concerned "
|
"For a permission that concerns a tournament, indicates what is the concerned "
|
||||||
"tournament."
|
"tournament."
|
||||||
|
@ -51,21 +71,21 @@ msgstr ""
|
||||||
"Pour une permission qui concerne un tournoi, indique quel est le tournoi "
|
"Pour une permission qui concerne un tournoi, indique quel est le tournoi "
|
||||||
"concerné."
|
"concerné."
|
||||||
|
|
||||||
#: chat/models.py:50 draw/models.py:429 draw/models.py:456
|
#: chat/models.py:63 draw/models.py:429 draw/models.py:456
|
||||||
#: participation/admin.py:136 participation/admin.py:155
|
#: participation/admin.py:136 participation/admin.py:155
|
||||||
#: participation/models.py:1434 participation/models.py:1443
|
#: participation/models.py:1434 participation/models.py:1443
|
||||||
#: participation/tables.py:84
|
#: participation/tables.py:84
|
||||||
msgid "pool"
|
msgid "pool"
|
||||||
msgstr "poule"
|
msgstr "poule"
|
||||||
|
|
||||||
#: chat/models.py:52
|
#: chat/models.py:65
|
||||||
msgid ""
|
msgid ""
|
||||||
"For a permission that concerns a pool, indicates what is the concerned pool."
|
"For a permission that concerns a pool, indicates what is the concerned pool."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Pour une permission qui concerne une poule, indique quelle est la poule "
|
"Pour une permission qui concerne une poule, indique quelle est la poule "
|
||||||
"concernée."
|
"concernée."
|
||||||
|
|
||||||
#: chat/models.py:61 draw/templates/draw/tournament_content.html:277
|
#: chat/models.py:74 draw/templates/draw/tournament_content.html:277
|
||||||
#: participation/admin.py:167 participation/models.py:252
|
#: participation/admin.py:167 participation/models.py:252
|
||||||
#: participation/models.py:708
|
#: participation/models.py:708
|
||||||
#: participation/templates/participation/tournament_harmonize.html:15
|
#: participation/templates/participation/tournament_harmonize.html:15
|
||||||
|
@ -75,18 +95,18 @@ msgstr ""
|
||||||
msgid "team"
|
msgid "team"
|
||||||
msgstr "équipe"
|
msgstr "équipe"
|
||||||
|
|
||||||
#: chat/models.py:63
|
#: chat/models.py:76
|
||||||
msgid ""
|
msgid ""
|
||||||
"For a permission that concerns a team, indicates what is the concerned team."
|
"For a permission that concerns a team, indicates what is the concerned team."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Pour une permission qui concerne une équipe, indique quelle est l'équipe "
|
"Pour une permission qui concerne une équipe, indique quelle est l'équipe "
|
||||||
"concernée."
|
"concernée."
|
||||||
|
|
||||||
#: chat/models.py:67
|
#: chat/models.py:80
|
||||||
msgid "private"
|
msgid "private"
|
||||||
msgstr "privé"
|
msgstr "privé"
|
||||||
|
|
||||||
#: chat/models.py:69
|
#: chat/models.py:82
|
||||||
msgid ""
|
msgid ""
|
||||||
"If checked, only users who have been explicitly added to the channel will be "
|
"If checked, only users who have been explicitly added to the channel will be "
|
||||||
"able to access it."
|
"able to access it."
|
||||||
|
@ -94,11 +114,11 @@ msgstr ""
|
||||||
"Si sélectionné, seul⋅es les utilisateur⋅rices qui ont été explicitement "
|
"Si sélectionné, seul⋅es les utilisateur⋅rices qui ont été explicitement "
|
||||||
"ajouté⋅es au canal pourront y accéder."
|
"ajouté⋅es au canal pourront y accéder."
|
||||||
|
|
||||||
#: chat/models.py:74
|
#: chat/models.py:87
|
||||||
msgid "invited users"
|
msgid "invited users"
|
||||||
msgstr "Utilisateur⋅rices invité"
|
msgstr "Utilisateur⋅rices invité"
|
||||||
|
|
||||||
#: chat/models.py:77
|
#: chat/models.py:90
|
||||||
msgid ""
|
msgid ""
|
||||||
"Extra users who have been invited to the channel, in addition to the "
|
"Extra users who have been invited to the channel, in addition to the "
|
||||||
"permitted group of the channel."
|
"permitted group of the channel."
|
||||||
|
@ -106,40 +126,40 @@ msgstr ""
|
||||||
"Utilisateur⋅rices supplémentaires qui ont été invité⋅es au canal, en plus du "
|
"Utilisateur⋅rices supplémentaires qui ont été invité⋅es au canal, en plus du "
|
||||||
"groupe autorisé du canal."
|
"groupe autorisé du canal."
|
||||||
|
|
||||||
#: chat/models.py:82
|
#: chat/models.py:95
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Channel {name}"
|
msgid "Channel {name}"
|
||||||
msgstr "Canal {name}"
|
msgstr "Canal {name}"
|
||||||
|
|
||||||
#: chat/models.py:148 chat/models.py:157
|
#: chat/models.py:161 chat/models.py:170
|
||||||
msgid "channel"
|
msgid "channel"
|
||||||
msgstr "canal"
|
msgstr "canal"
|
||||||
|
|
||||||
#: chat/models.py:149
|
#: chat/models.py:162
|
||||||
msgid "channels"
|
msgid "channels"
|
||||||
msgstr "canaux"
|
msgstr "canaux"
|
||||||
|
|
||||||
#: chat/models.py:163
|
#: chat/models.py:176
|
||||||
msgid "author"
|
msgid "author"
|
||||||
msgstr "auteur⋅rice"
|
msgstr "auteur⋅rice"
|
||||||
|
|
||||||
#: chat/models.py:170
|
#: chat/models.py:183
|
||||||
msgid "created at"
|
msgid "created at"
|
||||||
msgstr "créé le"
|
msgstr "créé le"
|
||||||
|
|
||||||
#: chat/models.py:175
|
#: chat/models.py:188
|
||||||
msgid "updated at"
|
msgid "updated at"
|
||||||
msgstr "modifié le"
|
msgstr "modifié le"
|
||||||
|
|
||||||
#: chat/models.py:180
|
#: chat/models.py:193
|
||||||
msgid "content"
|
msgid "content"
|
||||||
msgstr "contenu"
|
msgstr "contenu"
|
||||||
|
|
||||||
#: chat/models.py:243
|
#: chat/models.py:256
|
||||||
msgid "message"
|
msgid "message"
|
||||||
msgstr "message"
|
msgstr "message"
|
||||||
|
|
||||||
#: chat/models.py:244
|
#: chat/models.py:257
|
||||||
msgid "messages"
|
msgid "messages"
|
||||||
msgstr "messages"
|
msgstr "messages"
|
||||||
|
|
||||||
|
@ -171,7 +191,7 @@ msgstr "Déconnexion"
|
||||||
msgid "Install app on home screen"
|
msgid "Install app on home screen"
|
||||||
msgstr "Installer l'application sur l'écran d'accueil"
|
msgstr "Installer l'application sur l'écran d'accueil"
|
||||||
|
|
||||||
#: chat/templates/chat/content.html:54
|
#: chat/templates/chat/content.html:55
|
||||||
msgid "Fetch previous messages…"
|
msgid "Fetch previous messages…"
|
||||||
msgstr "Récupérer les messages précédents…"
|
msgstr "Récupérer les messages précédents…"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue