fix 'Chargement..' for profil
This commit is contained in:
parent
16560e0b52
commit
a4a39fd0ba
@ -16,24 +16,15 @@ function CreateAuthorPageLink() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function PublishLink() {
|
|
||||||
return (
|
|
||||||
<Link href="/publish" className={buttonClassName}>
|
|
||||||
{t('nav.publish')}
|
|
||||||
</Link>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function LoadingButton() {
|
|
||||||
return (
|
|
||||||
<div className="px-4 py-2 bg-neon-cyan/20 text-neon-cyan rounded-lg text-sm font-medium">
|
|
||||||
{t('nav.loading')}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function AuthorProfileLink({ presentation, profile }: { presentation: Article; profile: { name?: string; picture?: string } | null }) {
|
function AuthorProfileLink({ presentation, profile }: { presentation: Article; profile: { name?: string; picture?: string } | null }) {
|
||||||
const authorName = presentation.title.replace(/^Présentation de /, '') || profile?.name || 'Auteur'
|
// Extract author name from presentation title or profile
|
||||||
|
// Title format: "Présentation de <name>" or just use profile name
|
||||||
|
let authorName = presentation.title.replace(/^Présentation de /, '').trim()
|
||||||
|
if (!authorName || authorName === 'Présentation') {
|
||||||
|
authorName = profile?.name || 'Auteur'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract picture from presentation (bannerUrl or from JSON metadata) or profile
|
||||||
const picture = presentation.bannerUrl || profile?.picture
|
const picture = presentation.bannerUrl || profile?.picture
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -48,6 +39,7 @@ function AuthorProfileLink({ presentation, profile }: { presentation: Article; p
|
|||||||
alt={authorName}
|
alt={authorName}
|
||||||
fill
|
fill
|
||||||
className="object-cover"
|
className="object-cover"
|
||||||
|
sizes="32px"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@ -64,19 +56,16 @@ export function ConditionalPublishButton() {
|
|||||||
const { connected, pubkey, profile } = useNostrAuth()
|
const { connected, pubkey, profile } = useNostrAuth()
|
||||||
const { checkPresentationExists } = useAuthorPresentation(pubkey ?? null)
|
const { checkPresentationExists } = useAuthorPresentation(pubkey ?? null)
|
||||||
const [presentation, setPresentation] = useState<Article | null>(null)
|
const [presentation, setPresentation] = useState<Article | null>(null)
|
||||||
const [loading, setLoading] = useState(false)
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const check = async () => {
|
const check = async () => {
|
||||||
if (!connected || !pubkey) {
|
if (!connected || !pubkey) {
|
||||||
setPresentation(null)
|
setPresentation(null)
|
||||||
setLoading(false)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setLoading(true)
|
// Check for presentation asynchronously, but don't show loading state
|
||||||
const pres = await checkPresentationExists()
|
const pres = await checkPresentationExists()
|
||||||
setPresentation(pres)
|
setPresentation(pres)
|
||||||
setLoading(false)
|
|
||||||
}
|
}
|
||||||
void check()
|
void check()
|
||||||
}, [connected, pubkey, checkPresentationExists])
|
}, [connected, pubkey, checkPresentationExists])
|
||||||
@ -85,14 +74,11 @@ export function ConditionalPublishButton() {
|
|||||||
return <CreateAuthorPageLink />
|
return <CreateAuthorPageLink />
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loading) {
|
// If presentation exists, show author profile link with image/fallback
|
||||||
return <LoadingButton />
|
if (presentation) {
|
||||||
}
|
|
||||||
|
|
||||||
if (!presentation) {
|
|
||||||
return <CreateAuthorPageLink />
|
|
||||||
}
|
|
||||||
|
|
||||||
// If presentation exists, show author profile link instead of publish button
|
|
||||||
return <AuthorProfileLink presentation={presentation} profile={profile} />
|
return <AuthorProfileLink presentation={presentation} profile={profile} />
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, show create author page button immediately (no loading state)
|
||||||
|
return <CreateAuthorPageLink />
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import React from 'react'
|
|
||||||
import { renderMarkdown } from '@/lib/markdownRenderer'
|
import { renderMarkdown } from '@/lib/markdownRenderer'
|
||||||
|
import { t } from '@/lib/i18n'
|
||||||
|
|
||||||
interface DocsContentProps {
|
interface DocsContentProps {
|
||||||
content: string
|
content: string
|
||||||
@ -10,7 +10,7 @@ export function DocsContent({ content, loading }: DocsContentProps) {
|
|||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<div className="text-center py-12">
|
<div className="text-center py-12">
|
||||||
<p className="text-cyber-accent">Chargement de la documentation...</p>
|
<p className="text-cyber-accent">{t('docs.loading')}</p>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -219,13 +219,13 @@ export function Nip95ConfigManager({ onConfigChange }: Nip95ConfigManagerProps)
|
|||||||
<div
|
<div
|
||||||
className="text-neon-cyan cursor-pointer hover:text-neon-green transition-colors"
|
className="text-neon-cyan cursor-pointer hover:text-neon-green transition-colors"
|
||||||
onClick={() => setEditingId(api.id)}
|
onClick={() => setEditingId(api.id)}
|
||||||
title="Click to edit URL"
|
title={t('settings.nip95.list.editUrl')}
|
||||||
>
|
>
|
||||||
{api.url}
|
{api.url}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="text-sm text-cyber-accent mt-1">
|
<div className="text-sm text-cyber-accent mt-1">
|
||||||
Priority: {api.priority} | ID: {api.id}
|
{t('settings.nip95.list.priorityLabel', { priority: api.priority, id: api.id })}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
@ -273,11 +273,10 @@ export function Nip95ConfigManager({ onConfigChange }: Nip95ConfigManagerProps)
|
|||||||
|
|
||||||
<div className="text-sm text-cyber-accent space-y-2">
|
<div className="text-sm text-cyber-accent space-y-2">
|
||||||
<p>
|
<p>
|
||||||
<strong>Note:</strong> Endpoints are tried in priority order (lower number = higher priority).
|
<strong>{t('settings.nip95.note.title')}</strong> {t('settings.nip95.note.priority')}
|
||||||
Only enabled endpoints will be used for uploads.
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
If an endpoint fails, the next enabled endpoint will be tried automatically.
|
{t('settings.nip95.note.fallback')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import type { AuthorPresentationDraft } from './articlePublisher'
|
|||||||
import type { SimplePoolWithSub } from '@/types/nostr-tools-extended'
|
import type { SimplePoolWithSub } from '@/types/nostr-tools-extended'
|
||||||
import { buildTags, extractTagsFromEvent, buildTagFilter } from './nostrTagSystem'
|
import { buildTags, extractTagsFromEvent, buildTagFilter } from './nostrTagSystem'
|
||||||
import { getPrimaryRelaySync } from './config'
|
import { getPrimaryRelaySync } from './config'
|
||||||
import { PLATFORM_SERVICE } from './platformConfig'
|
import { PLATFORM_SERVICE, MIN_EVENT_DATE } from './platformConfig'
|
||||||
import { generateAuthorHashId } from './hashIdGenerator'
|
import { generateAuthorHashId } from './hashIdGenerator'
|
||||||
import { generateObjectUrl } from './urlGenerator'
|
import { generateObjectUrl } from './urlGenerator'
|
||||||
import { getLatestVersion } from './versionManager'
|
import { getLatestVersion } from './versionManager'
|
||||||
@ -104,6 +104,7 @@ export function parsePresentationEvent(event: Event): import('@/types/nostr').Au
|
|||||||
|
|
||||||
// Try to extract profile JSON from tag first (new format)
|
// Try to extract profile JSON from tag first (new format)
|
||||||
let profileData: {
|
let profileData: {
|
||||||
|
authorName?: string
|
||||||
presentation?: string
|
presentation?: string
|
||||||
contentDescription?: string
|
contentDescription?: string
|
||||||
mainnetAddress?: string
|
mainnetAddress?: string
|
||||||
@ -191,6 +192,7 @@ export async function fetchAuthorPresentationFromPool(
|
|||||||
authorPubkey: pubkey,
|
authorPubkey: pubkey,
|
||||||
service: PLATFORM_SERVICE,
|
service: PLATFORM_SERVICE,
|
||||||
}),
|
}),
|
||||||
|
since: MIN_EVENT_DATE,
|
||||||
limit: 100, // Get all versions to find the latest
|
limit: 100, // Get all versions to find the latest
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import type { Article } from '@/types/nostr'
|
|||||||
import { parseArticleFromEvent } from './nostrEventParsing'
|
import { parseArticleFromEvent } from './nostrEventParsing'
|
||||||
import { buildTagFilter } from './nostrTagSystem'
|
import { buildTagFilter } from './nostrTagSystem'
|
||||||
import { getPrimaryRelaySync } from './config'
|
import { getPrimaryRelaySync } from './config'
|
||||||
import { PLATFORM_SERVICE } from './platformConfig'
|
import { PLATFORM_SERVICE, MIN_EVENT_DATE } from './platformConfig'
|
||||||
|
|
||||||
function createSeriesSubscription(pool: SimplePool, seriesId: string, limit: number) {
|
function createSeriesSubscription(pool: SimplePool, seriesId: string, limit: number) {
|
||||||
const filters = [
|
const filters = [
|
||||||
@ -16,6 +16,7 @@ function createSeriesSubscription(pool: SimplePool, seriesId: string, limit: num
|
|||||||
seriesId,
|
seriesId,
|
||||||
service: PLATFORM_SERVICE,
|
service: PLATFORM_SERVICE,
|
||||||
}),
|
}),
|
||||||
|
since: MIN_EVENT_DATE,
|
||||||
limit,
|
limit,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import { checkZapReceipt as checkZapReceiptHelper } from './nostrZapVerification
|
|||||||
import { subscribeWithTimeout } from './nostrSubscription'
|
import { subscribeWithTimeout } from './nostrSubscription'
|
||||||
import { getPrimaryRelay, getPrimaryRelaySync } from './config'
|
import { getPrimaryRelay, getPrimaryRelaySync } from './config'
|
||||||
import { buildTagFilter } from './nostrTagSystem'
|
import { buildTagFilter } from './nostrTagSystem'
|
||||||
import { PLATFORM_SERVICE } from './platformConfig'
|
import { PLATFORM_SERVICE, MIN_EVENT_DATE } from './platformConfig'
|
||||||
|
|
||||||
class NostrService {
|
class NostrService {
|
||||||
private pool: SimplePool | null = null
|
private pool: SimplePool | null = null
|
||||||
@ -89,12 +89,14 @@ class NostrService {
|
|||||||
// Subscribe to both 'publication' and 'author' type events
|
// Subscribe to both 'publication' and 'author' type events
|
||||||
// Authors are identified by tag type='author' in the tag system
|
// Authors are identified by tag type='author' in the tag system
|
||||||
// Filter by service='zapwall.fr' to only get notes from this platform
|
// Filter by service='zapwall.fr' to only get notes from this platform
|
||||||
|
// Limit to events published on or after January 6, 2026
|
||||||
const filters = [
|
const filters = [
|
||||||
{
|
{
|
||||||
...buildTagFilter({
|
...buildTagFilter({
|
||||||
type: 'publication',
|
type: 'publication',
|
||||||
service: PLATFORM_SERVICE,
|
service: PLATFORM_SERVICE,
|
||||||
}),
|
}),
|
||||||
|
since: MIN_EVENT_DATE,
|
||||||
limit,
|
limit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -102,6 +104,7 @@ class NostrService {
|
|||||||
type: 'author',
|
type: 'author',
|
||||||
service: PLATFORM_SERVICE,
|
service: PLATFORM_SERVICE,
|
||||||
}),
|
}),
|
||||||
|
since: MIN_EVENT_DATE,
|
||||||
limit,
|
limit,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,3 +1,7 @@
|
|||||||
export const PLATFORM_NPUB = 'npub18s03s39fa80ce2n3cmm0zme3jqehc82h6ld9sxq03uejqm3d05gsae0fuu'
|
export const PLATFORM_NPUB = 'npub18s03s39fa80ce2n3cmm0zme3jqehc82h6ld9sxq03uejqm3d05gsae0fuu'
|
||||||
export const PLATFORM_BITCOIN_ADDRESS = 'bc1qerauk5yhqytl6z93ckvwkylup8s0256uenzg9y'
|
export const PLATFORM_BITCOIN_ADDRESS = 'bc1qerauk5yhqytl6z93ckvwkylup8s0256uenzg9y'
|
||||||
export const PLATFORM_SERVICE = 'zapwall.fr'
|
export const PLATFORM_SERVICE = 'zapwall.fr'
|
||||||
|
|
||||||
|
// Minimum date for Nostr events: January 6, 2026 00:00:00 UTC
|
||||||
|
// Timestamp Unix: 1736115200
|
||||||
|
export const MIN_EVENT_DATE = 1736115200
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import type { Review } from '@/types/nostr'
|
|||||||
import { parseReviewFromEvent } from './nostrEventParsing'
|
import { parseReviewFromEvent } from './nostrEventParsing'
|
||||||
import { buildTagFilter } from './nostrTagSystem'
|
import { buildTagFilter } from './nostrTagSystem'
|
||||||
import { getPrimaryRelaySync } from './config'
|
import { getPrimaryRelaySync } from './config'
|
||||||
import { PLATFORM_SERVICE } from './platformConfig'
|
import { PLATFORM_SERVICE, MIN_EVENT_DATE } from './platformConfig'
|
||||||
|
|
||||||
function buildReviewFilters(articleId: string) {
|
function buildReviewFilters(articleId: string) {
|
||||||
const tagFilter = buildTagFilter({
|
const tagFilter = buildTagFilter({
|
||||||
@ -17,8 +17,10 @@ function buildReviewFilters(articleId: string) {
|
|||||||
kinds: number[]
|
kinds: number[]
|
||||||
'#quote'?: string[]
|
'#quote'?: string[]
|
||||||
'#article'?: string[]
|
'#article'?: string[]
|
||||||
|
since?: number
|
||||||
} = {
|
} = {
|
||||||
kinds: Array.isArray(tagFilter.kinds) ? tagFilter.kinds as number[] : [1],
|
kinds: Array.isArray(tagFilter.kinds) ? tagFilter.kinds as number[] : [1],
|
||||||
|
since: MIN_EVENT_DATE,
|
||||||
}
|
}
|
||||||
if (tagFilter['#quote']) {
|
if (tagFilter['#quote']) {
|
||||||
filterObj['#quote'] = tagFilter['#quote'] as string[]
|
filterObj['#quote'] = tagFilter['#quote'] as string[]
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import type { Series } from '@/types/nostr'
|
|||||||
import { parseSeriesFromEvent } from './nostrEventParsing'
|
import { parseSeriesFromEvent } from './nostrEventParsing'
|
||||||
import { buildTagFilter } from './nostrTagSystem'
|
import { buildTagFilter } from './nostrTagSystem'
|
||||||
import { getPrimaryRelaySync } from './config'
|
import { getPrimaryRelaySync } from './config'
|
||||||
import { PLATFORM_SERVICE } from './platformConfig'
|
import { PLATFORM_SERVICE, MIN_EVENT_DATE } from './platformConfig'
|
||||||
|
|
||||||
function buildSeriesFilters(authorPubkey: string) {
|
function buildSeriesFilters(authorPubkey: string) {
|
||||||
const tagFilter = buildTagFilter({
|
const tagFilter = buildTagFilter({
|
||||||
@ -18,6 +18,7 @@ function buildSeriesFilters(authorPubkey: string) {
|
|||||||
kinds: tagFilter.kinds as number[],
|
kinds: tagFilter.kinds as number[],
|
||||||
...(tagFilter.authors ? { authors: tagFilter.authors as string[] } : {}),
|
...(tagFilter.authors ? { authors: tagFilter.authors as string[] } : {}),
|
||||||
...(tagFilter['#series'] ? { '#series': tagFilter['#series'] as string[] } : {}),
|
...(tagFilter['#series'] ? { '#series': tagFilter['#series'] as string[] } : {}),
|
||||||
|
since: MIN_EVENT_DATE,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -66,6 +67,7 @@ function buildSeriesByIdFilters(seriesId: string) {
|
|||||||
type: 'series',
|
type: 'series',
|
||||||
service: PLATFORM_SERVICE,
|
service: PLATFORM_SERVICE,
|
||||||
}),
|
}),
|
||||||
|
since: MIN_EVENT_DATE,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { nostrService } from './nostr'
|
|||||||
import type { Article } from '@/types/nostr'
|
import type { Article } from '@/types/nostr'
|
||||||
import { getPrimaryRelaySync } from './config'
|
import { getPrimaryRelaySync } from './config'
|
||||||
import { buildTagFilter, extractTagsFromEvent } from './nostrTagSystem'
|
import { buildTagFilter, extractTagsFromEvent } from './nostrTagSystem'
|
||||||
import { PLATFORM_SERVICE } from './platformConfig'
|
import { PLATFORM_SERVICE, MIN_EVENT_DATE } from './platformConfig'
|
||||||
|
|
||||||
function subscribeToPresentation(pool: import('nostr-tools').SimplePool, pubkey: string): Promise<number> {
|
function subscribeToPresentation(pool: import('nostr-tools').SimplePool, pubkey: string): Promise<number> {
|
||||||
const filters = [
|
const filters = [
|
||||||
@ -12,6 +12,7 @@ function subscribeToPresentation(pool: import('nostr-tools').SimplePool, pubkey:
|
|||||||
authorPubkey: pubkey,
|
authorPubkey: pubkey,
|
||||||
service: PLATFORM_SERVICE,
|
service: PLATFORM_SERVICE,
|
||||||
}),
|
}),
|
||||||
|
since: MIN_EVENT_DATE,
|
||||||
limit: 1,
|
limit: 1,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
@ -192,3 +192,8 @@ settings.nip95.list.cancel=Cancel
|
|||||||
settings.nip95.list.remove=Remove
|
settings.nip95.list.remove=Remove
|
||||||
settings.nip95.remove.confirm=Are you sure you want to remove this endpoint?
|
settings.nip95.remove.confirm=Are you sure you want to remove this endpoint?
|
||||||
settings.nip95.empty=No endpoints configured
|
settings.nip95.empty=No endpoints configured
|
||||||
|
settings.nip95.list.priorityLabel=Priority: {{priority}} | ID: {{id}}
|
||||||
|
settings.nip95.list.editUrl=Click to edit URL
|
||||||
|
settings.nip95.note.title=Note:
|
||||||
|
settings.nip95.note.priority=Endpoints are tried in priority order (lower number = higher priority). Only enabled endpoints will be used for uploads.
|
||||||
|
settings.nip95.note.fallback=If an endpoint fails, the next enabled endpoint will be tried automatically.
|
||||||
|
|||||||
@ -192,3 +192,8 @@ settings.nip95.list.cancel=Annuler
|
|||||||
settings.nip95.list.remove=Supprimer
|
settings.nip95.list.remove=Supprimer
|
||||||
settings.nip95.remove.confirm=Êtes-vous sûr de vouloir supprimer cet endpoint ?
|
settings.nip95.remove.confirm=Êtes-vous sûr de vouloir supprimer cet endpoint ?
|
||||||
settings.nip95.empty=Aucun endpoint configuré
|
settings.nip95.empty=Aucun endpoint configuré
|
||||||
|
settings.nip95.list.priorityLabel=Priorité: {{priority}} | ID: {{id}}
|
||||||
|
settings.nip95.list.editUrl=Cliquer pour modifier l'URL
|
||||||
|
settings.nip95.note.title=Note :
|
||||||
|
settings.nip95.note.priority=Les endpoints sont essayés dans l'ordre de priorité (nombre plus bas = priorité plus haute). Seuls les endpoints activés seront utilisés pour les uploads.
|
||||||
|
settings.nip95.note.fallback=Si un endpoint échoue, le prochain endpoint activé sera essayé automatiquement.
|
||||||
|
|||||||
@ -18,6 +18,17 @@ nav.publish=Publish profile
|
|||||||
nav.createAuthorPage=Create author page
|
nav.createAuthorPage=Create author page
|
||||||
nav.loading=Loading...
|
nav.loading=Loading...
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
docs.title=Documentation
|
||||||
|
docs.userGuide=User Guide
|
||||||
|
docs.faq=FAQ
|
||||||
|
docs.publishing=Publishing Guide
|
||||||
|
docs.payment=Payment Guide
|
||||||
|
docs.error=Error
|
||||||
|
docs.error.loadFailed=Unable to load documentation.
|
||||||
|
docs.meta.description=Complete documentation for zapwall.fr
|
||||||
|
docs.loading=Loading documentation...
|
||||||
|
|
||||||
# Categories
|
# Categories
|
||||||
category.science-fiction=Science Fiction
|
category.science-fiction=Science Fiction
|
||||||
category.scientific-research=Scientific Research
|
category.scientific-research=Scientific Research
|
||||||
@ -182,3 +193,8 @@ settings.nip95.list.cancel=Cancel
|
|||||||
settings.nip95.list.remove=Remove
|
settings.nip95.list.remove=Remove
|
||||||
settings.nip95.remove.confirm=Are you sure you want to remove this endpoint?
|
settings.nip95.remove.confirm=Are you sure you want to remove this endpoint?
|
||||||
settings.nip95.empty=No endpoints configured
|
settings.nip95.empty=No endpoints configured
|
||||||
|
settings.nip95.list.priorityLabel=Priority: {{priority}} | ID: {{id}}
|
||||||
|
settings.nip95.list.editUrl=Click to edit URL
|
||||||
|
settings.nip95.note.title=Note:
|
||||||
|
settings.nip95.note.priority=Endpoints are tried in priority order (lower number = higher priority). Only enabled endpoints will be used for uploads.
|
||||||
|
settings.nip95.note.fallback=If an endpoint fails, the next enabled endpoint will be tried automatically.
|
||||||
|
|||||||
@ -18,6 +18,17 @@ nav.publish=Publier le profil
|
|||||||
nav.createAuthorPage=Créer page auteur
|
nav.createAuthorPage=Créer page auteur
|
||||||
nav.loading=Chargement...
|
nav.loading=Chargement...
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
docs.title=Documentation
|
||||||
|
docs.userGuide=Guide d'utilisation
|
||||||
|
docs.faq=FAQ
|
||||||
|
docs.publishing=Guide de publication
|
||||||
|
docs.payment=Guide de paiement
|
||||||
|
docs.error=Erreur
|
||||||
|
docs.error.loadFailed=Impossible de charger la documentation.
|
||||||
|
docs.meta.description=Documentation complète pour zapwall.fr
|
||||||
|
docs.loading=Chargement de la documentation...
|
||||||
|
|
||||||
# Categories
|
# Categories
|
||||||
category.science-fiction=Science-fiction
|
category.science-fiction=Science-fiction
|
||||||
category.scientific-research=Recherche scientifique
|
category.scientific-research=Recherche scientifique
|
||||||
@ -182,3 +193,8 @@ settings.nip95.list.cancel=Annuler
|
|||||||
settings.nip95.list.remove=Supprimer
|
settings.nip95.list.remove=Supprimer
|
||||||
settings.nip95.remove.confirm=Êtes-vous sûr de vouloir supprimer cet endpoint ?
|
settings.nip95.remove.confirm=Êtes-vous sûr de vouloir supprimer cet endpoint ?
|
||||||
settings.nip95.empty=Aucun endpoint configuré
|
settings.nip95.empty=Aucun endpoint configuré
|
||||||
|
settings.nip95.list.priorityLabel=Priorité: {{priority}} | ID: {{id}}
|
||||||
|
settings.nip95.list.editUrl=Cliquer pour modifier l'URL
|
||||||
|
settings.nip95.note.title=Note :
|
||||||
|
settings.nip95.note.priority=Les endpoints sont essayés dans l'ordre de priorité (nombre plus bas = priorité plus haute). Seuls les endpoints activés seront utilisés pour les uploads.
|
||||||
|
settings.nip95.note.fallback=Si un endpoint échoue, le prochain endpoint activé sera essayé automatiquement.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user