Add AppleMusic Module
This commit is contained in:
261
modules/apple-music/apple-music.js
Normal file
261
modules/apple-music/apple-music.js
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
// Apple Music Overlay Module
|
||||||
|
// This module connects to a local Cider instance to display Apple Music playback information.
|
||||||
|
// Initial sources were taken from https://github.com/nuttylmao/nutty.gg
|
||||||
|
|
||||||
|
;(function() {
|
||||||
|
let visibilityDefault = 5;
|
||||||
|
let visibilityDuration = visibilityDefault;
|
||||||
|
let animationSpeed = 0.5;
|
||||||
|
|
||||||
|
const moduleUrl = window.getModuleUrl();
|
||||||
|
loadCSSModule('overlay-applemusic-css', moduleUrl + '/css/apple-music.css');
|
||||||
|
loadModuleResources([
|
||||||
|
{ type:'css', url:'https://cdn.jsdelivr.net/npm/@xz/fonts@1/serve/metropolis.min.css', id:'xz-fonts' },
|
||||||
|
{ type:'js', url:'https://cdn.socket.io/4.7.5/socket.io.min.js', id:'socket-io', crossorigin:'anonymous' },
|
||||||
|
{ type:'js', url:'https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.0/TweenMax.min.js', id:'tweenmax' }
|
||||||
|
]).then(() => {
|
||||||
|
initModule();
|
||||||
|
let outer = document.getElementById('musicWidgetContainer');
|
||||||
|
let maxWidth = outer.clientWidth+50;
|
||||||
|
window.addEventListener("resize", resize);
|
||||||
|
resize();
|
||||||
|
connectws();
|
||||||
|
|
||||||
|
function initModule() {
|
||||||
|
const container = document.getElementById('mainContainer') || document.body;
|
||||||
|
|
||||||
|
// Crée le conteneur principal
|
||||||
|
if (!document.getElementById('musicWidgetContainer')) {
|
||||||
|
const widget = document.createElement('div');
|
||||||
|
widget.id = 'musicWidgetContainer';
|
||||||
|
|
||||||
|
// Album art box
|
||||||
|
const artBox = document.createElement('div');
|
||||||
|
artBox.id = 'albumArtBox';
|
||||||
|
const albumArt = document.createElement('img');
|
||||||
|
albumArt.id = 'albumArt';
|
||||||
|
albumArt.src = ''; // placeholder
|
||||||
|
const albumArtBack = document.createElement('img');
|
||||||
|
albumArtBack.id = 'albumArtBack';
|
||||||
|
albumArtBack.src = ''; // placeholder
|
||||||
|
artBox.append(albumArt, albumArtBack);
|
||||||
|
|
||||||
|
// Song info box
|
||||||
|
const infoBox = document.createElement('div');
|
||||||
|
infoBox.id = 'songInfoBox';
|
||||||
|
|
||||||
|
const songInfo = document.createElement('div');
|
||||||
|
songInfo.id = 'songInfo';
|
||||||
|
const innerBox = document.createElement('div');
|
||||||
|
innerBox.id = 'IAmRunningOutOfNamesForTheseBoxes';
|
||||||
|
|
||||||
|
const songLabel = document.createElement('div');
|
||||||
|
songLabel.id = 'songLabel';
|
||||||
|
songLabel.innerText = '-/-';
|
||||||
|
const artistLabel = document.createElement('div');
|
||||||
|
artistLabel.id = 'artistLabel';
|
||||||
|
artistLabel.innerText = '-/-';
|
||||||
|
const albumLabel = document.createElement('div');
|
||||||
|
albumLabel.id = 'albumLabel';
|
||||||
|
albumLabel.innerText = '-/-';
|
||||||
|
|
||||||
|
const times = document.createElement('div');
|
||||||
|
times.id = 'times';
|
||||||
|
const progressTime = document.createElement('div');
|
||||||
|
progressTime.id = 'progressTime';
|
||||||
|
progressTime.innerText = '0:00';
|
||||||
|
const duration = document.createElement('div');
|
||||||
|
duration.id = 'duration';
|
||||||
|
duration.innerText = '0:00';
|
||||||
|
times.append(progressTime, duration);
|
||||||
|
|
||||||
|
const progressBg = document.createElement('div');
|
||||||
|
progressBg.id = 'progressBg';
|
||||||
|
const progressBar = document.createElement('div');
|
||||||
|
progressBar.id = 'progressBar';
|
||||||
|
progressBg.appendChild(progressBar);
|
||||||
|
|
||||||
|
innerBox.append(songLabel, artistLabel, albumLabel, times, progressBg);
|
||||||
|
songInfo.appendChild(innerBox);
|
||||||
|
|
||||||
|
const backgroundArt = document.createElement('div');
|
||||||
|
backgroundArt.id = 'backgroundArt';
|
||||||
|
const backgroundImage = document.createElement('img');
|
||||||
|
backgroundImage.id = 'backgroundImage';
|
||||||
|
backgroundImage.src = '';
|
||||||
|
const backgroundImageBack = document.createElement('img');
|
||||||
|
backgroundImageBack.id = 'backgroundImageBack';
|
||||||
|
backgroundImageBack.src = '';
|
||||||
|
backgroundArt.append(backgroundImage, backgroundImageBack);
|
||||||
|
|
||||||
|
infoBox.append(songInfo, backgroundArt);
|
||||||
|
|
||||||
|
widget.append(artBox, infoBox);
|
||||||
|
container.appendChild(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.SBdispatcher) {
|
||||||
|
SBdispatcher.on('musicPlaying', data => {
|
||||||
|
visibilityDuration = data.param1 || visibilityDefault;
|
||||||
|
showSongInfo();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function connectws() {
|
||||||
|
if ("WebSocket" in window) {
|
||||||
|
const CiderApp = io("http://localhost:10767/", {
|
||||||
|
transports: ['websocket']
|
||||||
|
});
|
||||||
|
|
||||||
|
CiderApp.on("disconnect", (event) => {
|
||||||
|
SetConnectionStatus(false);
|
||||||
|
setTimeout(connectws, 5000);
|
||||||
|
});
|
||||||
|
|
||||||
|
CiderApp.on("connect", (event) => {
|
||||||
|
SetConnectionStatus(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set up websocket artwork/information handling
|
||||||
|
CiderApp.on("API:Playback", ({ data, type }) => {
|
||||||
|
switch (type) {
|
||||||
|
// Song changes
|
||||||
|
case ("playbackStatus.nowPlayingItemDidChange"):
|
||||||
|
UpdateSongInfo(data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Progress bar moves
|
||||||
|
case ("playbackStatus.playbackTimeDidChange"):
|
||||||
|
UpdateProgressBar(data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Pause/unpause
|
||||||
|
case ("playbackStatus.playbackStateDidChange"):
|
||||||
|
UpdatePlaybackState(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showSongInfo() {
|
||||||
|
setTimeout(() => {
|
||||||
|
SetVisibility(true);
|
||||||
|
}, animationSpeed * 500);
|
||||||
|
|
||||||
|
if (visibilityDuration > 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
SetVisibility(false);
|
||||||
|
}, visibilityDuration * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function UpdateSongInfo(data) {
|
||||||
|
// Set the user's info
|
||||||
|
let albumArtUrl = data.artwork.url;
|
||||||
|
albumArtUrl = albumArtUrl.replace("{w}", data.artwork.width);
|
||||||
|
albumArtUrl = albumArtUrl.replace("{h}", data.artwork.height);
|
||||||
|
|
||||||
|
UpdateAlbumArt(document.getElementById("albumArt"), albumArtUrl);
|
||||||
|
UpdateAlbumArt(document.getElementById("backgroundImage"), albumArtUrl);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
UpdateTextLabel(document.getElementById("songLabel"), data.name);
|
||||||
|
UpdateTextLabel(document.getElementById("artistLabel"), data.artistName);
|
||||||
|
}, animationSpeed * 500);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
document.getElementById("albumArtBack").src = albumArtUrl;
|
||||||
|
document.getElementById("backgroundImageBack").src = albumArtUrl;
|
||||||
|
}, 2 * animationSpeed * 500);
|
||||||
|
|
||||||
|
showSongInfo()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function UpdateTextLabel(div, text) {
|
||||||
|
if (div.innerHTML != text) {
|
||||||
|
div.setAttribute("class", "text-fade");
|
||||||
|
setTimeout(() => {
|
||||||
|
div.innerHTML = text;
|
||||||
|
div.setAttribute("class", ".text-show");
|
||||||
|
}, animationSpeed * 250);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function UpdateAlbumArt(div, imgsrc) {
|
||||||
|
if (div.src != imgsrc) {
|
||||||
|
div.setAttribute("class", "text-fade");
|
||||||
|
setTimeout(() => {
|
||||||
|
div.src = imgsrc;
|
||||||
|
div.setAttribute("class", "text-show");
|
||||||
|
}, animationSpeed * 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function UpdateProgressBar(data) {
|
||||||
|
const progress = ((data.currentPlaybackTime / data.currentPlaybackDuration) * 100);
|
||||||
|
const progressTime = ConvertSecondsToMinutesSoThatItLooksBetterOnTheOverlay(data.currentPlaybackTime);
|
||||||
|
const duration = ConvertSecondsToMinutesSoThatItLooksBetterOnTheOverlay(data.currentPlaybackTimeRemaining);
|
||||||
|
document.getElementById("progressBar").style.width = `${progress}%`;
|
||||||
|
document.getElementById("progressTime").innerHTML = progressTime;
|
||||||
|
document.getElementById("duration").innerHTML = `-${duration}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function UpdatePlaybackState(data) {
|
||||||
|
console.log(data);
|
||||||
|
switch (data.state) {
|
||||||
|
case ("paused"):
|
||||||
|
case ("stopped"):
|
||||||
|
SetVisibility(false);
|
||||||
|
break;
|
||||||
|
case ("playing"):
|
||||||
|
UpdateSongInfo(data.attributes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function ConvertSecondsToMinutesSoThatItLooksBetterOnTheOverlay(time) {
|
||||||
|
const minutes = Math.floor(time / 60);
|
||||||
|
const seconds = Math.trunc(time - minutes * 60);
|
||||||
|
|
||||||
|
return `${minutes}:${('0' + seconds).slice(-2)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SetVisibility(isVisible) {
|
||||||
|
widgetVisibility = isVisible;
|
||||||
|
|
||||||
|
const musicWidgetContainer = document.getElementById("musicWidgetContainer");
|
||||||
|
|
||||||
|
if (isVisible) {
|
||||||
|
var tl = new TimelineMax();
|
||||||
|
tl
|
||||||
|
.to(musicWidgetContainer, animationSpeed, { bottom: "50%", ease: Power1.easeInOut }, 'label')
|
||||||
|
.to(musicWidgetContainer, animationSpeed, { opacity: 1, ease: Power1.easeInOut }, 'label')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var tl = new TimelineMax();
|
||||||
|
tl
|
||||||
|
.to(musicWidgetContainer, animationSpeed, { bottom: "45%", ease: Power1.easeInOut }, 'label')
|
||||||
|
.to(musicWidgetContainer, animationSpeed, { opacity: 0, ease: Power1.easeInOut }, 'label')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function SetConnectionStatus(connected) {
|
||||||
|
if (connected) {
|
||||||
|
console.log("Connected to Cider!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log("Not connected to Cider...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resize() {
|
||||||
|
const scale = window.innerWidth / maxWidth;
|
||||||
|
outer.style.transform = 'translate(0%, 0%) scale(' + scale + ')';
|
||||||
|
}
|
||||||
|
}).catch(err => console.error(err));
|
||||||
|
|
||||||
|
})();
|
||||||
139
modules/apple-music/css/apple-music.css
Normal file
139
modules/apple-music/css/apple-music.css
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
#musicWidgetContainer {
|
||||||
|
--corner-radius: 10px;
|
||||||
|
--album-art-size: 100px;
|
||||||
|
position: absolute;
|
||||||
|
width: 600px;
|
||||||
|
height: 140px;
|
||||||
|
top: 20px;
|
||||||
|
right: 0px;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
|
||||||
|
display: flex;
|
||||||
|
height: var(--album-art-size);
|
||||||
|
margin: 20px;
|
||||||
|
filter: drop-shadow(0px 0px 4px #000000);
|
||||||
|
width: 100%;
|
||||||
|
max-width: 500px;
|
||||||
|
bottom: 45%;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #albumArtBox {
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
position: relative;
|
||||||
|
border-radius: var(--corner-radius);
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 0px 8px 0px 0px;
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #albumArt {
|
||||||
|
position: absolute;
|
||||||
|
width: var(--album-art-size);
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #albumArtBack {
|
||||||
|
width: var(--album-art-size);
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #songInfoBox {
|
||||||
|
position: relative;
|
||||||
|
color: white;
|
||||||
|
width: calc(100% - 125px);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 0 1 auto;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 1;
|
||||||
|
text-shadow: 2px 2px 2px black;
|
||||||
|
overflow: hidden;
|
||||||
|
z-index: 4;
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #songInfo {
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
position: relative;
|
||||||
|
border-radius: var(--corner-radius);
|
||||||
|
padding: 0px 20px;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #IAmRunningOutOfNamesForTheseBoxes {
|
||||||
|
width: calc(100% - 40px);
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
-ms-transform: translateY(-50%);
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #backgroundArt {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: var(--corner-radius);
|
||||||
|
overflow: hidden;
|
||||||
|
z-index: -1;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #backgroundImage {
|
||||||
|
filter: blur(20px);
|
||||||
|
position: absolute;
|
||||||
|
width: 140%;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%) translateY(-50%);
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #backgroundImageBack {
|
||||||
|
filter: blur(20px);
|
||||||
|
position: absolute;
|
||||||
|
width: 140%;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%) translateY(-50%);
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #songLabel {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 20px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #artistLabel {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 100;
|
||||||
|
font-style: italic;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #albumLabel {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 100;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #progressBg {
|
||||||
|
margin-top: 5px;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #1F1F1F;
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #progressBar {
|
||||||
|
border-radius: 5px;
|
||||||
|
height: 5px;
|
||||||
|
width: 20%;
|
||||||
|
background-color: #ffffff;
|
||||||
|
margin: 10px 0px;
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #times {
|
||||||
|
position: relative;
|
||||||
|
height: 10px;
|
||||||
|
font-size: 8px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 3.5;
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #progressTime {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
#musicWidgetContainer #duration {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
#musicWidgetContainer .text-show {
|
||||||
|
opacity: 1;
|
||||||
|
transition: all 0.25s ease;
|
||||||
|
}
|
||||||
|
#musicWidgetContainer .text-fade {
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.25s ease;
|
||||||
|
}
|
||||||
163
modules/apple-music/css/apple-music.less
Normal file
163
modules/apple-music/css/apple-music.less
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
// out: apple-music.css, sourcemap: false, compress: false
|
||||||
|
|
||||||
|
#musicWidgetContainer {
|
||||||
|
--corner-radius: 10px;
|
||||||
|
--album-art-size: 100px;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
width: 600px;
|
||||||
|
height: 140px;
|
||||||
|
top: 20px;
|
||||||
|
right: 0px;
|
||||||
|
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
|
||||||
|
display: flex;
|
||||||
|
height: var(--album-art-size);
|
||||||
|
margin: 20px;
|
||||||
|
filter: drop-shadow(0px 0px 4px rgba(0, 0, 0, 1));
|
||||||
|
width: 100%;
|
||||||
|
max-width: 500px;
|
||||||
|
bottom: 45%;
|
||||||
|
opacity: 0;
|
||||||
|
|
||||||
|
#albumArtBox {
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
position: relative;
|
||||||
|
border-radius: var(--corner-radius);
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 0px 8px 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#albumArt {
|
||||||
|
position: absolute;
|
||||||
|
width: var(--album-art-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#albumArtBack {
|
||||||
|
width: var(--album-art-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#songInfoBox {
|
||||||
|
position: relative;
|
||||||
|
color: white;
|
||||||
|
width: calc(100% - 125px);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 0 1 auto;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 1;
|
||||||
|
text-shadow: 2px 2px 2px black;
|
||||||
|
overflow: hidden;
|
||||||
|
z-index: 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
#songInfo {
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
position: relative;
|
||||||
|
border-radius: var(--corner-radius);
|
||||||
|
padding: 0px 20px;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#IAmRunningOutOfNamesForTheseBoxes {
|
||||||
|
position: absolute;
|
||||||
|
width: calc(100% - 40px);
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
-ms-transform: translateY(-50%);
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
#backgroundArt {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: var(--corner-radius);
|
||||||
|
overflow: hidden;
|
||||||
|
z-index: -1;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
#backgroundImage {
|
||||||
|
filter: blur(20px);
|
||||||
|
position: absolute;
|
||||||
|
width: 140%;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%) translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
#backgroundImageBack {
|
||||||
|
filter: blur(20px);
|
||||||
|
position: absolute;
|
||||||
|
width: 140%;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%) translateY(-50%);
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#songLabel {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 20px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#artistLabel {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 100;
|
||||||
|
font-style: italic;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#albumLabel {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 100;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#progressBg {
|
||||||
|
margin-top: 5px;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #1F1F1F;
|
||||||
|
}
|
||||||
|
|
||||||
|
#progressBar {
|
||||||
|
border-radius: 5px;
|
||||||
|
height: 5px;
|
||||||
|
width: 20%;
|
||||||
|
background-color: #ffffff;
|
||||||
|
margin: 10px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#times {
|
||||||
|
position: relative;
|
||||||
|
height: 10px;
|
||||||
|
font-size: 8px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 3.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
#progressTime {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
#duration {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-show {
|
||||||
|
opacity: 1;
|
||||||
|
transition: all 0.25s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-fade {
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.25s ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -111,6 +111,34 @@ function getModuleUrl() {
|
|||||||
return url.substring(0, url.lastIndexOf('/'));
|
return url.substring(0, url.lastIndexOf('/'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadModuleResources(resources) {
|
||||||
|
const promises = resources.map(res => {
|
||||||
|
const key = res.id || res.url;
|
||||||
|
if (document.getElementById(key)) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
if (res.type === 'css') {
|
||||||
|
loadCSSModule(key, res.url);
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
if (res.type === 'js') {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.id = key;
|
||||||
|
script.src = res.url;
|
||||||
|
if (res.integrity) script.integrity = res.integrity;
|
||||||
|
if (res.crossorigin) script.crossOrigin = res.crossorigin;
|
||||||
|
script.onload = () => resolve();
|
||||||
|
script.onerror = () => reject(new Error(`Échec chargement script ${res.url}`));
|
||||||
|
document.head.appendChild(script);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
});
|
||||||
|
return Promise.all(promises).then(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function getBooleanParam(paramName, defaultValue) {
|
function getBooleanParam(paramName, defaultValue) {
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
const paramValue = urlParams.get(paramName);
|
const paramValue = urlParams.get(paramName);
|
||||||
@@ -245,4 +273,4 @@ function positionDiv(container) {
|
|||||||
|
|
||||||
window.loadCSSModule = loadCSSModule;
|
window.loadCSSModule = loadCSSModule;
|
||||||
window.getModuleUrl = getModuleUrl;
|
window.getModuleUrl = getModuleUrl;
|
||||||
window.getBooleanParam = getBooleanParam;
|
window.loadModuleResources = loadModuleResources;
|
||||||
|
|||||||
@@ -17,4 +17,5 @@
|
|||||||
<script type="text/javascript" src="modules/alert-banner/alert-banner.js"></script>
|
<script type="text/javascript" src="modules/alert-banner/alert-banner.js"></script>
|
||||||
<script type="text/javascript" src="modules/big-emote/big-emote.js"></script>
|
<script type="text/javascript" src="modules/big-emote/big-emote.js"></script>
|
||||||
<script type="text/javascript" src="modules/alert-video/alert-video.js"></script>
|
<script type="text/javascript" src="modules/alert-video/alert-video.js"></script>
|
||||||
|
<script type="text/javascript" src="modules/apple-music/apple-music.js"></script>
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user