Release v2.5.6
This commit is contained in:
@@ -11,12 +11,13 @@ module.exports = function registerAnnouncementRoutes(app, deps) {
|
||||
const { buildPagination } = require('../../../lib/pagination');
|
||||
const announcementData = require('#src/data/announcements');
|
||||
const announcementIcons = require('#src/data/announcement-icons');
|
||||
const { buildDuplicateAnnouncementName, buildDuplicateAnnouncement } = require('./duplicate');
|
||||
|
||||
const LIST_PAGE_SIZE = 25;
|
||||
const ANNOUNCEMENT_TYPES = [
|
||||
{ value: 'lower-third', label: 'Lower third' },
|
||||
{ value: 'fullscreen', label: 'Fullscreen' },
|
||||
{ value: 'top-banner', label: 'Top banner' }
|
||||
{ value: 'lower-third', label: 'Lower third', icon: 'arrow-bar-down' },
|
||||
{ value: 'fullscreen', label: 'Fullscreen', icon: 'arrows-fullscreen' },
|
||||
{ value: 'top-banner', label: 'Top banner', icon: 'arrow-bar-up' }
|
||||
];
|
||||
const ANNOUNCEMENT_COLORS = [
|
||||
{ value: 'primary', label: 'Primary' },
|
||||
@@ -63,8 +64,7 @@ module.exports = function registerAnnouncementRoutes(app, deps) {
|
||||
}
|
||||
|
||||
function isAnnouncementDeletionBlocked(announcement) {
|
||||
const screenIds = Array.isArray(announcement && announcement.screen_ids) ? announcement.screen_ids : [];
|
||||
return isAnnouncementActive(announcement) || screenIds.length > 0;
|
||||
return isAnnouncementActive(announcement);
|
||||
}
|
||||
|
||||
async function fetchAllScreenSlugs() {
|
||||
@@ -221,6 +221,10 @@ module.exports = function registerAnnouncementRoutes(app, deps) {
|
||||
const durationMode = String(normalized.durationMode || '').trim() || (durationSeconds > 0 ? 'duration' : 'until_disabled');
|
||||
const isActive = isAnnouncementActive(normalized);
|
||||
const canDelete = Boolean(normalized.id) && !isAnnouncementDeletionBlocked(normalized);
|
||||
const hasTargets = Array.isArray(normalized.screen_ids) && normalized.screen_ids.length > 0;
|
||||
const deleteBlockedMessage = canDelete
|
||||
? ''
|
||||
: 'This announcement is currently active and cannot be deleted.';
|
||||
|
||||
return Object.assign({}, normalized, {
|
||||
durationMode: durationMode,
|
||||
@@ -230,7 +234,11 @@ module.exports = function registerAnnouncementRoutes(app, deps) {
|
||||
isActive: isActive,
|
||||
actionLabel: isActive ? 'Stop' : 'Play',
|
||||
actionIcon: isActive ? 'bi-stop-fill' : 'bi-play-fill',
|
||||
actionClassName: isActive ? 'btn-outline-warning' : 'btn-outline-success',
|
||||
actionDisabled: !isActive && !hasTargets,
|
||||
actionClassName: !isActive && !hasTargets
|
||||
? 'btn-outline-info'
|
||||
: (isActive ? 'btn-outline-warning' : 'btn-info'),
|
||||
actionDisabledTitle: !isActive && !hasTargets ? 'Select at least one screen group to play this announcement.' : '',
|
||||
actionConfirmMessage: isActive
|
||||
? 'Stop this announcement on the selected screens now?'
|
||||
: 'Send this announcement to the selected screens now?',
|
||||
@@ -238,7 +246,7 @@ module.exports = function registerAnnouncementRoutes(app, deps) {
|
||||
? `/announcements/${normalized.id}/stop`
|
||||
: `/announcements/${normalized.id}/play`,
|
||||
canDelete: canDelete,
|
||||
deleteBlockedMessage: canDelete ? '' : 'This announcement is still in use by one or more screens.'
|
||||
deleteBlockedMessage: deleteBlockedMessage
|
||||
});
|
||||
}
|
||||
|
||||
@@ -301,6 +309,33 @@ module.exports = function registerAnnouncementRoutes(app, deps) {
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/announcements/:id/duplicate', requirePermission('announcements.read'), requirePermission('announcements.create'), async function (req, res, next) {
|
||||
try {
|
||||
const announcement = await common.fetchAnnouncementById(pool, Number(req.params.id));
|
||||
if (!announcement) {
|
||||
return res.status(404).send('Announcement not found');
|
||||
}
|
||||
|
||||
const screens = await fetchAnnouncementScreens();
|
||||
let duplicateName = buildDuplicateAnnouncementName(announcement.short_label || announcement.message || 'Announcement');
|
||||
let duplicateIndex = 2;
|
||||
while (await common.fetchDuplicateName(pool, 'd_announcements', duplicateName, null, 'short_label')) {
|
||||
duplicateName = buildDuplicateAnnouncementName(announcement.short_label || announcement.message || 'Announcement') + ' (' + duplicateIndex + ')';
|
||||
duplicateIndex += 1;
|
||||
}
|
||||
|
||||
res.send(pages.renderAnnouncementAddPage(buildAnnouncementFormData(buildDuplicateAnnouncement(announcement, duplicateName)), req.query.message ? String(req.query.message) : 'Review the copied values and save when ready.', req.currentUser, {
|
||||
announcementTypes: ANNOUNCEMENT_TYPES,
|
||||
announcementColors: ANNOUNCEMENT_COLORS,
|
||||
announcementIcons: ANNOUNCEMENT_ICONS,
|
||||
announcementScreens: buildAnnouncementScreenOptions(screens, announcement.screen_ids || []),
|
||||
messageVariant: 'info'
|
||||
}));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/announcements', requirePermission('announcements.create'), async function (req, res, next) {
|
||||
try {
|
||||
const message = String(req.body.message || '').replace(/\r\n/g, '\n').trim();
|
||||
@@ -421,7 +456,7 @@ module.exports = function registerAnnouncementRoutes(app, deps) {
|
||||
}
|
||||
|
||||
if (isAnnouncementDeletionBlocked(announcement)) {
|
||||
return res.redirect('/announcements/' + announcement.id + '/edit?message=' + encodeURIComponent('This announcement is still in use by one or more screens.'));
|
||||
return res.redirect('/announcements/' + announcement.id + '/edit?message=' + encodeURIComponent('This announcement is currently active and cannot be deleted.'));
|
||||
}
|
||||
|
||||
await pool.query('DELETE FROM d_announcements WHERE id = ?', [announcement.id]);
|
||||
|
||||
Reference in New Issue
Block a user