<commit_before><template>
  <tr
    class="song-item"
    draggable="true"
    :data-song-id="song.id"
    @click="clicked"
    @dblclick.prevent="playRightAwayyyyyyy"
    @dragstart="dragStart"
    @dragleave="removeDroppableState"
    @dragover.prevent="allowDrop"
    @drop.stop.prevent="handleDrop"
    @contextmenu.prevent="openContextMenu"
    :class="{ selected: item.selected, playing: playing }"
  >
    <td class="track-number">{{ song.track || '' }}</td>
    <td class="title">{{ song.title }}</td>
    <td class="artist">{{ song.artist.name }}</td>
    <td class="album">{{ song.album.name }}</td>
    <td class="time">{{ song.fmtLength }}</td>
    <td class="play" @click.stop="doPlayback">
      <i class="fa fa-pause-circle" v-if="song.playbackState === 'playing'"/>
      <i class="fa fa-play-circle" v-else/>
    </td>
  </tr>
</template>

<script>
import { playback } from '../../services'
import { queueStore } from '../../stores'
import $v from 'vuequery'

export default {
  props: ['item'],
  name: 'song-item',

  data () {
    return {
      parentSongList: null
    }
  },

  computed: {
    /**
     * A shortcut to access the current vm's song (instead of this.item.song).
     * @return {Object}
     */
    song () {
      return this.item.song
    },

    playing () {
      return this.song.playbackState === 'playing' || this.song.playbackState === 'paused'
    }
  },

  created () {
    this.parentSongList = $v(this).closest('song-list').vm
  },

  methods: {
    /**
     * Play the song right away.
     */
    playRightAwayyyyyyy () {
      if (!queueStore.contains(this.song)) {
        queueStore.queueAfterCurrent(this.song)
      }

      playback.play(this.song)
    },

    /**
     * Take the right playback action based on the current playback state.
     */
    doPlayback () {
      switch (this.song.playbackState) {
        case 'playing':
          playback.pause()
          break
        case 'paused':
          playback.resume()
          break
        default:
          this.playRightAwayyyyyyy()
          break
      }
    },

    clicked (event) {
      this.parentSongList.rowClicked(this, event)
    },

    dragStart (event) {
      this.parentSongList.dragStart(this, event)
    },

    removeDroppableState (event) {
      this.parentSongList.removeDroppableState(event)
    },

    /**
     * Add a "droppable" class and set the drop effect when other songs are dragged over the row.
     *
     * @param {Object} event The dragover event.
     */
    allowDrop (event) {
      this.parentSongList.allowDrop(event)
    },

    handleDrop (event) {
      this.parentSongList.handleDrop(this, event)
    },

    openContextMenu (event) {
      this.parentSongList.openContextMenu(this, event)
    }
  }
}
</script>

<style lang="sass">
@import "../../../sass/partials/_vars.scss";
@import "../../../sass/partials/_mixins.scss";

.song-item {
  border-bottom: 1px solid $color2ndBgr;
  height: 35px;

  html.no-touchevents &:hover {
    background: rgba(255, 255, 255, .05);
  }

  .time, .track-number {
    color: $color2ndText;
  }

  .title {<commit_msg>Refactor the song item component<commit_after><template>
  <tr
    class="song-item"
    draggable="true"
    :data-song-id="song.id"
    @click="clicked"
    @dblclick.prevent="playRightAwayyyyyyy"
    @dragstart="dragStart"
    @dragleave="dragLeave"
    @dragover.prevent="dragOver"
    @drop.stop.prevent="dropStop"
    @contextmenu.prevent="contextMenu"
    :class="{ selected: item.selected, playing: playing }"
  >
    <td class="track-number">{{ song.track || '' }}</td>
    <td class="title">{{ song.title }}</td>
    <td class="artist">{{ song.artist.name }}</td>
    <td class="album">{{ song.album.name }}</td>
    <td class="time">{{ song.fmtLength }}</td>
    <td class="play" @click.stop="doPlayback">
      <i class="fa fa-pause-circle" v-if="song.playbackState === 'playing'"/>
      <i class="fa fa-play-circle" v-else/>
    </td>
  </tr>
</template>

<script>
import { playback } from '../../services'
import { queueStore } from '../../stores'
import $v from 'vuequery'

export default {
  props: ['item'],
  name: 'song-item',

  data () {
    return {
      parentSongList: null
    }
  },

  computed: {
    /**
     * A shortcut to access the current vm's song (instead of this.item.song).
     * @return {Object}
     */
    song () {
      return this.item.song
    },

    /**
     * Determine if the current song is being played (or paused).
     * @return {Bool}
     */
    playing () {
      return this.song.playbackState === 'playing' || this.song.playbackState === 'paused'
    }
  },

  created () {
    this.parentSongList = $v(this).closest('song-list').vm
  },

  methods: {
    /**
     * Play the song right away.
     */
    playRightAwayyyyyyy () {
      if (!queueStore.contains(this.song)) {
        queueStore.queueAfterCurrent(this.song)
      }

      playback.play(this.song)
    },

    /**
     * Take the right playback action based on the current playback state.
     */
    doPlayback () {
      switch (this.song.playbackState) {
        case 'playing':
          playback.pause()
          break
        case 'paused':
          playback.resume()
          break
        default:
          this.playRightAwayyyyyyy()
          break
      }
    },

    /**
     * Proxy the click event to the parent song list component.
     * @param  {Event} event
     */
    clicked (event) {
      this.parentSongList.rowClicked(this, event)
    },

    /**
     * Proxy the dragstart event to the parent song list component.
     * @param  {Event} event
     */
    dragStart (event) {
      this.parentSongList.dragStart(this, event)
    },

    /**
     * Proxy the dragleave event to the parent song list component.
     * @param  {Event} event
     */
    dragLeave (event) {
      this.parentSongList.removeDroppableState(event)
    },

    /**
     * Proxy the dragover event to the parent song list component.
     * @param {Event} event The dragover event.
     */
    dragOver (event) {
      this.parentSongList.allowDrop(event)
    },

    /**
     * Proxy the dropstop event to the parent song list component.
     * @param  {Event} event
     */
    dropStop (event) {
      this.parentSongList.handleDrop(this, event)
    },

    /**
     * Proxy the contextmenu event to the parent song list component.
     * @param  {Event} event
     */
    contextMenu (event) {
      this.parentSongList.openContextMenu(this, event)
    }
  }
}
</script>

<style lang="sass">
@import "../../../sass/partials/_vars.scss";
@import "../../../sass/partials/_mixins.scss";

.song-item {
  border-bottom: 1px solid $color2ndBgr;
  height: 35px;

  html.no-touchevents &:hover {
    background: rgba(255, 255, 255, .05);
  }

  .time, .track-number {
    color: $color2ndText;
  }

  .title {
{'fraction_non_alphanumeric': 0.1565966141272621, 'fraction_numerical': 0.004670169293636894, 'mean_word_length': 2.3560235063663075, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 6, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7481812', 'n_tokens_mistral': 2377, 'n_tokens_neox': 2251, 'n_words': 490}