mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
refactor: decouple format extras from main fichiers block, scope FilePond destroy to individual slots, fix FilePond integration for decoupled extras
This commit is contained in:
3
TODO.md
3
TODO.md
@@ -20,3 +20,6 @@
|
|||||||
- [x] Update admin/add.php, admin/edit.php, partage/index.php: swap sortable+file-upload-queue for filepond
|
- [x] Update admin/add.php, admin/edit.php, partage/index.php: swap sortable+file-upload-queue for filepond
|
||||||
- [x] Remove file-upload-queue.js and sortable.min.js
|
- [x] Remove file-upload-queue.js and sortable.min.js
|
||||||
- [x] Clean up CSS: remove .fq-*, .tfe-file-queue styles, add filepond.css + theme overrides
|
- [x] Clean up CSS: remove .fq-*, .tfe-file-queue styles, add filepond.css + theme overrides
|
||||||
|
- [x] Decouple format extras from main file inputs — slot-based HTMX swaps preserve FilePond instances
|
||||||
|
- [x] Fix initFilePonds → window.XamxamInitFilePonds bug
|
||||||
|
- [x] Verify backend $_FILES['queue_file'][*] data flow unchanged
|
||||||
|
|||||||
@@ -113,7 +113,7 @@
|
|||||||
* Upgrade .tfe-file-picker inputs to FilePond instances.
|
* Upgrade .tfe-file-picker inputs to FilePond instances.
|
||||||
* Called on page load and after HTMX swaps.
|
* Called on page load and after HTMX swaps.
|
||||||
*/
|
*/
|
||||||
function initFilePonds() {
|
window.XamxamInitFilePonds = function () {
|
||||||
document.querySelectorAll(".tfe-file-picker").forEach(function (input) {
|
document.querySelectorAll(".tfe-file-picker").forEach(function (input) {
|
||||||
// Skip already upgraded inputs
|
// Skip already upgraded inputs
|
||||||
if (input.dataset.filepondUpgraded) return;
|
if (input.dataset.filepondUpgraded) return;
|
||||||
@@ -145,18 +145,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy all FilePond instances and restore original inputs.
|
* Destroy FilePond instances inside a given container element.
|
||||||
* Called before HTMX swaps that replace the file block.
|
* Used before HTMX swaps to avoid leaks.
|
||||||
*/
|
*/
|
||||||
function destroyFilePonds() {
|
function destroyFilePondsIn(el) {
|
||||||
Object.keys(_ponds).forEach(function (key) {
|
if (!el) return;
|
||||||
try {
|
// Find FilePond-upgraded inputs inside this element
|
||||||
_ponds[key].destroy();
|
el.querySelectorAll(".tfe-file-picker[data-filepond-upgraded]").forEach(function (input) {
|
||||||
} catch (_) { /* ignore */ }
|
// Destroy the FilePond instance if it exists
|
||||||
delete _ponds[key];
|
var id = input.id;
|
||||||
});
|
var pond = id ? _ponds[id] : null;
|
||||||
// Also catch any stray instances (HTMX may have replaced DOM)
|
if (pond) {
|
||||||
document.querySelectorAll(".tfe-file-picker[data-filepond-upgraded]").forEach(function (input) {
|
try { pond.destroy(); } catch (_) {}
|
||||||
|
delete _ponds[id];
|
||||||
|
}
|
||||||
delete input.dataset.filepondUpgraded;
|
delete input.dataset.filepondUpgraded;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -164,17 +166,16 @@
|
|||||||
// ── HTMX integration ─────────────────────────────────────────────────
|
// ── HTMX integration ─────────────────────────────────────────────────
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called before HTMX replaces the #format-fichiers-block.
|
* Before HTMX swaps a slot element that may contain FilePond instances,
|
||||||
* We must destroy FilePond instances on the soon-to-be-removed DOM nodes
|
* destroy them to avoid leaks and file-state conflicts.
|
||||||
* to avoid leaks and file-state conflicts.
|
|
||||||
*/
|
*/
|
||||||
function onHtmxBeforeSwap(evt) {
|
function onHtmxBeforeSwap(evt) {
|
||||||
// Only care about format-fichiers-block swaps
|
var target = evt.detail.target;
|
||||||
if (evt.detail.target && (
|
if (!target) return;
|
||||||
evt.detail.target.id === "format-fichiers-block" ||
|
var id = target.id || "";
|
||||||
evt.detail.target.closest && evt.detail.target.closest("#format-fichiers-block")
|
// Only care about slot elements that may contain FilePond file inputs
|
||||||
)) {
|
if (id === "slot-video" || id === "slot-audio" || id === "annexes-input-block" || id === "format-extras-block") {
|
||||||
destroyFilePonds();
|
destroyFilePondsIn(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,26 +184,18 @@
|
|||||||
// Hook into HTMX events if htmx is loaded
|
// Hook into HTMX events if htmx is loaded
|
||||||
if (window.htmx) {
|
if (window.htmx) {
|
||||||
window.htmx.on("htmx:beforeSwap", onHtmxBeforeSwap);
|
window.htmx.on("htmx:beforeSwap", onHtmxBeforeSwap);
|
||||||
|
window.htmx.on("htmx:afterSwap", function () {
|
||||||
|
window.XamxamInitFilePonds();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialise on DOM ready
|
// Initialise on DOM ready
|
||||||
if (document.readyState === "loading") {
|
if (document.readyState === "loading") {
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
initFilePonds();
|
window.XamxamInitFilePonds();
|
||||||
// Re-init handles HTMX after-swap
|
|
||||||
if (window.htmx) {
|
|
||||||
window.htmx.on("htmx:afterSwap", function () {
|
|
||||||
initFilePonds();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
initFilePonds();
|
window.XamxamInitFilePonds();
|
||||||
if (window.htmx) {
|
|
||||||
window.htmx.on("htmx:afterSwap", function () {
|
|
||||||
initFilePonds();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Mark form dirty on FilePond changes (beforeunload guard) ─────────
|
// ── Mark form dirty on FilePond changes (beforeunload guard) ─────────
|
||||||
|
|||||||
@@ -2,25 +2,17 @@
|
|||||||
/**
|
/**
|
||||||
* fichiers-fragment.php (partage & admin)
|
* fichiers-fragment.php (partage & admin)
|
||||||
*
|
*
|
||||||
* HTMX fragment: returns the combined Format(s) + Fichiers block.
|
* Returns the combined Format(s) + Fichiers block.
|
||||||
* Called on every format checkbox change so the Fichiers fieldset adapts.
|
|
||||||
*
|
*
|
||||||
* Fixed inputs (always present in #format-fichiers-block):
|
* Architecture:
|
||||||
* 1. Image de couverture (optional) — single file, plain input
|
* - Formats checkboxes: static, never swapped. They trigger HTMX swaps
|
||||||
* 2. Note d'intention (PDF, required) — single file, plain input
|
* on individual #slot-siteweb, #slot-video, #slot-audio elements.
|
||||||
* 3. TFE — multi-file, FilePond-powered — client-side, orderable
|
* - File inputs (couverture, note d'intention, TFE, annexes): always
|
||||||
* 4. Annexes checkbox + FilePond-powered queue — client-side, orderable
|
* static in the DOM — never destroyed by format toggling.
|
||||||
*
|
* - Format-specific extras: each is a standalone HTMX fragment slot.
|
||||||
* Format-specific extra inputs (#format-extras-block):
|
* When unchecked → empty hidden placeholder. When checked → input
|
||||||
* - Site web → URL field only
|
* fields rendered via HTMX. This preserves FilePond instances on
|
||||||
* - Vidéo → PeerTube single upload OR FilePond multi-file upload
|
* the main file inputs across format changes.
|
||||||
* - Audio → PeerTube single upload OR FilePond multi-file upload
|
|
||||||
*
|
|
||||||
* File uploads are managed by FilePond (file-upload-filepond.js).
|
|
||||||
* Each .tfe-file-picker input is upgraded to a FilePond instance.
|
|
||||||
* storeAsFile:true preserves native multipart form submission;
|
|
||||||
* server receives files via $_FILES indexed by name attribute
|
|
||||||
* (e.g. queue_file[tfe][], queue_file[video][], etc.).
|
|
||||||
*
|
*
|
||||||
* Expected POST:
|
* Expected POST:
|
||||||
* formats[] — array of selected format_type IDs
|
* formats[] — array of selected format_type IDs
|
||||||
@@ -75,7 +67,7 @@ $hxPost = $adminMode ? '/admin/fichiers-fragment.php' : '/partage/fichiers-fragm
|
|||||||
|
|
||||||
$hasAnnexesChecked = !empty($_POST['has_annexes']);
|
$hasAnnexesChecked = !empty($_POST['has_annexes']);
|
||||||
?>
|
?>
|
||||||
<!-- ═══════════════════ Format(s) + Fichiers (stable) ═══════════════════ -->
|
<!-- ═══════════════════ Format(s) + Fichiers (static, never swapped) ═══════════════════ -->
|
||||||
<div id="format-fichiers-block">
|
<div id="format-fichiers-block">
|
||||||
<input type="hidden" name="admin_mode" value="<?= $adminMode ? '1' : '0' ?>">
|
<input type="hidden" name="admin_mode" value="<?= $adminMode ? '1' : '0' ?>">
|
||||||
<input type="hidden" name="edit_mode" value="<?= $editMode ? '1' : '0' ?>">
|
<input type="hidden" name="edit_mode" value="<?= $editMode ? '1' : '0' ?>">
|
||||||
@@ -89,13 +81,7 @@ $hasAnnexesChecked = !empty($_POST['has_annexes']);
|
|||||||
<div>
|
<div>
|
||||||
<span class="admin-row-label">Format(s) du TFE :<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></span>
|
<span class="admin-row-label">Format(s) du TFE :<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></span>
|
||||||
<fieldset class="admin-checkbox-group"
|
<fieldset class="admin-checkbox-group"
|
||||||
<?= !$adminMode ? 'required aria-required="true"' : '' ?>
|
<?= !$adminMode ? 'required aria-required="true"' : '' ?> >
|
||||||
hx-post="<?= htmlspecialchars($hxPost) ?>"
|
|
||||||
hx-target="#format-fichiers-block"
|
|
||||||
hx-select="#format-fichiers-block"
|
|
||||||
hx-trigger="change"
|
|
||||||
hx-include="this, [name='website_url'], [name='admin_mode'], [name='edit_mode'], [name='_cover'], [name='has_annexes']"
|
|
||||||
hx-swap="outerHTML">
|
|
||||||
<legend class="sr-only">Format(s) du TFE</legend>
|
<legend class="sr-only">Format(s) du TFE</legend>
|
||||||
<ul>
|
<ul>
|
||||||
<?php foreach ($allFormats as $opt): ?>
|
<?php foreach ($allFormats as $opt): ?>
|
||||||
@@ -104,7 +90,28 @@ $hasAnnexesChecked = !empty($_POST['has_annexes']);
|
|||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
name="formats[]"
|
name="formats[]"
|
||||||
value="<?= htmlspecialchars((string)$opt['id']) ?>"
|
value="<?= htmlspecialchars((string)$opt['id']) ?>"
|
||||||
<?= in_array((int)$opt['id'], $selectedFormats, true) ? 'checked' : '' ?>>
|
<?= in_array((int)$opt['id'], $selectedFormats, true) ? 'checked' : '' ?>
|
||||||
|
<?php if ((int)$opt['id'] === ($siteWebId ?? 0)): ?>
|
||||||
|
hx-post="<?= htmlspecialchars($hxPost) ?>"
|
||||||
|
hx-target="#slot-siteweb"
|
||||||
|
hx-select="#slot-siteweb"
|
||||||
|
hx-trigger="change"
|
||||||
|
hx-include="[name='formats[]'], [name='website_url'], [name='admin_mode'], [name='edit_mode'], [name='_cover']"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
<?php elseif ((int)$opt['id'] === ($videoId ?? 0)): ?>
|
||||||
|
hx-post="<?= htmlspecialchars($hxPost) ?>"
|
||||||
|
hx-target="#slot-video"
|
||||||
|
hx-select="#slot-video"
|
||||||
|
hx-trigger="change"
|
||||||
|
hx-include="[name='formats[]'], [name='website_url'], [name='admin_mode'], [name='edit_mode'], [name='_cover']"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
<?php elseif ((int)$opt['id'] === ($audioId ?? 0)): ?>
|
||||||
|
hx-post="<?= htmlspecialchars($hxPost) ?>"
|
||||||
|
hx-target="#slot-audio"
|
||||||
|
hx-select="#slot-audio"
|
||||||
|
hx-trigger="change"
|
||||||
|
hx-include="[name='formats[]'], [name='website_url'], [name='admin_mode'], [name='edit_mode'], [name='_cover']"
|
||||||
|
<?php endif; ?>>
|
||||||
<?= htmlspecialchars($opt['name']) ?>
|
<?= htmlspecialchars($opt['name']) ?>
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
@@ -272,10 +279,11 @@ $hasAnnexesChecked = !empty($_POST['has_annexes']);
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ── Format-specific extras (swappable) ── -->
|
<!-- ── Format-specific extras (individual swappable slots) ── -->
|
||||||
<div id="format-extras-block" style="display:flex;flex-direction:column;gap:var(--space-s);">
|
<div id="format-extras-block" style="display:flex;flex-direction:column;gap:var(--space-s);">
|
||||||
|
<!-- Slot: Site web -->
|
||||||
<?php if ($hasSiteWeb): ?>
|
<?php if ($hasSiteWeb): ?>
|
||||||
<div class="admin-form-group">
|
<div id="slot-siteweb" class="admin-form-group">
|
||||||
<label for="website_url">URL du site<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
|
<label for="website_url">URL du site<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
|
||||||
<div class="admin-file-input">
|
<div class="admin-file-input">
|
||||||
<input type="url" id="website_url" name="website_url"
|
<input type="url" id="website_url" name="website_url"
|
||||||
@@ -285,11 +293,14 @@ $hasAnnexesChecked = !empty($_POST['has_annexes']);
|
|||||||
<small>Le TFE sera affiché comme un site embarqué sur sa page publique.</small>
|
<small>Le TFE sera affiché comme un site embarqué sur sa page publique.</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<?php else: ?>
|
||||||
|
<div id="slot-siteweb" hidden></div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<!-- Slot: Video -->
|
||||||
<?php if ($hasVideo): ?>
|
<?php if ($hasVideo): ?>
|
||||||
<?php if ($peerTubeEnabled): ?>
|
<?php if ($peerTubeEnabled): ?>
|
||||||
<div class="admin-form-group">
|
<div id="slot-video" class="admin-form-group">
|
||||||
<label for="peertube_video">Vidéo PeerTube<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
|
<label for="peertube_video">Vidéo PeerTube<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
|
||||||
<div class="admin-file-input">
|
<div class="admin-file-input">
|
||||||
<input type="file" id="peertube_video" name="peertube_video"
|
<input type="file" id="peertube_video" name="peertube_video"
|
||||||
@@ -299,7 +310,7 @@ $hasAnnexesChecked = !empty($_POST['has_annexes']);
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<div class="admin-form-group admin-files-fieldgroup">
|
<div id="slot-video" class="admin-form-group admin-files-fieldgroup">
|
||||||
<label for="video-files-input">Vidéo<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
|
<label for="video-files-input">Vidéo<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
|
||||||
<div class="admin-file-input">
|
<div class="admin-file-input">
|
||||||
<input type="file" id="video-files-input"
|
<input type="file" id="video-files-input"
|
||||||
@@ -312,11 +323,14 @@ $hasAnnexesChecked = !empty($_POST['has_annexes']);
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<div id="slot-video" hidden></div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<!-- Slot: Audio -->
|
||||||
<?php if ($hasAudio): ?>
|
<?php if ($hasAudio): ?>
|
||||||
<?php if ($peerTubeEnabled): ?>
|
<?php if ($peerTubeEnabled): ?>
|
||||||
<div class="admin-form-group">
|
<div id="slot-audio" class="admin-form-group">
|
||||||
<label for="peertube_audio">Audio PeerTube<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
|
<label for="peertube_audio">Audio PeerTube<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
|
||||||
<div class="admin-file-input">
|
<div class="admin-file-input">
|
||||||
<input type="file" id="peertube_audio" name="peertube_audio"
|
<input type="file" id="peertube_audio" name="peertube_audio"
|
||||||
@@ -326,7 +340,7 @@ $hasAnnexesChecked = !empty($_POST['has_annexes']);
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<div class="admin-form-group admin-files-fieldgroup">
|
<div id="slot-audio" class="admin-form-group admin-files-fieldgroup">
|
||||||
<label for="audio-files-input">Audio<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
|
<label for="audio-files-input">Audio<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
|
||||||
<div class="admin-file-input">
|
<div class="admin-file-input">
|
||||||
<input type="file" id="audio-files-input"
|
<input type="file" id="audio-files-input"
|
||||||
@@ -339,6 +353,8 @@ $hasAnnexesChecked = !empty($_POST['has_annexes']);
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<div id="slot-audio" hidden></div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<script>if(window.XamxamInitFilePonds)window.XamxamInitFilePonds();</script>
|
<script>if(window.XamxamInitFilePonds)window.XamxamInitFilePonds();</script>
|
||||||
|
|||||||
@@ -324,6 +324,32 @@
|
|||||||
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||||
+\\\\\\\ to: qwltvwqq 0c33e74c "Replace custom file-upload-queue.js with FilePond" (rebased revision)
|
+\\\\\\\ to: qwltvwqq 0c33e74c "Replace custom file-upload-queue.js with FilePond" (rebased revision)
|
||||||
++ $linkName = $link['name'] ?? '';
|
++ $linkName = $link['name'] ?? '';
|
||||||
|
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: qwltvwqq 0c33e74c "Replace custom file-upload-queue.js with FilePond" (rebased revision)
|
||||||
|
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ to: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||||
|
- $linkName = $link['name'] ?? '';
|
||||||
|
- $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: somsyvxz 14a3cd10 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebase destination)
|
||||||
|
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ to: ztztkrsu 223fb3b3 (rebased revision)
|
||||||
|
$linkName = $link['name'] ?? '';
|
||||||
|
$linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
$linkLockedYear = $link['locked_year'] ?? null;
|
||||||
|
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||||
|
+\\\\\\\ to: ztztkrsu 4234ef1b (rebased revision)
|
||||||
|
++ $linkName = $link['name'] ?? '';
|
||||||
|
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: ztztkrsu 4234ef1b (rebased revision)
|
||||||
|
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ to: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||||
|
- $linkName = $link['name'] ?? '';
|
||||||
|
- $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff from: somsyvxz 14a3cd10 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebase destination)
|
||||||
|
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ to: yuuqpnwp 806e0941 "Fix FilePond integration: decouple format extras from main file inputs" (rebased revision)
|
||||||
|
$linkName = $link['name'] ?? '';
|
||||||
|
$linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
|
$linkLockedYear = $link['locked_year'] ?? null;
|
||||||
|
+%%%%%%% diff from: somsyvxz 249f7943 "Bulk bar anti-shift, tags icons, AP no-wrap, credits reorder" (rebased revision)
|
||||||
|
+\\\\\\\ to: yuuqpnwp 6a989604 "Fix FilePond integration: decouple format extras from main file inputs" (rebased revision)
|
||||||
|
++ $linkName = $link['name'] ?? '';
|
||||||
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
++ $linkExpiresVal = $link['expires_at'] ? date('Y-m-d\TH:i', strtotime($link['expires_at'])) : '';
|
||||||
?>
|
?>
|
||||||
<tr class="admin-table-row" onclick="event.stopPropagation(); window.open('/partage/<?= urlencode($link['slug']) ?>', '_blank')" style="cursor:pointer">
|
<tr class="admin-table-row" onclick="event.stopPropagation(); window.open('/partage/<?= urlencode($link['slug']) ?>', '_blank')" style="cursor:pointer">
|
||||||
|
|||||||
Reference in New Issue
Block a user