| | document.body.style.paddingRight = `${window.innerWidth - document.body.clientWidth}px`; |
| | document.body.style.overflow = 'hidden'; |
| | const internalConfig = { |
| | 'network': { |
| | 'userAgent': { |
| | 'chromeWindows': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', |
| | 'curl': 'curl/8.4.0', |
| | 'curlUnity': 'UnityPlayer/2021.3.14f1 (UnityWebRequest/1.0, libcurl/7.84.0-DEV)' |
| | }, |
| | 'timeout': 15000 |
| | } |
| | }; |
| | const apiConnectDefaultHeader = { |
| | 'Access-Controll-Allow-Origin': '*' |
| | } |
| | const appSettingsStorageName = '018d2fc7-d0bb-7393-9ebc-6f6ec26b03ce_appSettings'; |
| | let appSettingsSaveData = new Object(); |
| | const appSettingsSaveDataDefault = { |
| | 'ui': { |
| | 'uiThemeMode': 'light' |
| | } |
| | }; |
| | let apiDataMasterDB = new Object(); |
| | let apiDataConfig = new Object(); |
| | let bootstrapTooltipList = null; |
| |
|
| | |
| |
|
| | window.addEventListener('load', async function(){ |
| | if (checkAppSettingsExistsOnStorage() === true) { |
| | loadAppSettingsFromLocalStorage(); |
| | } else { |
| | loadAppSettingsFromLocalStorage(); |
| | if (window.matchMedia('(prefers-color-scheme:dark)').matches === true) { |
| | console.warn(`prefers-color-scheme:dark detected`); |
| | if (appSettingsSaveData.ui.uiThemeMode !== 'dark') { |
| | appSettingsSaveData.ui.uiThemeMode = 'dark'; |
| | writeAppSettingsToLocalStorage(); |
| | } |
| | } else { |
| | appSettingsSaveData.ui.uiThemeMode = 'light'; |
| | writeAppSettingsToLocalStorage(); |
| | } |
| | } |
| | appSettingsCheckedUiUpdate(); |
| | appSettingsApply(); |
| | await loadRequiredDatabase(); |
| | await decryptConfig(); |
| | pushToTrackListGroupUi(); |
| | pushToAlbumListGroupUi(); |
| | fsOverlayLoadingScrControl(); |
| | }); |
| |
|
| | document.querySelector('#loadDatabaseTestButton').addEventListener('click', async function() { |
| | console.log('loadDatabaseTestButton clicked!'); |
| | await loadRequiredDatabase(); |
| | await decryptConfig(); |
| | }); |
| |
|
| | document.querySelector('#trackListingTestButton').addEventListener('click', () => { |
| | console.log('trackListingTestButton clicked!'); |
| | pushToTrackListGroupUi(); |
| | }); |
| |
|
| | |
| |
|
| | function fsOverlayLoadingScrControl () { |
| | document.getElementById('fsOverlayLoadingScr').style.backgroundColor = 'rgba(0,0,0,0)'; |
| | document.getElementById('fsOverlayLoadingScr').style.visibility = 'hidden'; |
| | document.getElementById('fsOverlayLoadingScr').style.backdropFilter = 'blur(0)'; |
| | document.getElementById('fsOverlayLoadingScr_loadingSpinner').style.opacity = 0; |
| | document.body.style.paddingRight = 0; |
| | document.body.style.overflow = 'auto'; |
| | } |
| |
|
| | |
| |
|
| | function pushToTrackListGroupUi () { |
| | const trackAllListGroup = document.querySelector('#trackAllListGroup'); |
| | while(trackAllListGroup.firstChild) { |
| | trackAllListGroup.removeChild(trackAllListGroup.firstChild); |
| | } |
| | let headerElObj = new Object(); |
| | headerElObj.buttonNodeEl = document.createElement('button'); |
| | headerElObj.divArtistNodeEl = document.createElement('div'); |
| | headerElObj.divAlbumNodeEl = document.createElement('div'); |
| | headerElObj.divTrackNodeEl = document.createElement('div'); |
| | headerElObj.buttonNodeEl.classList.add('list-group-item', 'list-group-item-action', 'd-flex'); |
| | headerElObj.buttonNodeEl.setAttribute('type', 'button'); |
| | headerElObj.buttonNodeEl.disabled = true; |
| | headerElObj.divArtistNodeEl.classList.add('flex-fill', 'w-100'); |
| | headerElObj.divAlbumNodeEl.classList.add('flex-fill', 'w-100'); |
| | headerElObj.divTrackNodeEl.classList.add('flex-fill', 'w-100'); |
| | headerElObj.divArtistNodeEl.innerHTML = 'Artist'; |
| | headerElObj.divAlbumNodeEl.innerHTML = 'Album'; |
| | headerElObj.divTrackNodeEl.innerHTML = 'Track'; |
| | headerElObj.buttonNodeEl.appendChild(headerElObj.divArtistNodeEl); |
| | headerElObj.buttonNodeEl.appendChild(headerElObj.divAlbumNodeEl); |
| | headerElObj.buttonNodeEl.appendChild(headerElObj.divTrackNodeEl); |
| | trackAllListGroup.appendChild(headerElObj.buttonNodeEl); |
| | apiDataMasterDB.response.data.albums.forEach((albumObject) => { |
| | albumObject.tracks.forEach((trackObject) => { |
| | let buttonNodeEl = document.createElement('button'); |
| | let divArtistNodeEl = document.createElement('div'); |
| | let divAlbumNodeEl = document.createElement('div'); |
| | let divTrackNodeEl = document.createElement('div'); |
| | buttonNodeEl.classList.add('list-group-item', 'list-group-item-action', 'd-flex'); |
| | buttonNodeEl.setAttribute('type', 'button'); |
| | buttonNodeEl.setAttribute('data-track-uuid', trackObject.uuid); |
| | divArtistNodeEl.classList.add('flex-fill', 'w-100'); |
| | divAlbumNodeEl.classList.add('flex-fill', 'w-100'); |
| | divTrackNodeEl.classList.add('flex-fill', 'w-100'); |
| | let albumArtistFilteredList = new Array(); |
| | albumObject.artist.forEach((str) => { |
| | albumArtistFilteredList.push(apiDataMasterDB.response.data.artists.filter((obj) => obj.uuid === str)[0].name); |
| | }); |
| | divArtistNodeEl.innerHTML = albumArtistFilteredList.join(', '); |
| | divAlbumNodeEl.innerHTML = albumObject.title; |
| | divTrackNodeEl.innerHTML = trackObject.title; |
| | buttonNodeEl.appendChild(divArtistNodeEl); |
| | buttonNodeEl.appendChild(divAlbumNodeEl); |
| | buttonNodeEl.appendChild(divTrackNodeEl); |
| | buttonNodeEl.addEventListener('click', () => { |
| | loadTrackInfoModal(trackObject.uuid); |
| | }); |
| | trackAllListGroup.appendChild(buttonNodeEl); |
| | }); |
| | }); |
| | } |
| |
|
| | |
| |
|
| | function pushToAlbumListGroupUi () { |
| | const albumAllCardGroup = document.getElementById('albumAllCardGroup'); |
| | while(albumAllCardGroup.firstChild) { |
| | albumAllCardGroup.removeChild(albumAllCardGroup.firstChild); |
| | } |
| | apiDataMasterDB.response.data.albums.forEach((albumObject) => { |
| | let albumParsedObject = getParsedAlbumObjectFromAlbumUuid(albumObject.uuid); |
| | let elementObj = new Object(); |
| | elementObj.colDiv = document.createElement('div'); |
| | elementObj.cardDiv = document.createElement('div'); |
| | elementObj.cardBodyDiv = document.createElement('div'); |
| | elementObj.cardImgDiv = document.createElement('div'); |
| | elementObj.cardImg = document.createElement('img'); |
| | elementObj.cardTitle = document.createElement('h5'); |
| | elementObj.cardText = document.createElement('p'); |
| | elementObj.colDiv.classList.add('col'); |
| | elementObj.cardDiv.classList.add('card', 'h-100'); |
| | elementObj.cardBodyDiv.classList.add('card-body'); |
| | elementObj.cardImgDiv.classList.add('object-fit-cover', 'cs_card-img-wrapper') |
| | elementObj.cardImg.classList.add('card-img-top', 'object-fit-cover', 'lazyload', 'customlazyload-blur', 'user-select-none', 'user-drag-none', 'pe-none'); |
| | elementObj.cardTitle.classList.add('card-title'); |
| | elementObj.cardText.classList.add('card-text'); |
| | elementObj.cardImg.src = `data:image/webp;base64,${albumObject.coverArtPotatoWebp16pxBase64}`; |
| | |
| | elementObj.cardImg.setAttribute('data-src', `${apiDataConfig.response.config.decrypted.rawMediaUrlBase64}/media/${albumParsedObject.uuid}/${albumParsedObject.coverArts.slice(-1)[0].fileName}.${albumParsedObject.coverArts.slice(-1)[0].format[0].extension}`); |
| | |
| | elementObj.cardTitle.innerHTML = albumParsedObject.title; |
| | elementObj.cardText.innerHTML = albumParsedObject.artist.map((obj) => obj.name).join(', '); |
| | elementObj.cardBodyDiv.appendChild(elementObj.cardTitle); |
| | elementObj.cardBodyDiv.appendChild(elementObj.cardText); |
| | elementObj.cardImgDiv.appendChild(elementObj.cardImg); |
| | elementObj.cardDiv.appendChild(elementObj.cardImgDiv); |
| | elementObj.cardDiv.appendChild(elementObj.cardBodyDiv); |
| | elementObj.cardDiv.addEventListener('click', () => {loadAlbumInfoModal(albumParsedObject.uuid)}); |
| | elementObj.colDiv.appendChild(elementObj.cardDiv); |
| | albumAllCardGroup.appendChild(elementObj.colDiv); |
| | }); |
| | } |
| |
|
| | |
| |
|
| | function loadTrackInfoModal (trackUuid) { |
| | const albumParsedObject = getParsedAlbumObjectFromAlbumUuid(getAlbumUuidFromTrackUuid(trackUuid)); |
| | const trackParsedObject = albumParsedObject.tracks.find((obj) => obj.uuid === trackUuid); |
| | if (bootstrapTooltipList !== null) {bootstrapTooltipList.forEach(el => el.dispose())} |
| | document.getElementById('trackInfoModal-metadataTable-trackTitle').innerHTML = trackParsedObject.title; |
| | if (trackParsedObject.titleLatin === null) { |
| | document.getElementById('trackInfoModal-metadataTable-trackTitle').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal-metadataTable-trackTitle').removeAttribute('data-bs-title'); |
| | } else { |
| | document.getElementById('trackInfoModal-metadataTable-trackTitle').setAttribute('data-bs-toggle', 'tooltip'); |
| | document.getElementById('trackInfoModal-metadataTable-trackTitle').setAttribute('data-bs-title', trackParsedObject.titleLatin); |
| | } |
| | document.getElementById('trackInfoModal-metadataTable-artists').innerHTML = trackParsedObject.artist.map((obj) => obj.name).join(', '); |
| | if (trackParsedObject.artist.some((obj) => obj.nameLatin !== null)) { |
| | document.getElementById('trackInfoModal-metadataTable-artists').setAttribute('data-bs-toggle', 'tooltip'); |
| | document.getElementById('trackInfoModal-metadataTable-artists').setAttribute('data-bs-title', trackParsedObject.artist.map((obj) => {if (obj.nameLatin !== null) {return obj.nameLatin} else {return obj.name}}).join(', ')); |
| | } else { |
| | document.getElementById('trackInfoModal-metadataTable-artists').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal-metadataTable-artists').removeAttribute('data-bs-title'); |
| | } |
| | if (trackParsedObject.lyricist === null) { |
| | document.getElementById('trackInfoModal-metadataTable-lyricist').parentNode.classList.add('d-none'); |
| | document.getElementById('trackInfoModal-metadataTable-lyricist').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal-metadataTable-lyricist').removeAttribute('data-bs-title'); |
| | } else { |
| | document.getElementById('trackInfoModal-metadataTable-lyricist').parentNode.classList.remove('d-none'); |
| | document.getElementById('trackInfoModal-metadataTable-lyricist').innerHTML = trackParsedObject.lyricist.map((obj) => obj.name).join(', '); |
| | if (trackParsedObject.lyricist.some((obj) => obj.nameLatin !== null)) { |
| | document.getElementById('trackInfoModal-metadataTable-lyricist').setAttribute('data-bs-toggle', 'tooltip'); |
| | document.getElementById('trackInfoModal-metadataTable-lyricist').setAttribute('data-bs-title', trackParsedObject.lyricist.map((obj) => {if (obj.nameLatin !== null) {return obj.nameLatin} else {return obj.name}}).join(', ')); |
| | } else { |
| | document.getElementById('trackInfoModal-metadataTable-lyricist').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal-metadataTable-lyricist').removeAttribute('data-bs-title'); |
| | } |
| | } |
| | if (trackParsedObject.composer === null) { |
| | document.getElementById('trackInfoModal-metadataTable-composer').parentNode.classList.add('d-none'); |
| | document.getElementById('trackInfoModal-metadataTable-composer').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal-metadataTable-composer').removeAttribute('data-bs-title'); |
| | } else { |
| | document.getElementById('trackInfoModal-metadataTable-composer').parentNode.classList.remove('d-none'); |
| | document.getElementById('trackInfoModal-metadataTable-composer').innerHTML = trackParsedObject.composer.map((obj) => obj.name).join(', '); |
| | if (trackParsedObject.composer.some((obj) => obj.nameLatin !== null)) { |
| | document.getElementById('trackInfoModal-metadataTable-composer').setAttribute('data-bs-toggle', 'tooltip'); |
| | document.getElementById('trackInfoModal-metadataTable-composer').setAttribute('data-bs-title', trackParsedObject.composer.map((obj) => {if (obj.nameLatin !== null) {return obj.nameLatin} else {return obj.name}}).join(', ')); |
| | } else { |
| | document.getElementById('trackInfoModal-metadataTable-composer').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal-metadataTable-composer').removeAttribute('data-bs-title'); |
| | } |
| | } |
| | if (trackParsedObject.arranger === null) { |
| | document.getElementById('trackInfoModal-metadataTable-arranger').parentNode.classList.add('d-none'); |
| | document.getElementById('trackInfoModal-metadataTable-arranger').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal-metadataTable-arranger').removeAttribute('data-bs-title'); |
| | } else { |
| | document.getElementById('trackInfoModal-metadataTable-arranger').parentNode.classList.remove('d-none'); |
| | document.getElementById('trackInfoModal-metadataTable-arranger').innerHTML = trackParsedObject.arranger.map((obj) => obj.name).join(', '); |
| | if (trackParsedObject.arranger.some((obj) => obj.nameLatin !== null)) { |
| | document.getElementById('trackInfoModal-metadataTable-arranger').setAttribute('data-bs-toggle', 'tooltip'); |
| | document.getElementById('trackInfoModal-metadataTable-arranger').setAttribute('data-bs-title', trackParsedObject.arranger.map((obj) => {if (obj.nameLatin !== null) {return obj.nameLatin} else {return obj.name}}).join(', ')); |
| | } else { |
| | document.getElementById('trackInfoModal-metadataTable-arranger').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal-metadataTable-arranger').removeAttribute('data-bs-title'); |
| | } |
| | } |
| | document.getElementById('trackInfoModal-metadataTable-trackDurationReadable').innerHTML = msecToReadableTime(trackParsedObject.durationMsecs); |
| | document.getElementById('trackInfoModal-metadataTable-trackDurationMsec').innerHTML = `${Math.ceil(trackParsedObject.durationMsecs)} ms`; |
| | document.getElementById('trackInfoModal-metadataTable-trackDurationSamples').innerHTML = `${trackParsedObject.durationSamples} samples`; |
| | document.getElementById('trackInfoModal-metadataTable-albumTitle').innerHTML = albumParsedObject.title; |
| | if (albumParsedObject.titleLatin === null) { |
| | document.getElementById('trackInfoModal-metadataTable-albumTitle').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal-metadataTable-albumTitle').removeAttribute('data-bs-title'); |
| | } else { |
| | document.getElementById('trackInfoModal-metadataTable-albumTitle').setAttribute('data-bs-toggle', 'tooltip'); |
| | document.getElementById('trackInfoModal-metadataTable-albumTitle').setAttribute('data-bs-title', albumParsedObject.titleLatin); |
| | } |
| | document.getElementById('trackInfoModal-metadataTable-albumArtist').innerHTML = albumParsedObject.artist.map((obj) => obj.name).join(', '); |
| | if (albumParsedObject.artist.some((obj) => obj.nameLatin !== null)) { |
| | document.getElementById('trackInfoModal-metadataTable-albumArtist').setAttribute('data-bs-toggle', 'tooltip'); |
| | document.getElementById('trackInfoModal-metadataTable-albumArtist').setAttribute('data-bs-title', albumParsedObject.artist.map((obj) => {if (obj.nameLatin !== null) {return obj.nameLatin} else {return obj.name}}).join(', ')); |
| | } else { |
| | document.getElementById('trackInfoModal-metadataTable-albumArtist').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal-metadataTable-albumArtist').removeAttribute('data-bs-title'); |
| | } |
| | document.getElementById('trackInfoModal-metadataTable-albumReleaseDate').innerHTML = moment(albumParsedObject.releaseDate).format('YYYY/MM/DD'); |
| | document.getElementById('trackInfoModal-metadataTable-albumBarcode').innerHTML = albumParsedObject.barCode; |
| | document.getElementById('trackInfoModal-metadataTable-albumCopyright').innerHTML = albumParsedObject.copyright; |
| | while(document.getElementById('trackInfoModal-externalLinkTable').firstChild) { |
| | document.getElementById('trackInfoModal-externalLinkTable').removeChild(document.getElementById('trackInfoModal-externalLinkTable').firstChild); |
| | } |
| | while(document.getElementById('trackInfoModal-coverArtLinkDiv').firstChild) { |
| | document.getElementById('trackInfoModal-coverArtLinkDiv').removeChild(document.getElementById('trackInfoModal-coverArtLinkDiv').firstChild); |
| | } |
| | while(document.getElementById('trackInfoModal-downloadTable').firstChild) { |
| | document.getElementById('trackInfoModal-downloadTable').removeChild(document.getElementById('trackInfoModal-downloadTable').firstChild); |
| | } |
| | if (albumParsedObject.link.itunes !== null || albumParsedObject.link.spotify !== null) { |
| | let temp_extLinkAlbumTrEl = document.createElement('tr'); |
| | let temp_extLinkAlbumTdKeyEl = document.createElement('td'); |
| | let temp_extLinkAlbumTdValueEl = document.createElement('td'); |
| | let temp_extLinkAlbumA1El = document.createElement('a'); |
| | let temp_extLinkAlbumA2El = document.createElement('a'); |
| | temp_extLinkAlbumTdKeyEl.innerHTML = 'Album Link'; |
| | if (albumParsedObject.link.itunes !== null) { |
| | temp_extLinkAlbumA1El.classList.add('btn','btn-outline-primary','btn-sm','me-2'); |
| | temp_extLinkAlbumA1El.setAttribute('href', `https://music.apple.com/album/${albumParsedObject.link.itunes}`); |
| | temp_extLinkAlbumA1El.setAttribute('role', 'button'); |
| | temp_extLinkAlbumA1El.setAttribute('target', '_blank'); |
| | temp_extLinkAlbumA1El.setAttribute('rel', 'noopener noreferrer'); |
| | temp_extLinkAlbumA1El.innerHTML = 'Apple Music'; |
| | temp_extLinkAlbumTdValueEl.appendChild(temp_extLinkAlbumA1El); |
| | } |
| | if (albumParsedObject.link.spotify !== null) { |
| | temp_extLinkAlbumA2El.classList.add('btn','btn-outline-primary','btn-sm','me-2'); |
| | temp_extLinkAlbumA2El.setAttribute('href', `https://open.spotify.com/album/${albumParsedObject.link.spotify}`); |
| | temp_extLinkAlbumA2El.setAttribute('role', 'button'); |
| | temp_extLinkAlbumA2El.setAttribute('target', '_blank'); |
| | temp_extLinkAlbumA2El.setAttribute('rel', 'noopener noreferrer'); |
| | temp_extLinkAlbumA2El.innerHTML = 'Spotify'; |
| | temp_extLinkAlbumTdValueEl.appendChild(temp_extLinkAlbumA2El); |
| | } |
| | temp_extLinkAlbumTrEl.appendChild(temp_extLinkAlbumTdKeyEl); |
| | temp_extLinkAlbumTrEl.appendChild(temp_extLinkAlbumTdValueEl); |
| | document.getElementById('trackInfoModal-externalLinkTable').appendChild(temp_extLinkAlbumTrEl); |
| | } |
| | albumParsedObject.coverArts.forEach((obj1) => { |
| | obj1.format.forEach((obj2) => { |
| | let temp_coverArtAEl = document.createElement('a'); |
| | temp_coverArtAEl.classList.add('btn','btn-primary','btn-sm','me-2','mb-2'); |
| | temp_coverArtAEl.setAttribute('href', `${apiDataConfig.response.config.decrypted.rawMediaUrlBase64}/media/${albumParsedObject.uuid}/${obj1.fileName}.${obj2.extension}`); |
| | temp_coverArtAEl.setAttribute('role', 'button'); |
| | temp_coverArtAEl.setAttribute('target', '_blank'); |
| | temp_coverArtAEl.setAttribute('rel', 'noopener noreferrer'); |
| | temp_coverArtAEl.innerHTML = `${obj2.name} ${obj1.height}px`; |
| | document.getElementById('trackInfoModal-coverArtLinkDiv').appendChild(temp_coverArtAEl); |
| | }); |
| | }); |
| | let temp_codecListImported = new Array(); |
| | if (albumParsedObject.isAllTrackSameCodecs === false) {temp_codecListImported = trackParsedObject.codecs} else {temp_codecListImported = albumParsedObject.codecs} |
| | temp_codecListImported.forEach((obj) => { |
| | let temp_dlTrEl = document.createElement('tr'); |
| | let temp_dlTdCodecEl = document.createElement('td'); |
| | let temp_dlTdInfoEl = document.createElement('td'); |
| | let temp_dlTdBtnEl = document.createElement('td'); |
| | let temp_dlButtonGroupEl = document.createElement('div'); |
| | let temp_dlButtonEl = document.createElement('button'); |
| | let temp_dlButtonExtEl = document.createElement('a'); |
| | let temp_dlButtonIconEl = document.createElement('i'); |
| | let temp_dlButtonExtIconEl = document.createElement('i'); |
| | let temp_codecBitrateTemporal = null; |
| | temp_dlTdCodecEl.innerHTML = obj.nameBasic; |
| | temp_dlTdCodecEl.setAttribute('data-bs-toggle', 'tooltip'); |
| | temp_dlTdCodecEl.setAttribute('data-bs-title', obj.nameLong); |
| | if ((obj.bitRateAvg !== null && obj.bitRateMax !== null) || (obj.bitRateAvg !== null && obj.bitRateMax === null)) { |
| | temp_codecBitrateTemporal = obj.bitRateAvg; |
| | } else { |
| | temp_codecBitrateTemporal = obj.bitRateMax; |
| | } |
| | if (obj.bitDepth === null) { |
| | temp_dlTdInfoEl.innerHTML = `${obj.sampleRate / 1000}kHz ${obj.channelCount}ch ${temp_codecBitrateTemporal / 1000}kbps`; |
| | } else { |
| | temp_dlTdInfoEl.innerHTML = `${obj.bitDepth}bit ${obj.sampleRate / 1000}kHz ${obj.channelCount}ch ${temp_codecBitrateTemporal / 1000}kbps`; |
| | } |
| | if (obj.isOriginal === true) { |
| | temp_dlButtonEl.classList.add('btn', 'btn-primary'); |
| | temp_dlButtonExtEl.classList.add('btn', 'btn-primary', 'text-center'); |
| | } else { |
| | temp_dlButtonEl.classList.add('btn', 'btn-secondary'); |
| | temp_dlButtonExtEl.classList.add('btn', 'btn-secondary', 'text-center'); |
| | } |
| | temp_dlButtonEl.setAttribute('type', 'button'); |
| | |
| | |
| | |
| | temp_dlButtonExtEl.setAttribute('href', `${apiDataConfig.response.config.decrypted.rawMediaUrlBase64}/media/${albumParsedObject.uuid}/${obj.path}/${trackParsedObject.uuid}.${obj.extension}`); |
| | temp_dlButtonExtEl.setAttribute('download', determineDownloadFileName(trackParsedObject.uuid, obj.uuid)); |
| | temp_dlButtonExtEl.setAttribute('role', 'button'); |
| | temp_dlButtonExtEl.setAttribute('target', '_blank'); |
| | temp_dlButtonExtEl.setAttribute('rel', 'noopener noreferrer'); |
| | temp_dlButtonGroupEl.setAttribute('role', 'group'); |
| | temp_dlButtonGroupEl.classList.add('btn-group'); |
| | temp_dlButtonIconEl.classList.add('bi', 'bi-download'); |
| | temp_dlButtonExtIconEl.classList.add('bi', 'bi-box-arrow-up-right'); |
| | temp_dlTdBtnEl.classList.add('text-end'); |
| | temp_dlButtonEl.appendChild(temp_dlButtonIconEl); |
| | temp_dlButtonExtEl.appendChild(temp_dlButtonExtIconEl); |
| | |
| | temp_dlButtonGroupEl.appendChild(temp_dlButtonExtEl); |
| | temp_dlTdBtnEl.appendChild(temp_dlButtonGroupEl); |
| | temp_dlTrEl.appendChild(temp_dlTdCodecEl); |
| | temp_dlTrEl.appendChild(temp_dlTdInfoEl); |
| | temp_dlTrEl.appendChild(temp_dlTdBtnEl); |
| | document.getElementById('trackInfoModal-downloadTable').appendChild(temp_dlTrEl); |
| | }); |
| | document.getElementById('trackInfoModal-previewAudio').src = `${apiDataConfig.response.config.decrypted.rawMediaUrlBase64}/media/${albumParsedObject.uuid}/${temp_codecListImported.slice(-1)[0].path}/${trackParsedObject.uuid}.${temp_codecListImported.slice(-1)[0].extension}`; |
| | const bootstrapTooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]'); |
| | bootstrapTooltipList = [...bootstrapTooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl)); |
| | document.getElementById('trackInfoModal-DebugAcdOutputEl').innerHTML = JSON.stringify(albumParsedObject, '', ' '); |
| | document.getElementById('trackInfoModal-ModalCloseButton').addEventListener('click', () => {allAudioElementStop()}); |
| | document.getElementById('trackInfoModal-ModalCloseIconButton').addEventListener('click', () => {allAudioElementStop()}); |
| | const trackInfoModal = new bootstrap.Modal(document.getElementById('trackInfoModal')); |
| | trackInfoModal.show(); |
| | } |
| | function loadTrackInfoModal2 (trackUuid) { |
| | const albumParsedObject = getParsedAlbumObjectFromAlbumUuid(getAlbumUuidFromTrackUuid(trackUuid)); |
| | const trackParsedObject = albumParsedObject.tracks.find((obj) => obj.uuid === trackUuid); |
| | if (bootstrapTooltipList !== null) {bootstrapTooltipList.forEach(el => el.dispose())} |
| | document.getElementById('trackInfoModal2-metadataTable-trackTitle').innerHTML = trackParsedObject.title; |
| | if (trackParsedObject.titleLatin === null) { |
| | document.getElementById('trackInfoModal2-metadataTable-trackTitle').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal2-metadataTable-trackTitle').removeAttribute('data-bs-title'); |
| | } else { |
| | document.getElementById('trackInfoModal2-metadataTable-trackTitle').setAttribute('data-bs-toggle', 'tooltip'); |
| | document.getElementById('trackInfoModal2-metadataTable-trackTitle').setAttribute('data-bs-title', trackParsedObject.titleLatin); |
| | } |
| | document.getElementById('trackInfoModal2-metadataTable-artists').innerHTML = trackParsedObject.artist.map((obj) => obj.name).join(', '); |
| | if (trackParsedObject.artist.some((obj) => obj.nameLatin !== null)) { |
| | document.getElementById('trackInfoModal2-metadataTable-artists').setAttribute('data-bs-toggle', 'tooltip'); |
| | document.getElementById('trackInfoModal2-metadataTable-artists').setAttribute('data-bs-title', trackParsedObject.artist.map((obj) => {if (obj.nameLatin !== null) {return obj.nameLatin} else {return obj.name}}).join(', ')); |
| | } else { |
| | document.getElementById('trackInfoModal2-metadataTable-artists').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal2-metadataTable-artists').removeAttribute('data-bs-title'); |
| | } |
| | if (trackParsedObject.lyricist === null) { |
| | document.getElementById('trackInfoModal2-metadataTable-lyricist').parentNode.classList.add('d-none'); |
| | document.getElementById('trackInfoModal2-metadataTable-lyricist').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal2-metadataTable-lyricist').removeAttribute('data-bs-title'); |
| | } else { |
| | document.getElementById('trackInfoModal2-metadataTable-lyricist').parentNode.classList.remove('d-none'); |
| | document.getElementById('trackInfoModal2-metadataTable-lyricist').innerHTML = trackParsedObject.lyricist.map((obj) => obj.name).join(', '); |
| | if (trackParsedObject.lyricist.some((obj) => obj.nameLatin !== null)) { |
| | document.getElementById('trackInfoModal2-metadataTable-lyricist').setAttribute('data-bs-toggle', 'tooltip'); |
| | document.getElementById('trackInfoModal2-metadataTable-lyricist').setAttribute('data-bs-title', trackParsedObject.lyricist.map((obj) => {if (obj.nameLatin !== null) {return obj.nameLatin} else {return obj.name}}).join(', ')); |
| | } else { |
| | document.getElementById('trackInfoModal2-metadataTable-lyricist').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal2-metadataTable-lyricist').removeAttribute('data-bs-title'); |
| | } |
| | } |
| | if (trackParsedObject.composer === null) { |
| | document.getElementById('trackInfoModal2-metadataTable-composer').parentNode.classList.add('d-none'); |
| | document.getElementById('trackInfoModal2-metadataTable-composer').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal2-metadataTable-composer').removeAttribute('data-bs-title'); |
| | } else { |
| | document.getElementById('trackInfoModal2-metadataTable-composer').parentNode.classList.remove('d-none'); |
| | document.getElementById('trackInfoModal2-metadataTable-composer').innerHTML = trackParsedObject.composer.map((obj) => obj.name).join(', '); |
| | if (trackParsedObject.composer.some((obj) => obj.nameLatin !== null)) { |
| | document.getElementById('trackInfoModal2-metadataTable-composer').setAttribute('data-bs-toggle', 'tooltip'); |
| | document.getElementById('trackInfoModal2-metadataTable-composer').setAttribute('data-bs-title', trackParsedObject.composer.map((obj) => {if (obj.nameLatin !== null) {return obj.nameLatin} else {return obj.name}}).join(', ')); |
| | } else { |
| | document.getElementById('trackInfoModal2-metadataTable-composer').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal2-metadataTable-composer').removeAttribute('data-bs-title'); |
| | } |
| | } |
| | if (trackParsedObject.arranger === null) { |
| | document.getElementById('trackInfoModal2-metadataTable-arranger').parentNode.classList.add('d-none'); |
| | document.getElementById('trackInfoModal2-metadataTable-arranger').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal2-metadataTable-arranger').removeAttribute('data-bs-title'); |
| | } else { |
| | document.getElementById('trackInfoModal2-metadataTable-arranger').parentNode.classList.remove('d-none'); |
| | document.getElementById('trackInfoModal2-metadataTable-arranger').innerHTML = trackParsedObject.arranger.map((obj) => obj.name).join(', '); |
| | if (trackParsedObject.arranger.some((obj) => obj.nameLatin !== null)) { |
| | document.getElementById('trackInfoModal2-metadataTable-arranger').setAttribute('data-bs-toggle', 'tooltip'); |
| | document.getElementById('trackInfoModal2-metadataTable-arranger').setAttribute('data-bs-title', trackParsedObject.arranger.map((obj) => {if (obj.nameLatin !== null) {return obj.nameLatin} else {return obj.name}}).join(', ')); |
| | } else { |
| | document.getElementById('trackInfoModal2-metadataTable-arranger').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal2-metadataTable-arranger').removeAttribute('data-bs-title'); |
| | } |
| | } |
| | document.getElementById('trackInfoModal2-metadataTable-trackDurationReadable').innerHTML = msecToReadableTime(trackParsedObject.durationMsecs); |
| | document.getElementById('trackInfoModal2-metadataTable-trackDurationMsec').innerHTML = `${Math.ceil(trackParsedObject.durationMsecs)} ms`; |
| | document.getElementById('trackInfoModal2-metadataTable-trackDurationSamples').innerHTML = `${trackParsedObject.durationSamples} samples`; |
| | document.getElementById('trackInfoModal2-metadataTable-albumTitle').innerHTML = albumParsedObject.title; |
| | if (albumParsedObject.titleLatin === null) { |
| | document.getElementById('trackInfoModal2-metadataTable-albumTitle').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal2-metadataTable-albumTitle').removeAttribute('data-bs-title'); |
| | } else { |
| | document.getElementById('trackInfoModal2-metadataTable-albumTitle').setAttribute('data-bs-toggle', 'tooltip'); |
| | document.getElementById('trackInfoModal2-metadataTable-albumTitle').setAttribute('data-bs-title', albumParsedObject.titleLatin); |
| | } |
| | document.getElementById('trackInfoModal2-metadataTable-albumArtist').innerHTML = albumParsedObject.artist.map((obj) => obj.name).join(', '); |
| | if (albumParsedObject.artist.some((obj) => obj.nameLatin !== null)) { |
| | document.getElementById('trackInfoModal2-metadataTable-albumArtist').setAttribute('data-bs-toggle', 'tooltip'); |
| | document.getElementById('trackInfoModal2-metadataTable-albumArtist').setAttribute('data-bs-title', albumParsedObject.artist.map((obj) => {if (obj.nameLatin !== null) {return obj.nameLatin} else {return obj.name}}).join(', ')); |
| | } else { |
| | document.getElementById('trackInfoModal2-metadataTable-albumArtist').removeAttribute('data-bs-toggle'); |
| | document.getElementById('trackInfoModal2-metadataTable-albumArtist').removeAttribute('data-bs-title'); |
| | } |
| | document.getElementById('trackInfoModal2-metadataTable-albumReleaseDate').innerHTML = moment(albumParsedObject.releaseDate).format('YYYY/MM/DD'); |
| | document.getElementById('trackInfoModal2-metadataTable-albumBarcode').innerHTML = albumParsedObject.barCode; |
| | document.getElementById('trackInfoModal2-metadataTable-albumCopyright').innerHTML = albumParsedObject.copyright; |
| | while(document.getElementById('trackInfoModal2-externalLinkTable').firstChild) { |
| | document.getElementById('trackInfoModal2-externalLinkTable').removeChild(document.getElementById('trackInfoModal2-externalLinkTable').firstChild); |
| | } |
| | while(document.getElementById('trackInfoModal2-coverArtLinkDiv').firstChild) { |
| | document.getElementById('trackInfoModal2-coverArtLinkDiv').removeChild(document.getElementById('trackInfoModal2-coverArtLinkDiv').firstChild); |
| | } |
| | while(document.getElementById('trackInfoModal2-downloadTable').firstChild) { |
| | document.getElementById('trackInfoModal2-downloadTable').removeChild(document.getElementById('trackInfoModal2-downloadTable').firstChild); |
| | } |
| | if (albumParsedObject.link.itunes !== null || albumParsedObject.link.spotify !== null) { |
| | let temp_extLinkAlbumTrEl = document.createElement('tr'); |
| | let temp_extLinkAlbumTdKeyEl = document.createElement('td'); |
| | let temp_extLinkAlbumTdValueEl = document.createElement('td'); |
| | let temp_extLinkAlbumA1El = document.createElement('a'); |
| | let temp_extLinkAlbumA2El = document.createElement('a'); |
| | temp_extLinkAlbumTdKeyEl.innerHTML = 'Album Link'; |
| | if (albumParsedObject.link.itunes !== null) { |
| | temp_extLinkAlbumA1El.classList.add('btn','btn-outline-primary','btn-sm','me-2'); |
| | temp_extLinkAlbumA1El.setAttribute('href', `https://music.apple.com/album/${albumParsedObject.link.itunes}`); |
| | temp_extLinkAlbumA1El.setAttribute('role', 'button'); |
| | temp_extLinkAlbumA1El.setAttribute('target', '_blank'); |
| | temp_extLinkAlbumA1El.setAttribute('rel', 'noopener noreferrer'); |
| | temp_extLinkAlbumA1El.innerHTML = 'Apple Music'; |
| | temp_extLinkAlbumTdValueEl.appendChild(temp_extLinkAlbumA1El); |
| | } |
| | if (albumParsedObject.link.spotify !== null) { |
| | temp_extLinkAlbumA2El.classList.add('btn','btn-outline-primary','btn-sm','me-2'); |
| | temp_extLinkAlbumA2El.setAttribute('href', `https://open.spotify.com/album/${albumParsedObject.link.spotify}`); |
| | temp_extLinkAlbumA2El.setAttribute('role', 'button'); |
| | temp_extLinkAlbumA2El.setAttribute('target', '_blank'); |
| | temp_extLinkAlbumA2El.setAttribute('rel', 'noopener noreferrer'); |
| | temp_extLinkAlbumA2El.innerHTML = 'Spotify'; |
| | temp_extLinkAlbumTdValueEl.appendChild(temp_extLinkAlbumA2El); |
| | } |
| | temp_extLinkAlbumTrEl.appendChild(temp_extLinkAlbumTdKeyEl); |
| | temp_extLinkAlbumTrEl.appendChild(temp_extLinkAlbumTdValueEl); |
| | document.getElementById('trackInfoModal2-externalLinkTable').appendChild(temp_extLinkAlbumTrEl); |
| | } |
| | albumParsedObject.coverArts.forEach((obj1) => { |
| | obj1.format.forEach((obj2) => { |
| | let temp_coverArtAEl = document.createElement('a'); |
| | temp_coverArtAEl.classList.add('btn','btn-primary','btn-sm','me-2','mb-2'); |
| | temp_coverArtAEl.setAttribute('href', `${apiDataConfig.response.config.decrypted.rawMediaUrlBase64}/media/${albumParsedObject.uuid}/${obj1.fileName}.${obj2.extension}`); |
| | temp_coverArtAEl.setAttribute('role', 'button'); |
| | temp_coverArtAEl.setAttribute('target', '_blank'); |
| | temp_coverArtAEl.setAttribute('rel', 'noopener noreferrer'); |
| | temp_coverArtAEl.innerHTML = `${obj2.name} ${obj1.height}px`; |
| | document.getElementById('trackInfoModal2-coverArtLinkDiv').appendChild(temp_coverArtAEl); |
| | }); |
| | }); |
| | let temp_codecListImported = new Array(); |
| | if (albumParsedObject.isAllTrackSameCodecs === false) {temp_codecListImported = trackParsedObject.codecs} else {temp_codecListImported = albumParsedObject.codecs} |
| | temp_codecListImported.forEach((obj) => { |
| | let temp_dlTrEl = document.createElement('tr'); |
| | let temp_dlTdCodecEl = document.createElement('td'); |
| | let temp_dlTdInfoEl = document.createElement('td'); |
| | let temp_dlTdBtnEl = document.createElement('td'); |
| | let temp_dlButtonGroupEl = document.createElement('div'); |
| | let temp_dlButtonEl = document.createElement('button'); |
| | let temp_dlButtonExtEl = document.createElement('a'); |
| | let temp_dlButtonIconEl = document.createElement('i'); |
| | let temp_dlButtonExtIconEl = document.createElement('i'); |
| | let temp_codecBitrateTemporal = null; |
| | temp_dlTdCodecEl.innerHTML = obj.nameBasic; |
| | temp_dlTdCodecEl.setAttribute('data-bs-toggle', 'tooltip'); |
| | temp_dlTdCodecEl.setAttribute('data-bs-title', obj.nameLong); |
| | if ((obj.bitRateAvg !== null && obj.bitRateMax !== null) || (obj.bitRateAvg !== null && obj.bitRateMax === null)) { |
| | temp_codecBitrateTemporal = obj.bitRateAvg; |
| | } else { |
| | temp_codecBitrateTemporal = obj.bitRateMax; |
| | } |
| | if (obj.bitDepth === null) { |
| | temp_dlTdInfoEl.innerHTML = `${obj.sampleRate / 1000}kHz ${obj.channelCount}ch ${temp_codecBitrateTemporal / 1000}kbps`; |
| | } else { |
| | temp_dlTdInfoEl.innerHTML = `${obj.bitDepth}bit ${obj.sampleRate / 1000}kHz ${obj.channelCount}ch ${temp_codecBitrateTemporal / 1000}kbps`; |
| | } |
| | if (obj.isOriginal === true) { |
| | temp_dlButtonEl.classList.add('btn', 'btn-primary'); |
| | temp_dlButtonExtEl.classList.add('btn', 'btn-primary', 'text-center'); |
| | } else { |
| | temp_dlButtonEl.classList.add('btn', 'btn-secondary'); |
| | temp_dlButtonExtEl.classList.add('btn', 'btn-secondary', 'text-center'); |
| | } |
| | temp_dlButtonEl.setAttribute('type', 'button'); |
| | |
| | |
| | |
| | temp_dlButtonExtEl.setAttribute('href', `${apiDataConfig.response.config.decrypted.rawMediaUrlBase64}/media/${albumParsedObject.uuid}/${obj.path}/${trackParsedObject.uuid}.${obj.extension}`); |
| | temp_dlButtonExtEl.setAttribute('download', determineDownloadFileName(trackParsedObject.uuid, obj.uuid)); |
| | temp_dlButtonExtEl.setAttribute('role', 'button'); |
| | temp_dlButtonExtEl.setAttribute('target', '_blank'); |
| | temp_dlButtonExtEl.setAttribute('rel', 'noopener noreferrer'); |
| | temp_dlButtonGroupEl.setAttribute('role', 'group'); |
| | temp_dlButtonGroupEl.classList.add('btn-group'); |
| | temp_dlButtonIconEl.classList.add('bi', 'bi-download'); |
| | temp_dlButtonExtIconEl.classList.add('bi', 'bi-box-arrow-up-right'); |
| | temp_dlTdBtnEl.classList.add('text-end'); |
| | temp_dlButtonEl.appendChild(temp_dlButtonIconEl); |
| | temp_dlButtonExtEl.appendChild(temp_dlButtonExtIconEl); |
| | |
| | temp_dlButtonGroupEl.appendChild(temp_dlButtonExtEl); |
| | temp_dlTdBtnEl.appendChild(temp_dlButtonGroupEl); |
| | temp_dlTrEl.appendChild(temp_dlTdCodecEl); |
| | temp_dlTrEl.appendChild(temp_dlTdInfoEl); |
| | temp_dlTrEl.appendChild(temp_dlTdBtnEl); |
| | document.getElementById('trackInfoModal2-downloadTable').appendChild(temp_dlTrEl); |
| | }); |
| | document.getElementById('trackInfoModal2-previewAudio').src = `${apiDataConfig.response.config.decrypted.rawMediaUrlBase64}/media/${albumParsedObject.uuid}/${temp_codecListImported.slice(-1)[0].path}/${trackParsedObject.uuid}.${temp_codecListImported.slice(-1)[0].extension}`; |
| | const bootstrapTooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]'); |
| | bootstrapTooltipList = [...bootstrapTooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl)); |
| | document.getElementById('trackInfoModal2-DebugAcdOutputEl').innerHTML = JSON.stringify(albumParsedObject, '', ' '); |
| | document.getElementById('trackInfoModal2-ModalCloseButton').addEventListener('click', () => {allAudioElementStop()}); |
| | document.getElementById('trackInfoModal2-ModalCloseIconButton').addEventListener('click', () => {allAudioElementStop()}); |
| | const trackInfoModal2 = new bootstrap.Modal(document.getElementById('trackInfoModal2')); |
| | trackInfoModal2.show(); |
| | } |
| |
|
| | |
| |
|
| | function loadAlbumInfoModal (albumUuid) { |
| | |
| | const albumParsedObject = getParsedAlbumObjectFromAlbumUuid(albumUuid); |
| | |
| | if (bootstrapTooltipList !== null) {bootstrapTooltipList.forEach(el => el.dispose())}; |
| | document.getElementById('albumInfoModal-metadataTable-albumTitle').innerHTML = albumParsedObject.title; |
| | if (albumParsedObject.titleLatin === null) { |
| | document.getElementById('albumInfoModal-metadataTable-albumTitle').removeAttribute('data-bs-toggle'); |
| | document.getElementById('albumInfoModal-metadataTable-albumTitle').removeAttribute('data-bs-title'); |
| | } else { |
| | document.getElementById('albumInfoModal-metadataTable-albumTitle').setAttribute('data-bs-toggle', 'tooltip'); |
| | document.getElementById('albumInfoModal-metadataTable-albumTitle').setAttribute('data-bs-title', albumParsedObject.titleLatin); |
| | } |
| | document.getElementById('albumInfoModal-metadataTable-albumArtist').innerHTML = albumParsedObject.artist.map((obj) => obj.name).join(', '); |
| | if (albumParsedObject.artist.some((obj) => obj.nameLatin !== null)) { |
| | document.getElementById('albumInfoModal-metadataTable-albumArtist').setAttribute('data-bs-toggle', 'tooltip'); |
| | document.getElementById('albumInfoModal-metadataTable-albumArtist').setAttribute('data-bs-title', albumParsedObject.artist.map((obj) => {if (obj.nameLatin !== null) {return obj.nameLatin} else {return obj.name}}).join(', ')); |
| | } else { |
| | document.getElementById('albumInfoModal-metadataTable-albumArtist').removeAttribute('data-bs-toggle'); |
| | document.getElementById('albumInfoModal-metadataTable-albumArtist').removeAttribute('data-bs-title'); |
| | } |
| | document.getElementById('albumInfoModal-metadataTable-albumReleaseDate').innerHTML = moment(albumParsedObject.releaseDate).format('YYYY/MM/DD'); |
| | document.getElementById('albumInfoModal-metadataTable-albumBarcode').innerHTML = albumParsedObject.barCode; |
| | document.getElementById('albumInfoModal-metadataTable-albumCopyright').innerHTML = albumParsedObject.copyright; |
| | |
| | while(document.getElementById('albumInfoModal-externalLinkTable').firstChild) { |
| | document.getElementById('albumInfoModal-externalLinkTable').removeChild(document.getElementById('albumInfoModal-externalLinkTable').firstChild); |
| | } |
| | while(document.getElementById('albumInfoModal-coverArtLinkDiv').firstChild) { |
| | document.getElementById('albumInfoModal-coverArtLinkDiv').removeChild(document.getElementById('albumInfoModal-coverArtLinkDiv').firstChild); |
| | } |
| | |
| | if (albumParsedObject.link.itunes !== null || albumParsedObject.link.spotify !== null) { |
| | let temp_extLinkAlbumTrEl = document.createElement('tr'); |
| | let temp_extLinkAlbumTdKeyEl = document.createElement('td'); |
| | let temp_extLinkAlbumTdValueEl = document.createElement('td'); |
| | let temp_extLinkAlbumA1El = document.createElement('a'); |
| | let temp_extLinkAlbumA2El = document.createElement('a'); |
| | temp_extLinkAlbumTdKeyEl.innerHTML = 'Album Link'; |
| | if (albumParsedObject.link.itunes !== null) { |
| | temp_extLinkAlbumA1El.classList.add('btn','btn-outline-primary','btn-sm','me-2'); |
| | temp_extLinkAlbumA1El.setAttribute('href', `https://music.apple.com/album/${albumParsedObject.link.itunes}`); |
| | temp_extLinkAlbumA1El.setAttribute('role', 'button'); |
| | temp_extLinkAlbumA1El.setAttribute('target', '_blank'); |
| | temp_extLinkAlbumA1El.setAttribute('rel', 'noopener noreferrer'); |
| | temp_extLinkAlbumA1El.innerHTML = 'Apple Music'; |
| | temp_extLinkAlbumTdValueEl.appendChild(temp_extLinkAlbumA1El); |
| | } |
| | if (albumParsedObject.link.spotify !== null) { |
| | temp_extLinkAlbumA2El.classList.add('btn','btn-outline-primary','btn-sm','me-2'); |
| | temp_extLinkAlbumA2El.setAttribute('href', `https://open.spotify.com/album/${albumParsedObject.link.spotify}`); |
| | temp_extLinkAlbumA2El.setAttribute('role', 'button'); |
| | temp_extLinkAlbumA2El.setAttribute('target', '_blank'); |
| | temp_extLinkAlbumA2El.setAttribute('rel', 'noopener noreferrer'); |
| | temp_extLinkAlbumA2El.innerHTML = 'Spotify'; |
| | temp_extLinkAlbumTdValueEl.appendChild(temp_extLinkAlbumA2El); |
| | } |
| | temp_extLinkAlbumTrEl.appendChild(temp_extLinkAlbumTdKeyEl); |
| | temp_extLinkAlbumTrEl.appendChild(temp_extLinkAlbumTdValueEl); |
| | document.getElementById('albumInfoModal-externalLinkTable').appendChild(temp_extLinkAlbumTrEl); |
| | } |
| | |
| | albumParsedObject.coverArts.forEach((obj1) => { |
| | obj1.format.forEach((obj2) => { |
| | let temp_coverArtAEl = document.createElement('a'); |
| | temp_coverArtAEl.classList.add('btn','btn-primary','btn-sm','me-2','mb-2'); |
| | temp_coverArtAEl.setAttribute('href', `${apiDataConfig.response.config.decrypted.rawMediaUrlBase64}/media/${albumParsedObject.uuid}/${obj1.fileName}.${obj2.extension}`); |
| | temp_coverArtAEl.setAttribute('role', 'button'); |
| | temp_coverArtAEl.setAttribute('target', '_blank'); |
| | temp_coverArtAEl.setAttribute('rel', 'noopener noreferrer'); |
| | temp_coverArtAEl.innerHTML = `${obj2.name} ${obj1.height}px`; |
| | document.getElementById('albumInfoModal-coverArtLinkDiv').appendChild(temp_coverArtAEl); |
| | }); |
| | }); |
| | |
| | const bootstrapTooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]'); |
| | bootstrapTooltipList = [...bootstrapTooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl)); |
| | |
| | const albumInfoModal = new bootstrap.Modal(document.getElementById('albumInfoModal')); |
| |
|
| | |
| | const albumTrackAllListGroup = document.querySelector('#albumInfoModal-trackAllListGroup'); |
| | while(albumTrackAllListGroup.firstChild) { |
| | albumTrackAllListGroup.removeChild(albumTrackAllListGroup.firstChild); |
| | } |
| | let headerElObj = new Object(); |
| | headerElObj.buttonNodeEl = document.createElement('button'); |
| | headerElObj.divArtistNodeEl = document.createElement('div'); |
| | headerElObj.divTrackNodeEl = document.createElement('div'); |
| | headerElObj.buttonNodeEl.classList.add('list-group-item', 'list-group-item-action', 'd-flex'); |
| | headerElObj.buttonNodeEl.setAttribute('type', 'button'); |
| | headerElObj.buttonNodeEl.disabled = true; |
| | headerElObj.divArtistNodeEl.classList.add('flex-fill', 'w-100'); |
| | headerElObj.divTrackNodeEl.classList.add('flex-fill', 'w-100'); |
| | headerElObj.divArtistNodeEl.innerHTML = 'Artist'; |
| | headerElObj.divTrackNodeEl.innerHTML = 'Track'; |
| | headerElObj.buttonNodeEl.appendChild(headerElObj.divArtistNodeEl); |
| | headerElObj.buttonNodeEl.appendChild(headerElObj.divTrackNodeEl); |
| | albumTrackAllListGroup.appendChild(headerElObj.buttonNodeEl); |
| | albumParsedObject.tracks.forEach((trackParsedObject) => { |
| | let buttonNodeEl = document.createElement('button'); |
| | let divArtistNodeEl = document.createElement('div'); |
| | let divTrackNodeEl = document.createElement('div'); |
| | buttonNodeEl.classList.add('list-group-item', 'list-group-item-action', 'd-flex'); |
| | buttonNodeEl.setAttribute('type', 'button'); |
| | buttonNodeEl.setAttribute('data-track-uuid', trackParsedObject.uuid); |
| | divArtistNodeEl.classList.add('flex-fill', 'w-100'); |
| | divTrackNodeEl.classList.add('flex-fill', 'w-100'); |
| | divArtistNodeEl.innerHTML = trackParsedObject.artist.map((obj) => obj.name).join(', '); |
| | divTrackNodeEl.innerHTML = trackParsedObject.title; |
| | buttonNodeEl.appendChild(divArtistNodeEl); |
| | buttonNodeEl.appendChild(divTrackNodeEl); |
| | buttonNodeEl.addEventListener('click', () => { |
| | albumInfoModal.hide(); |
| | loadTrackInfoModal2(trackParsedObject.uuid) |
| | }); |
| | albumTrackAllListGroup.appendChild(buttonNodeEl); |
| | }); |
| | |
| | |
| | albumInfoModal.show(); |
| | } |
| |
|
| | |
| |
|
| | document.querySelector('#settingsApplyButton').addEventListener('click', () => {appSettingsApply()}); |
| | document.querySelector('#settingsUiSwitchUiModeDiv').addEventListener('click', function () { |
| | appSettingsSaveData.ui.uiThemeMode = document.querySelector('#settingsUiSwitchUiMode').elements['settingsUiSwitchUiMode'].value; |
| | console.log('settingsUiSwitchUiMode div clicked!'); |
| | }); |
| |
|
| |
|
| | |
| |
|
| | function appSettingsApply () { |
| | writeAppSettingsToLocalStorage(); |
| | switch (appSettingsSaveData.ui.uiThemeMode) { |
| | case 'light': |
| | document.querySelector('html').setAttribute('data-bs-theme', 'light'); |
| | document.querySelector('html').setAttribute('data-mdb-theme', 'light'); |
| | break; |
| | case 'dark': |
| | document.querySelector('html').setAttribute('data-bs-theme', 'dark'); |
| | document.querySelector('html').setAttribute('data-mdb-theme', 'dark'); |
| | } |
| | } |
| |
|
| | |
| |
|
| | function appSettingsCheckedUiUpdate () { |
| | const settingsUiSwitchUiModeElements = document.querySelector('#settingsUiSwitchUiMode').elements; |
| | for (let i = 0; i < settingsUiSwitchUiModeElements.length; i++) { |
| | if (settingsUiSwitchUiModeElements[i].value === appSettingsSaveData.ui.uiThemeMode) { |
| | settingsUiSwitchUiModeElements[i].checked = true; |
| | } else { |
| | settingsUiSwitchUiModeElements[i].checked = false; |
| | } |
| | } |
| | } |
| |
|
| | |
| |
|
| | async function apiConnect (axiosObj) { |
| | let connectionTimerStart = performance.now(); |
| | try { |
| | const response = await axios(axiosObj); |
| | let connectionTimerEnd = performance.now(); |
| | return { |
| | 'apiConnectionTime': connectionTimerEnd - connectionTimerStart, |
| | 'response': response.data |
| | }; |
| | } catch (error) { |
| | let connectionTimerEnd = performance.now(); |
| | console.error(`API request failed: ${error.code}`); |
| | alert(`API request failed: ${error.code}`); |
| | throw error; |
| | } |
| | } |
| |
|
| | async function loadRequiredDatabase () { |
| | document.querySelectorAll('.fetchingDataNowLabel').forEach((el) => { |
| | el.classList.remove('d-none'); |
| | }); |
| | apiDataMasterDB = await apiConnect({ |
| | 'method': 'get', |
| | 'url': `./db/master.json`, |
| | 'headers': apiConnectDefaultHeader, |
| | 'timeout': internalConfig.network.timeout |
| | }); |
| | apiDataConfig = await apiConnect({ |
| | 'method': 'get', |
| | 'url': `./config.json`, |
| | 'headers': apiConnectDefaultHeader, |
| | 'timeout': internalConfig.network.timeout |
| | }); |
| | if (apiDataMasterDB) { |
| | document.querySelector('#databaseTestInfoCodeEl').innerHTML = `OK (Time: ${Math.ceil(apiDataMasterDB.apiConnectionTime)} ms)`; |
| | document.querySelector('#databaseTestOutputCodeEl').innerHTML = JSON.stringify(apiDataMasterDB.response, '', ' '); |
| | } else { |
| | document.querySelector('#databaseTestInfoCodeEl').innerHTML = `Failed`; |
| | } |
| | document.querySelectorAll('.fetchingDataNowLabel').forEach((el) => { |
| | el.classList.add('d-none'); |
| | }); |
| | } |
| |
|
| | |
| |
|
| | function getAlbumUuidFromTrackUuid (trackUuid) { |
| | let albumUuid = null; |
| | apiDataMasterDB.response.data.albums.forEach((albumObject) => { |
| | if (albumObject.tracks.some((trackObject) => trackObject.uuid === trackUuid)) { |
| | albumUuid = albumObject.uuid; |
| | } |
| | }); |
| | return albumUuid; |
| | } |
| |
|
| | function getDbObjectFromUuid (uuid, type) { |
| | switch (type) { |
| | case 'album': |
| | if (apiDataMasterDB.response.data.albums.some((albumObject) => albumObject.uuid === uuid)) { |
| | return apiDataMasterDB.response.data.albums.filter((albumObject) => albumObject.uuid === uuid)[0]; |
| | } else { |
| | return null; |
| | } |
| | case 'track': |
| | apiDataMasterDB.response.data.albums.forEach((albumObject) => { |
| | if (albumObject.tracks.some((trackObject) => trackObject.uuid === uuid)) { |
| | return albumObject.tracks.filter((trackObject) => trackObject.uuid === uuid)[0]; |
| | } |
| | }); |
| | return null; |
| | case 'artist': |
| | if (apiDataMasterDB.response.data.artists.some((artistObject) => artistObject.uuid === uuid)) { |
| | return apiDataMasterDB.response.data.artists.filter((artistObject) => artistObject.uuid === uuid)[0]; |
| | } else { |
| | return null; |
| | } |
| | case 'codec': |
| | if (apiDataMasterDB.response.data.codecs.some((codecObject) => codecObject.uuid === uuid)) { |
| | return apiDataMasterDB.response.data.codecs.filter((codecObject) => codecObject.uuid === uuid)[0]; |
| | } else { |
| | return null; |
| | } |
| | default: |
| | throw new Error ('unexpected type'); |
| | } |
| | } |
| |
|
| | function getParsedAlbumObjectFromAlbumUuid (uuid) { |
| | const rawAlbumObject = getDbObjectFromUuid(uuid, 'album'); |
| | let outputObject = JSON.parse(JSON.stringify(rawAlbumObject)); |
| | outputObject.artist = new Array(); |
| | rawAlbumObject.artist.forEach((artistUuidStr) => { |
| | outputObject.artist.push(getDbObjectFromUuid(artistUuidStr, 'artist')); |
| | }); |
| | if (rawAlbumObject.isAllTrackSameCodecs === true) { |
| | outputObject.codecs = new Array(); |
| | rawAlbumObject.codecs.forEach((codecObj) => { |
| | let temp_searchedCodecObj = new Object(); |
| | temp_searchedCodecObj = getDbObjectFromUuid(codecObj.uuid, 'codec'); |
| | temp_searchedCodecObj.isOriginal = codecObj.isOriginal; |
| | temp_searchedCodecObj.path = codecObj.path; |
| | outputObject.codecs.push(temp_searchedCodecObj); |
| | }); |
| | } |
| | if (rawAlbumObject.isCoverArtsUseDefault === true) { |
| | outputObject.coverArts = apiDataMasterDB.response.data.coverArtDefaults; |
| | } |
| | outputObject.tracks = new Array(); |
| | rawAlbumObject.tracks.forEach((rawTrackObj) => { |
| | let temp_outputTrackObj = new Object(); |
| | temp_outputTrackObj = JSON.parse(JSON.stringify(rawTrackObj)); |
| | temp_outputTrackObj.artist = new Array(); |
| | rawTrackObj.artist.forEach((artistUuidStr) => { |
| | temp_outputTrackObj.artist.push(getDbObjectFromUuid(artistUuidStr, 'artist')); |
| | }); |
| | if (rawTrackObj.lyricist !== null) { |
| | temp_outputTrackObj.lyricist = new Array(); |
| | rawTrackObj.lyricist.forEach((artistUuidStr) => { |
| | temp_outputTrackObj.lyricist.push(getDbObjectFromUuid(artistUuidStr, 'artist')); |
| | }); |
| | } |
| | if (rawTrackObj.composer !== null) { |
| | temp_outputTrackObj.composer = new Array(); |
| | rawTrackObj.composer.forEach((artistUuidStr) => { |
| | temp_outputTrackObj.composer.push(getDbObjectFromUuid(artistUuidStr, 'artist')); |
| | }); |
| | } |
| | if (rawTrackObj.arranger !== null) { |
| | temp_outputTrackObj.arranger = new Array(); |
| | rawTrackObj.arranger.forEach((artistUuidStr) => { |
| | temp_outputTrackObj.arranger.push(getDbObjectFromUuid(artistUuidStr, 'artist')); |
| | }); |
| | } |
| | if (rawAlbumObject.isAllTrackSameCodecs === false || rawTrackObj.codecs !== null) { |
| | temp_outputTrackObj.codecs = new Array(); |
| | rawTrackObj.codecs.forEach((codecObj) => { |
| | let temp_searchedCodecObj2 = new Object(); |
| | temp_searchedCodecObj2 = getDbObjectFromUuid(codecObj.uuid, 'codec'); |
| | temp_searchedCodecObj2.isOriginal = codecObj.isOriginal; |
| | temp_searchedCodecObj2.path = codecObj.path; |
| | temp_outputTrackObj.codecs.push(temp_searchedCodecObj2); |
| | }); |
| | temp_outputTrackObj.durationMsecs = (rawTrackObj.durationSamples / temp_outputTrackObj.codecs.filter((t) => t.isOriginal === true)[0].sampleRate) * 1000; |
| | } else { |
| | temp_outputTrackObj.durationMsecs = (rawTrackObj.durationSamples / outputObject.codecs.filter((t) => t.isOriginal === true)[0].sampleRate) * 1000; |
| | } |
| | outputObject.tracks.push(temp_outputTrackObj); |
| | }); |
| | let temp_albumTotalDurationSamples = 0; |
| | let temp_albumTotalDurationMsecs = 0; |
| | for (let i = 0; i < rawAlbumObject.tracks.length; i++) { |
| | temp_albumTotalDurationSamples += outputObject.tracks[i].durationSamples; |
| | temp_albumTotalDurationMsecs += outputObject.tracks[i].durationMsecs; |
| | } |
| | outputObject.durationSamples = temp_albumTotalDurationSamples; |
| | outputObject.durationMsecs = temp_albumTotalDurationMsecs; |
| | return outputObject; |
| | } |
| |
|
| | |
| |
|
| | async function downloadAudioDataToBlob (trackUuid, codecUuid) { |
| | const albumParsedObject = getParsedAlbumObjectFromAlbumUuid(getAlbumUuidFromTrackUuid(trackUuid)); |
| | const trackParsedObject = albumParsedObject.tracks.find((obj) => obj.uuid === trackUuid); |
| | let codecParsedObject = null; |
| | if (albumParsedObject.isAllTrackSameCodecs === false) { |
| | codecParsedObject = trackParsedObject.codecs.find((obj) => obj.uuid === codecUuid); |
| | } else { |
| | codecParsedObject = albumParsedObject.codecs.find((obj) => obj.uuid === codecUuid); |
| | } |
| | const axiosRes = await apiConnect ({ |
| | 'method': 'get', |
| | 'url': `${apiDataConfig.response.config.decrypted.rawMediaUrlBase64}/media/${albumParsedObject.uuid}/${codecParsedObject.path}/${trackParsedObject.uuid}.${codecParsedObject.extension}`, |
| | 'headers': apiConnectDefaultHeader, |
| | 'timeout': internalConfig.network.timeout, |
| | 'responseType': 'blob' |
| | }); |
| | console.log(`File downloaded to Blob\nDownload time: ${axiosRes.apiConnectionTime} ms`); |
| | const blobUrl = window.URL.createObjectURL(response.data); |
| | const link = document.createElement('a'); |
| | let saveFileName = null; |
| | if (trackParsedObject.titleFileName !== null) { |
| | saveFileName = `${trackParsedObject.disc}_${('00' + trackParsedObject.index).slice(-2)}_${trackParsedObject.titleFileName}.${codecParsedObject.extension}`; |
| | } else { |
| | saveFileName = `${trackParsedObject.disc}_${('00' + trackParsedObject.index).slice(-2)}_${trackParsedObject.title}.${codecParsedObject.extension}`; |
| | } |
| | link.href = blobUrl; |
| | link.setAttribute('download', saveFileName); |
| | link.classList.add('d-none'); |
| | document.body.appendChild(link); |
| | link.click(); |
| | document.body.removeChild(link); |
| | } |
| |
|
| | function determineDownloadFileName (trackUuid, codecUuid) { |
| | const albumParsedObject = getParsedAlbumObjectFromAlbumUuid(getAlbumUuidFromTrackUuid(trackUuid)); |
| | const trackParsedObject = albumParsedObject.tracks.find((obj) => obj.uuid === trackUuid); |
| | let codecParsedObject = null; |
| | if (albumParsedObject.isAllTrackSameCodecs === false) { |
| | codecParsedObject = trackParsedObject.codecs.find((obj) => obj.uuid === codecUuid); |
| | } else { |
| | codecParsedObject = albumParsedObject.codecs.find((obj) => obj.uuid === codecUuid); |
| | } |
| | let saveFileName = null; |
| | if (trackParsedObject.titleFileName !== null) { |
| | saveFileName = `${trackParsedObject.disc}_${('00' + trackParsedObject.index).slice(-2)}_${trackParsedObject.titleFileName}.${codecParsedObject.extension}`; |
| | } else { |
| | saveFileName = `${trackParsedObject.disc}_${('00' + trackParsedObject.index).slice(-2)}_${trackParsedObject.title}.${codecParsedObject.extension}`; |
| | } |
| | return saveFileName; |
| | } |
| |
|
| | |
| |
|
| | async function decryptConfig () { |
| | apiDataConfig.response.config.decrypted = new Object(); |
| | console.log(`Decrypting config data using AES 128-bit CBC ...`) |
| | const encryptKey = await CryptoJS.enc.Hex.parse(CryptoJS.enc.Base64.parse(apiDataConfig.response.config.encryption.key.split('').reverse().join('')).toString(CryptoJS.enc.Utf8)); |
| | const encryptIv = await CryptoJS.enc.Hex.parse(CryptoJS.enc.Base64.parse(apiDataConfig.response.config.encryption.iv.split('').reverse().join('')).toString(CryptoJS.enc.Utf8)); |
| | Object.keys(apiDataConfig.response.config.encrypted).forEach(async function (keyName) { |
| | apiDataConfig.response.config.decrypted[keyName] = await CryptoJS.AES.decrypt({ |
| | 'ciphertext': CryptoJS.enc.Base64.parse(apiDataConfig.response.config.encrypted[keyName]) |
| | }, encryptKey, { |
| | 'iv': encryptIv, |
| | 'mode': CryptoJS.mode.CBC, |
| | 'padding': CryptoJS.pad.Pkcs7 |
| | }).toString(CryptoJS.enc.Utf8); |
| | }); |
| | console.log(`All config data has been decrypted`); |
| | } |
| |
|
| | |
| |
|
| | function loadAppSettingsFromLocalStorage () { |
| | if (localStorage.hasOwnProperty(appSettingsStorageName)) { |
| | appSettingsSaveData = JSON.parse(CryptoJS.enc.Base64.parse(localStorage.getItem(appSettingsStorageName)).toString(CryptoJS.enc.Utf8)); |
| | console.warn(`LocalStorage key detected`); |
| | console.log(`Loaded appSettings:\n${JSON.stringify(appSettingsSaveData)}`); |
| | } else { |
| | appSettingsSaveData = appSettingsSaveDataDefault; |
| | console.warn(`LocalStorage key not found\nUsing default settings`); |
| | writeAppSettingsToLocalStorage(); |
| | } |
| | } |
| |
|
| | function checkAppSettingsExistsOnStorage () { |
| | if (localStorage.hasOwnProperty(appSettingsStorageName)) { |
| | return true |
| | } else { |
| | return false |
| | } |
| | } |
| |
|
| | function writeAppSettingsToLocalStorage () { |
| | |
| | localStorage.setItem(appSettingsStorageName, CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(JSON.stringify(appSettingsSaveData)))); |
| | console.log(`Wrote appSettings:\n${JSON.stringify(appSettingsSaveData)}`); |
| | } |
| |
|
| | |
| |
|
| | function allAudioElementStop () { |
| | let audioElements = document.getElementsByTagName('audio'); |
| | for (let i = 0; i < audioElements.length; i++) { |
| | audioElements[i].pause(); |
| | } |
| | } |
| |
|
| | |
| |
|
| | function msecToReadableTime (msec) { |
| | let msecCeiled = Math.ceil(msec); |
| | let sec = msec / 1000; |
| | let min = ('00' + Math.floor(sec / 60)).slice(-2); |
| | let secPart = ('00' + Math.floor(sec % 60)).slice(-2); |
| | return `${min}:${secPart}.${('000' + msecCeiled % 1000).slice(-3)}`; |
| | } |
| |
|