diff --git a/src/components/AudioPlayer.js b/src/components/AudioPlayer.js
deleted file mode 100644
index de2c8ea..0000000
--- a/src/components/AudioPlayer.js
+++ /dev/null
@@ -1,368 +0,0 @@
-import { LitElement, css, html, unsafeCSS } from 'lit'
-import { Task } from '@lit-labs/task'
-import WaveSurfer from 'wavesurfer.js'
-import { formatSeconds } from '../api/utils'
-
-import MainCSS from '../assets/styles/main.scss?inline'
-
-// temp bg image
-import Photo from '/images/Meredith Monk (1974) Photo Lauretta HArris.jpg?url'
-
-// components
-import './SvgIcon.js'
-import './RangeSlider.js'
-
-class AudioPlayer extends LitElement {
- static properties = {
- details: { type: Object },
- data: { state: true },
- playing: { state: true },
- volume: { state: true },
- track: { state: true },
- audio: { state: true },
- }
-
- constructor() {
- super()
- this.details = {}
- this.data = {}
- this.audio = null
- this.playing = false
- this.audioEl = {}
-
- this.track = 0
- }
-
- _getAudio = new Task(
- this,
- async () => {
- if (!this.details.media) return
-
- if (this.details.tracks) {
- console.log(this.details.tracks[0])
-
- if (!this.audio) {
- this.initAudio()
- }
-
- this.audio.load(this.details.tracks[this.track])
-
- return this.audio
- } else {
- try {
- if (this.audio.media) {
- this.audio.destroy()
- }
-
- const wsEl = this.initWs()
-
- this.audio.load(`/media/${this.details.media}.mp3`, this.details.data)
-
- return wsEl
- } catch (err) {
- console.error(err)
- }
- }
- },
- () => [ this.details ]
- )
-
- initAudio() {
- this.audio = document.createElement('audio')
-
-
- this.audio.addEventListener('loadstart', () => {
- this.loading = true
- })
-
- this.audio.addEventListener('canplay', () => {
- this.loading = false
- })
-
- this.audio.addEventListener('play', () => {
- this.playing = true
- })
-
- this.audio.addEventListener('pause', () => {
- this.playing = false
- })
-
- this.audio.addEventListener('loadedmetadata', () => {
- this.data = {
- ...this.data,
- position: 0,
- duration: this.audio.duration
- }
- })
-
- this.audio.addEventListener('ended', () => {
- // auto play next track or end if last track
- })
-
- this.audio.addEventListener('timeupdate', () => {
- this.data = {
- ...this.data,
- position: this.audio.currentTime
- }
- })
-
- this.audio.addEventListener('seeking', () => {
- this.data = {
- ...this.data,
- position: this.audio.currentTime
- }
- })
- }
-
- initWs() {
- const div = document.createElement('div')
- div.classList.add('waveform')
-
- this.audio = WaveSurfer.create({
- container: div,
- waveColor: '#ffffff50',
- progressColor: 'white',
- cursorColor: 'transparent',
- fillParent: true,
- barWidth: 4,
- barGap: 6,
- barRadius: 5,
- dragToSeek: true,
- })
-
- this.audio.setVolume(0.6)
- this.volume = this.audio.getVolume()
-
- this.audio.on('ready', (duration) => {
- this.data = {
- ...this.data,
- position: 0,
- duration
- }
- })
-
- this.audio.on('play', () => {
- this.playing = true
- })
-
- this.audio.on('pause', () => {
- this.playing = false
- })
-
- this.audio.on('interaction', (newTime) => {
- this.data = {
- ...this.data,
- position: newTime
- }
- })
-
- this.audio.on('timeupdate', (currentTime) => {
- this.data = {
- ...this.data,
- position: currentTime
- }
- })
-
- return div
- }
-
- togglePlay() {
- this.audio.playPause()
- }
-
- skipForward() {
- this.audio.skip(15)
- }
-
- skipBackward() {
- this.audio.skip(-15)
- }
-
- nextTrack() {
- this.dispatchEvent(new Event('next-track', { bubbles: true, composed: true }))
- }
-
- prevTrack() {
- this.dispatchEvent(new CustomEvent('prev-track', { bubbles: true, composed: true }))
- }
-
- volHandler(evt) {
- if (evt.detail) {
- this.audio.setVolume(evt.detail.value)
- }
- }
-
- progressCalc() {
- const { position, duration } = this.data
- let percentage = 0
-
- if (position && duration) {
- percentage = (position / duration) * 100
- }
-
- return `${percentage}%`
- }
-
- render() {
- return html`
-
-
- ${this.details.title}
- ${this.details.details}
-
-
-
-
-
- ${this._getAudio.render({
- complete: (div) => div
- })}
-
-
${formatSeconds(this.data.position)} ${formatSeconds(this.data.duration)}
-
-
-
- `
- }
-
- static styles = [ css`${unsafeCSS(MainCSS)}`, css`
- :host {
- position: absolute;
- inset: 0;
- padding: 1em;
- display: grid;
- grid-template-rows: 0.7fr 0.7fr 1fr;
- gap: 1em;
- opacity: 0;
- animation: fadeIn 0.125s ease-in forwards;
- overflow: hidden;
- border-radius: 0.75em 0 0 0.75em;
- isolation: isolate;
- }
-
- .bg-img {
- position: absolute;
- inset: 0;
- object-fit: cover;
- object-position: center 25%;
- opacity: 0.2;
- mix-blend-mode: overlay;
- scale: 1.1;
- width: 100%;
- height: 100%;
- }
-
- header {
- color: var(--netural-100, white);
- font-size: 1.5em;
- line-height: 1.2;
- padding: 0.5em;
- }
-
- header > p {
- font-size: 1.5em;
- max-width: 25ch;
- }
-
- .info, .controls {
- position: relative;
- }
-
- .progress {
- --progress-bar: 0%;
- position: absolute;
- display: flex;
- align-items: center;
- inset: 0;
- z-index: 3;
- pointer-events: none;
- }
-
- .progress > .bar {
- height: 0.25em;
- width: var(--progress-bar);
- background: #ffffff80;
- border-radius: 100vmax;
- }
-
- .time_pos, .time_dur {
- font-family: sans-serif;
- font-size: 0.85em;
- color: var(--neutral-100, white);
- position: absolute;
- bottom: 1em;
- }
-
- .time_dur {
- right: 0;
- }
-
- .controls {
- display: flex;
- flex-direction: column;
- justify-content: space-evenly;
- width: 65%;
- margin-inline: auto;
- }
-
- .controls > div {
- display: flex;
- align-items: center;
- justify-content: space-evenly;
- margin-block-end: 1em;
- gap: 0.25em;
- }
-
- mm-icon {
- color: white;
- font-size: 2.5em;
- }
-
- mm-icon.skip15 {
- font-size: 1.5em;
- }
-
- mm-icon:not(.skip15, .play, .pause) {
- font-size: 1em;
- }
-
- mm-volctrl {
- display: block;
- width: 80%;
- margin-inline: auto;
- }
-
- .waveform {
- position: relative;
- height: 15em;
- display: flex;
- flex-direction: column;
- justify-content: center;
- }
-
- @keyframes fadeIn {
- to {
- opacity: 1;
- }
- }
- ` ]
-}
-
-customElements.define('mm-aplayer', AudioPlayer)
diff --git a/src/components/HorizontalScroller.js b/src/components/HorizontalScroller.js
index 6a1daff..a02e13f 100644
--- a/src/components/HorizontalScroller.js
+++ b/src/components/HorizontalScroller.js
@@ -32,6 +32,7 @@ class HorizontalScroller extends LitElement {
scroll-padding-inline: 0.5em;
padding-inline-start: 0.5em;
padding-inline-end: 0.5em;
+ padding-block-start: 0.25em;
padding-block-end: 0.75em;
}
`
diff --git a/src/components/ImageViewer.js b/src/components/ImageViewer.js
index cca8ba3..e68c0ca 100644
--- a/src/components/ImageViewer.js
+++ b/src/components/ImageViewer.js
@@ -4,44 +4,84 @@ import MainCSS from '../assets/styles/main.scss?inline'
class ImageViewer extends LitElement {
static properties = {
- src: { type: String },
+ details: { type: Object },
imgEl: { state: true },
+ figEl: { state: true },
captionWidth: { state: true },
- loading: { state: true }
+ loading: { state: true },
+ title: { state: true },
+ caption : { state: true }
}
constructor() {
super()
- this.src = ''
+ this.details = {}
this.imgEl = new Image()
this.captionWidth = 'min-content'
this.loading = true
+
+ this.title = ''
+ this.caption = ''
+
+ this.figEl = {}
+ }
+
+ firstUpdated() {
+ this.figEl = this.shadowRoot.querySelector('figure')
}
connectedCallback() {
super.connectedCallback()
+
this.imgEl.addEventListener('load', () => {
+ this.figEl.classList.remove('unloading')
+
this.captionWidth = `${this.imgEl.offsetWidth}px`
this.loading = false
})
}
- set src(val) {
- if (val) {
- this.imgEl.src = val
- console.log(this.imgEl)
+ willUpdate(att) {
+ if (att.has('details') && this.details?.media) {
+ this.figEl.classList.add('unloading')
+
+ this.figEl.addEventListener('transitionend', () => {
+ this.title = this.details.title || ''
+ this.caption = this.details.caption || ''
+ this.imgEl.hidden = false
+
+ this.imgEl.src = this.details.media
+ })
+ }
+ this.update()
+ }
+
+ fullscreen() {
+ if (this.figEl.webkitSupportsFullscreen) {
+ this.figEl.webkitEnterFullscreen()
+ return
+ }
+
+ if (document.fullscreenElement !== null) {
+ document.exitFullscreen()
+ this.figEl.removeAttribute('data-fullscreen')
+ } else {
+ this.figEl.requestFullscreen()
+ this.figEl.setAttribute('data-fullscreen', true)
}
}
render() {
return html`
-