Add copy buttons to Media Info

This commit is contained in:
Dmitry Lyzo 2022-02-23 00:36:00 +03:00
parent 7239269980
commit 1f62db7f31
4 changed files with 38 additions and 4 deletions

View file

@ -992,6 +992,10 @@ div.itemDetailGalleryLink.defaultCardBackground {
border-collapse: collapse; border-collapse: collapse;
} }
.mediaInfoContent .btnCopy .material-icons {
font-size: inherit;
}
.mediaInfoStream { .mediaInfoStream {
margin: 0 3em 0 0; margin: 0 3em 0 0;
display: inline-block; display: inline-block;
@ -1000,6 +1004,10 @@ div.itemDetailGalleryLink.defaultCardBackground {
.mediaInfoStreamType { .mediaInfoStreamType {
display: block; display: block;
margin: 0.622em 0; /* copy button height compensation */
}
.layout-tv .mediaInfoStreamType {
margin: 1em 0; margin: 1em 0;
} }

View file

@ -7,6 +7,9 @@
import dialogHelper from '../dialogHelper/dialogHelper'; import dialogHelper from '../dialogHelper/dialogHelper';
import layoutManager from '../layoutManager'; import layoutManager from '../layoutManager';
import toast from '../toast/toast';
import { copy } from '../../scripts/clipboard';
import dom from '../../scripts/dom';
import globalize from '../../scripts/globalize'; import globalize from '../../scripts/globalize';
import loading from '../loading/loading'; import loading from '../loading/loading';
import '../../elements/emby-select/emby-select'; import '../../elements/emby-select/emby-select';
@ -19,6 +22,12 @@ import '../../assets/css/flexstyles.scss';
import ServerConnections from '../ServerConnections'; import ServerConnections from '../ServerConnections';
import template from './itemMediaInfo.template.html'; import template from './itemMediaInfo.template.html';
// Do not add extra spaces between tags - they will be copied into the result
const copyButtonHtml = layoutManager.tv ? '' :
`<button is="paper-icon-button-light" class="btnCopy" title="${globalize.translate('Copy')}" aria-label="${globalize.translate('Copy')}"
><span class="material-icons content_copy" aria-hidden="true"></span></button>`;
const attributeDelimiterHtml = layoutManager.tv ? '' : '<span class="hide">: </span>';
function setMediaInfo(user, page, item) { function setMediaInfo(user, page, item) {
let html = item.MediaSources.map(version => { let html = item.MediaSources.map(version => {
return getMediaSourceHtml(user, item, version); return getMediaSourceHtml(user, item, version);
@ -28,12 +37,24 @@ import template from './itemMediaInfo.template.html';
} }
const mediaInfoContent = page.querySelector('#mediaInfoContent'); const mediaInfoContent = page.querySelector('#mediaInfoContent');
mediaInfoContent.innerHTML = html; mediaInfoContent.innerHTML = html;
for (const btn of mediaInfoContent.querySelectorAll('.btnCopy')) {
btn.addEventListener('click', () => {
const infoBlock = dom.parentWithClass(btn, 'mediaInfoStream') || dom.parentWithClass(btn, 'mediaInfoSource') || mediaInfoContent;
copy(infoBlock.textContent).then(() => {
toast(globalize.translate('Copied'));
}).catch(() => {
console.error('Could not copy text');
});
});
}
} }
function getMediaSourceHtml(user, item, version) { function getMediaSourceHtml(user, item, version) {
let html = ''; let html = '<div class="mediaInfoSource">';
if (version.Name) { if (version.Name) {
html += `<div><h2 class="mediaInfoStreamType">${version.Name}</h2></div>`; html += `<div><h2 class="mediaInfoStreamType">${version.Name}${copyButtonHtml}</h2></div>\n`;
} }
if (version.Container) { if (version.Container) {
html += `${createAttribute(globalize.translate('MediaInfoContainer'), version.Container)}<br/>`; html += `${createAttribute(globalize.translate('MediaInfoContainer'), version.Container)}<br/>`;
@ -69,7 +90,7 @@ import template from './itemMediaInfo.template.html';
} }
const displayType = globalize.translate(translateString); const displayType = globalize.translate(translateString);
html += `<h2 class="mediaInfoStreamType">${displayType}</h2>`; html += `\n<h2 class="mediaInfoStreamType">${displayType}${copyButtonHtml}</h2>\n`;
const attributes = []; const attributes = [];
if (stream.DisplayTitle) { if (stream.DisplayTitle) {
attributes.push(createAttribute(globalize.translate('MediaInfoTitle'), stream.DisplayTitle)); attributes.push(createAttribute(globalize.translate('MediaInfoTitle'), stream.DisplayTitle));
@ -154,11 +175,12 @@ import template from './itemMediaInfo.template.html';
html += attributes.join('<br/>'); html += attributes.join('<br/>');
html += '</div>'; html += '</div>';
} }
html += '</div>';
return html; return html;
} }
function createAttribute(label, value) { function createAttribute(label, value) {
return `<span class="mediaInfoLabel">${label}</span><span class="mediaInfoAttribute">${value}</span>`; return `<span class="mediaInfoLabel">${label}</span>${attributeDelimiterHtml}<span class="mediaInfoAttribute">${value}</span>\n`;
} }
function loadMediaInfo(itemId, serverId) { function loadMediaInfo(itemId, serverId) {

View file

@ -148,6 +148,8 @@
"Console": "Console", "Console": "Console",
"ContinueWatching": "Continue watching", "ContinueWatching": "Continue watching",
"Continuing": "Continuing", "Continuing": "Continuing",
"Copied": "Copied",
"Copy": "Copy",
"CopyStreamURL": "Copy Stream URL", "CopyStreamURL": "Copy Stream URL",
"CopyStreamURLSuccess": "URL copied successfully.", "CopyStreamURLSuccess": "URL copied successfully.",
"CriticRating": "Critics rating", "CriticRating": "Critics rating",

View file

@ -121,6 +121,8 @@
"Connect": "Соединиться", "Connect": "Соединиться",
"ContinueWatching": "Продолжение просмотра", "ContinueWatching": "Продолжение просмотра",
"Continuing": "Продолжаемое", "Continuing": "Продолжаемое",
"Copied": "Скопировано",
"Copy": "Копировать",
"CriticRating": "Оценка критиков", "CriticRating": "Оценка критиков",
"CustomDlnaProfilesHelp": "Создайте настраиваемый профиль, назначаемый для нового устройства или переопределите системный профиль.", "CustomDlnaProfilesHelp": "Создайте настраиваемый профиль, назначаемый для нового устройства или переопределите системный профиль.",
"DateAdded": "Дата добавления", "DateAdded": "Дата добавления",