diff --git a/src/assets/css/librarybrowser.scss b/src/assets/css/librarybrowser.scss index 691e50bf8..dd747c42b 100644 --- a/src/assets/css/librarybrowser.scss +++ b/src/assets/css/librarybrowser.scss @@ -992,6 +992,10 @@ div.itemDetailGalleryLink.defaultCardBackground { border-collapse: collapse; } +.mediaInfoContent .btnCopy .material-icons { + font-size: inherit; +} + .mediaInfoStream { margin: 0 3em 0 0; display: inline-block; @@ -1000,6 +1004,10 @@ div.itemDetailGalleryLink.defaultCardBackground { .mediaInfoStreamType { display: block; + margin: 0.622em 0; /* copy button height compensation */ +} + +.layout-tv .mediaInfoStreamType { margin: 1em 0; } diff --git a/src/components/itemMediaInfo/itemMediaInfo.js b/src/components/itemMediaInfo/itemMediaInfo.js index 37d19dc80..30f168b21 100644 --- a/src/components/itemMediaInfo/itemMediaInfo.js +++ b/src/components/itemMediaInfo/itemMediaInfo.js @@ -7,6 +7,9 @@ import dialogHelper from '../dialogHelper/dialogHelper'; 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 loading from '../loading/loading'; import '../../elements/emby-select/emby-select'; @@ -19,6 +22,12 @@ import '../../assets/css/flexstyles.scss'; import ServerConnections from '../ServerConnections'; import template from './itemMediaInfo.template.html'; +// Do not add extra spaces between tags - they will be copied into the result +const copyButtonHtml = layoutManager.tv ? '' : + ``; +const attributeDelimiterHtml = layoutManager.tv ? '' : ': '; + function setMediaInfo(user, page, item) { let html = item.MediaSources.map(version => { return getMediaSourceHtml(user, item, version); @@ -28,12 +37,24 @@ import template from './itemMediaInfo.template.html'; } const mediaInfoContent = page.querySelector('#mediaInfoContent'); 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) { - let html = ''; + let html = '