Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: set buffer on endtime save causing immediate song end skip #147

Merged
merged 7 commits into from
Oct 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/actions/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import CurrentSnip from '../models/snip/current-snip.js'
import TrackList from '../models/tracklist/track-list.js'
import NowPlayingIcons from '../models/now-playing-icons.js'

import Chorus from '../models/chorus.js'
import SongTracker from '../observers/song-tracker.js'
import TrackListObserver from '../observers/track-list.js'
import NowPlayingObserver from '../observers/now-playing.js'
Expand All @@ -21,13 +22,16 @@ class App {

#init() {
this._songTracker = new SongTracker()
this._chorus = new Chorus(this._songTracker)
this._snip = new CurrentSnip(this._songTracker)

this._nowPlayingIcons = new NowPlayingIcons(this._snip)
this._trackListObserver = new TrackListObserver(new TrackList(this._store))
this._nowPlayingIcons = new NowPlayingIcons({ snip: this._snip, chorus: this._chorus })
this._nowPlayingObserver = new NowPlayingObserver({
snip: this._snip, songTracker: this._songTracker
snip: this._snip,
chorus: this._chorus,
songTracker: this._songTracker
})
this._trackListObserver = new TrackListObserver(new TrackList(this._songTracker))

this.#resetInterval()
this.#reInit()
Expand Down
4 changes: 2 additions & 2 deletions src/events/listeners/action-listeners.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Listeners from './listeners.js'

export default class ActionListeners extends Listeners {
constructor() {
super()
constructor(songTracker) {
super(songTracker)
this._setup = false
}

Expand Down
5 changes: 3 additions & 2 deletions src/events/listeners/header-listeners.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import Listeners from './listeners.js'

export default class HeaderListeners extends Listeners {
constructor() {
super()
constructor(songTracker) {
super(songTracker)

this._setup = false
this._viewInFocus = null
this._VIEWS = ['snip', 'speed', 'seek']
Expand Down
5 changes: 2 additions & 3 deletions src/events/listeners/listeners.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ import Seek from '../../models/seek/seek.js'
import Speed from '../../models/speed/speed.js'
import CurrentSnip from '../../models/snip/current-snip.js'
import { spotifyVideo } from '../../actions/overload.js'
import SongTracker from '../../observers/song-tracker.js'

export default class Listeners {
constructor() {
constructor(songTracker) {
this._video = spotifyVideo.element
this._seek = new Seek()
this._speed = new Speed()
this._snip = new CurrentSnip(new SongTracker())
this._snip = new CurrentSnip(songTracker)
}

_hide() {
Expand Down
6 changes: 3 additions & 3 deletions src/models/chorus.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import { parseNodeString } from '../utils/parser.js'
import { spotifyVideo } from '../actions/overload.js'

export default class Chorus {
constructor() {
constructor(songTracker) {
this._video = spotifyVideo.element
this.headerListeners = new HeaderListeners()
this.actionListeners = new ActionListeners()
this.headerListeners = new HeaderListeners(songTracker)
this.actionListeners = new ActionListeners(songTracker)
}

get isShowing() {
Expand Down
5 changes: 2 additions & 3 deletions src/models/now-playing-icons.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Chorus from './chorus.js'
import { store } from '../stores/data.js'
import { currentData } from '../data/current.js'
import { createControls } from '../components/controls.js'
Expand All @@ -8,9 +7,9 @@ import { currentSongInfo } from '../utils/song.js'
import { parseNodeString } from '../utils/parser.js'

export default class NowPlayingIcons {
constructor(snip) {
constructor({ snip, chorus }) {
this.snip = snip
this.chorus = new Chorus()
this.chorus = chorus

this.init()
}
Expand Down
12 changes: 5 additions & 7 deletions src/models/slider/slider-controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,16 @@ import { playback } from '../../utils/playback.js'
import { secondsToTime } from '../../utils/time.js'

export default class SliderControls {
#slider

constructor() {
this.#slider = new Slider()
this._slider = new Slider()
}

init() {
this.#slider.init()
this._slider.init()
}

setInitialValues(track) {
this.#slider.setInitialValues(track)
this._slider.setInitialValues(track)
this.#setInitialStartAndEndValues(track)
}

Expand Down Expand Up @@ -50,7 +48,7 @@ export default class SliderControls {
const current = playback.current()
const duration = playback.duration()

this.#slider.updateSliderLeftHalf(startTime ?? current)
this.#slider.updateSliderRightHalf(endTime ?? duration)
this._slider.updateSliderLeftHalf(startTime ?? current)
this._slider.updateSliderRightHalf(endTime ?? duration)
}
}
29 changes: 16 additions & 13 deletions src/models/slider/slider.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@ import { secondsToTime } from '../../utils/time.js'
import { currentSongInfo } from '../../utils/song.js'

export default class Slider {
#video
#leftDebouncer
#rightDebouncer
#isCurrentlyPlaying = true

constructor() {
this.#video = spotifyVideo.element
this._leftDebouncer = null
this._rightDebouncer = null
this._isCurrentlyPlaying = true
this._video = spotifyVideo.element
}

init() {
this.#setUpEvents()
this._video.element.setAttribute('lastSetThumb', '')
}

#setUpEvents() {
Expand All @@ -36,7 +35,7 @@ export default class Slider {
}

setInitialValues(track) {
this.#isCurrentlyPlaying = !track?.id ? true : track.id == currentSongInfo().id
this._isCurrentlyPlaying = !track?.id ? true : track.id == currentSongInfo().id

const { endTime, startTime } = track
const { endDisplay } = this.#elements
Expand Down Expand Up @@ -69,28 +68,32 @@ export default class Slider {
}

#setLeftValue() {
if (this.#leftDebouncer) clearTimeout(this.#leftDebouncer)
if (this._leftDebouncer) clearTimeout(this._leftDebouncer)

this.#leftDebouncer = setTimeout(() => {
this._leftDebouncer = setTimeout(() => {
const { inputLeft } = this.#elements
const currentValue = parseInt(inputLeft.value)

this.updateSliderLeftHalf(currentValue)

if (this.#isCurrentlyPlaying) this.#video.currentTime = inputLeft.value
if (this._isCurrentlyPlaying) this._video.currentTime = inputLeft.value

this._video.element.setAttribute('lastSetThumb', 'start')
}, 50)
}

#setRightValue() {
if (this.#rightDebouncer) clearTimeout(this.#rightDebouncer)
if (this._rightDebouncer) clearTimeout(this._rightDebouncer)

this.#rightDebouncer = setTimeout(() => {
this._rightDebouncer = setTimeout(() => {
const { inputRight } = this.#elements
const currentValue = parseInt(inputRight.value)

this.updateSliderRightHalf(currentValue)

if (this.#isCurrentlyPlaying) this.#video.currentTime = inputRight.value
if (this._isCurrentlyPlaying) this._video.currentTime = inputRight.value

this._video.element.setAttribute('lastSetThumb', 'end')
}, 50)
}

Expand Down
13 changes: 11 additions & 2 deletions src/models/snip/current-snip.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { spotifyVideo } from '../../actions/overload.js'
export default class CurrentSnip extends Snip {
constructor(songTracker) {
super()

this._songTracker = songTracker
this._video = spotifyVideo.element
}
Expand Down Expand Up @@ -56,9 +57,16 @@ export default class CurrentSnip extends Snip {
}
}

setCurrentTime({ prevEndTime, endTime }) {
const lastSetThumb = this._video.element.getAttribute('lastSetThumb')

if (lastSetThumb !== 'end') return
this._video.currentTime = Math.max(Math.min(prevEndTime, endTime) - 5, 1)
}

async save() {
const { inputLeft, inputRight } = this._elements
const { isSkipped } = await this.read()
const { isSkipped, endTime: prevEndTime } = await this.read()

await this._store.saveTrack({
id: currentSongInfo().id,
Expand All @@ -74,6 +82,7 @@ export default class CurrentSnip extends Snip {

const updatedValues = await this.read()
this.skipTrackOnSave(updatedValues)
this._songTracker.currentSongState = updatedValues
this.setCurrentTime({ prevEndTime, endTime: updatedValues.endTime })
await this._songTracker.updateCurrentSongData(updatedValues)
}
}
5 changes: 3 additions & 2 deletions src/models/tracklist/track-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import SnipIcon from './snip-icon.js'
import Chorus from '../chorus.js'
import TrackSnip from '../snip/track-snip.js'

import { store } from '../../stores/data.js'
import { trackSongInfo } from '../../utils/song.js'

export default class TrackList {
constructor(store) {
this._chorus = new Chorus()
constructor(songTracker) {
this._chorus = new Chorus(songTracker)
this._skipIcon = new SkipIcon(store)
this._snipIcon = new SnipIcon(store)
this._trackSnip = new TrackSnip(store)
Expand Down
5 changes: 2 additions & 3 deletions src/observers/now-playing.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import Chorus from '../models/chorus.js'
import SeekIcons from '../models/seek/seek-icon.js'

export default class NowPlayingObserver {
constructor({ snip, songTracker }) {
constructor({ snip, chorus, songTracker }) {
this._snip = snip
this._observer = null
this._songTracker = songTracker

this._chorus = new Chorus()
this._chorus = chorus
this._seekIcons = new SeekIcons()

this.observe()
Expand Down
21 changes: 14 additions & 7 deletions src/observers/song-tracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { songState } from '../data/song-state.js'
import { spotifyVideo } from '../actions/overload.js'

import { request } from '../utils/request.js'
import { playback } from '../utils/playback.js'
import { timeToSeconds } from '../utils/time.js'
import { highlightElement } from '../utils/higlight.js'

Expand All @@ -18,14 +19,15 @@ export default class SongTracker {
songStateData.isShared ? this.handleShared(songStateData) : await this.songChange(songStateData)
}

set currentSongState(values) {
async updateCurrentSongData(values) {
if (!values) return
if (!this._currentSongState) return

this._currentSongState = {
...this._currentSongState,
...this._currentSongState || {},
...values,
}

await this.#applyEffects(this._currentSongState)
}

get #isLooping() {
Expand All @@ -37,11 +39,12 @@ export default class SongTracker {
await request({
type: 'seek',
value: Math.max(parseInt(position, 10) - 1, 1) * 1000,
cb: () => { this.#mute(); setTimeout(() => this._video.volume = 1, 1000) }
cb: () => { this.#mute(); setTimeout(() => this.#unMute(), 1000) }
})
}

#mute() { this._video.volume = 0 }
#unMute() { this._video.volume = 1 }

#setupListeners() {
this._video.element.addEventListener('timeupdate', this.#handleTimeUpdate)
Expand Down Expand Up @@ -79,11 +82,12 @@ export default class SongTracker {
uris: [`spotify:track:${trackId}`],
position_ms: Math.max(parseInt(startTime, 10) - 1, 1) * 1000,
},
cb: () => { this.#mute(); setTimeout(() => this._video.volume = 1, 1000) }
cb: () => { this.#mute(); setTimeout(() => this.#unMute(), 1000) }
})
}

async songChange(initialData = null) {
this.#mute()
const songStateData = initialData ?? await this.#setCurrentSongData()
await this.#applyEffects(songStateData)
const { isSnip, isSkipped, startTime, isShared } = songStateData
Expand All @@ -98,9 +102,11 @@ export default class SongTracker {

if (currentPositionTime < parsedStartTime) {
await this.#seekTo(startTime)
} else {
this.#unMute()
}
} else {
this._video.volume = 1
this.#unMute()
}
}

Expand All @@ -120,7 +126,8 @@ export default class SongTracker {
const { startTime, endTime } = this._currentSongState
const currentTimeMS = parseInt(this._video.currentTime * 1000, 10)

const endTimeMS = parseInt(endTime, 10) * 1000 - 500
const isSongEnd = endTime == playback.duration()
const endTimeMS = parseInt(endTime, 10) * 1000 - (isSongEnd ? 100 : 0)
const atSongEnd = currentTimeMS >= endTimeMS
if (!atSongEnd) return

Expand Down