Rework content commands, add audio player
This commit is contained in:
@ -0,0 +1,128 @@
|
||||
|
||||
struct AudioPlayer: HtmlProducer {
|
||||
|
||||
let playingText: String
|
||||
|
||||
let items: [PlaylistItem]
|
||||
|
||||
private var top: String {
|
||||
"""
|
||||
<div class='top'>
|
||||
<div> </div>
|
||||
<div class='top-center'>\(playingText)</div>
|
||||
<div class='show-playlist'><svg><use href='#\(AudioPlayerPlaylistIcon.name)'></use></svg></div>
|
||||
</div>
|
||||
"""
|
||||
}
|
||||
|
||||
private var center: String {
|
||||
"""
|
||||
<div class='center'>
|
||||
<img data-amplitude-song-info='cover_art_url' class='main-album-art'/>
|
||||
<div class='song-meta-data'>
|
||||
<span data-amplitude-song-info='name' class='song-name'></span>
|
||||
<span data-amplitude-song-info='artist' class='song-artist'></span>
|
||||
</div>
|
||||
<div class='time-progress'>
|
||||
<div id='progress-container'>
|
||||
<input type='range' class='amplitude-song-slider'/>
|
||||
<progress id='song-played-progress' class='amplitude-song-played-progress'></progress>
|
||||
<progress id='song-buffered-progress' class='amplitude-buffered-progress' value='0'></progress>
|
||||
</div>
|
||||
<div class='time-container'>
|
||||
<span class='current-time'>
|
||||
<span class='amplitude-current-hours'></span>:<span class='amplitude-current-minutes'></span>:<span class='amplitude-current-seconds'></span>
|
||||
</span>
|
||||
<span class='duration'>
|
||||
<span class='amplitude-duration-hours'></span>:<span class='amplitude-duration-minutes'></span>:<span class='amplitude-duration-seconds'></span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
}
|
||||
|
||||
private var controls: String {
|
||||
"""
|
||||
<div id="audio-player-controls">
|
||||
<svg id="previous" class="amplitude-prev"><use href='#\(AudioPlayerPreviousIcon.name)'></use></svg>
|
||||
<div class="amplitude-play-pause" id="play-pause">
|
||||
<svg class="play-icon"><use href='#\(AudioPlayerPlayIcon.name)'></use></svg>
|
||||
<svg class="pause-icon"><use href='#\(AudioPlayerPauseIcon.name)'></use></svg>
|
||||
</div>
|
||||
<svg id="next" class="amplitude-next"><use href='#\(AudioPlayerNextIcon.name)'></use></svg>
|
||||
</div>
|
||||
"""
|
||||
}
|
||||
|
||||
private var playlistStart: String {
|
||||
"""
|
||||
<div id="playlist-container">
|
||||
<div class="top">
|
||||
<div class="queue">Playlist</div>
|
||||
<div class="close-playlist"><svg><use href='#\(AudioPlayerCloseIcon.name)'></use></svg></div>
|
||||
</div>
|
||||
<div class="playlist">
|
||||
"""
|
||||
}
|
||||
|
||||
private var playlistEnd: String {
|
||||
"""
|
||||
</div>
|
||||
|
||||
<div class="white-player-playlist-controls">
|
||||
<img data-amplitude-song-info="cover_art_url" class="playlist-album-art"/>
|
||||
<div class="playlist-controls">
|
||||
<div class="playlist-meta-data">
|
||||
<span data-amplitude-song-info="name" class="song-name"></span>
|
||||
<span data-amplitude-song-info="artist" class="song-artist"></span>
|
||||
</div>
|
||||
<div class="playlist-control-wrapper">
|
||||
<svg class="amplitude-prev" id="playlist-previous"><use href='#\(AudioPlayerPreviousIcon.name)'></use></svg>
|
||||
<div class="amplitude-play-pause" id="playlist-play-pause">
|
||||
<svg class="play-icon"><use href='#\(AudioPlayerPlayIcon.name)'></use></svg>
|
||||
<svg class="pause-icon"><use href='#\(AudioPlayerPauseIcon.name)'></use></svg>
|
||||
</div>
|
||||
<svg class="amplitude-next" id="playlist-next"><use href='#\(AudioPlayerNextIcon.name)'></use></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
}
|
||||
|
||||
func populate(_ result: inout String) {
|
||||
result += "<div class='audio-player'>"
|
||||
result += top
|
||||
result += center
|
||||
result += controls
|
||||
result += playlistStart
|
||||
for item in items {
|
||||
result += item.content
|
||||
}
|
||||
result += playlistEnd
|
||||
result += "</div>"
|
||||
}
|
||||
|
||||
struct PlaylistItem {
|
||||
|
||||
let index: Int
|
||||
|
||||
let image: String
|
||||
|
||||
let name: String
|
||||
|
||||
let album: String
|
||||
|
||||
let track: Int
|
||||
|
||||
let artist: String
|
||||
|
||||
var content: String {
|
||||
"""
|
||||
<div class="playlist-song amplitude-song-container amplitude-play-pause amplitude-paused" data-amplitude-song-index="\(index)"><img src="\(image)"><div class="playlist-song-meta"><span class="playlist-song-name">\(name)</span><span class="playlist-song-artist">\(album) • \(artist)</span></div></div>
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
import Foundation
|
||||
|
||||
struct AmplitudeSong: Codable {
|
||||
let name: String
|
||||
let artist: String
|
||||
let album: String
|
||||
let track: String
|
||||
let url: String
|
||||
let cover_art_url: String
|
||||
}
|
||||
|
||||
struct AudioPlayerScript: HtmlProducer {
|
||||
|
||||
let items: [AmplitudeSong]
|
||||
|
||||
init(items: [AmplitudeSong]) {
|
||||
self.items = items
|
||||
}
|
||||
|
||||
func populate(_ result: inout String) {
|
||||
result += "<script>\n"
|
||||
result += "Amplitude.init({ songs: "
|
||||
let songData = try! JSONEncoder().encode(items)
|
||||
result += String(data: songData, encoding: .utf8)!
|
||||
result += "});"
|
||||
result += "function playEntry(index) { Amplitude.playSongAtIndex(index) };"
|
||||
result += animatePlaylist
|
||||
result += "</script>"
|
||||
}
|
||||
|
||||
private var animatePlaylist: String {
|
||||
"""
|
||||
const el = document.getElementById('playlist-container')
|
||||
document.getElementsByClassName('show-playlist')[0].addEventListener('click', function(){
|
||||
el.classList.remove('slide-out-top');
|
||||
el.classList.add('slide-in-top');
|
||||
el.style.display = "block";
|
||||
});
|
||||
document.getElementsByClassName('close-playlist')[0].addEventListener('click', function(){
|
||||
el.classList.remove('slide-in-top');
|
||||
el.classList.add('slide-out-top');
|
||||
el.style.display = "none";
|
||||
});
|
||||
"""
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user