<commit_before><template>
  <div id="app" :class="{ 'standalone' : inStandAloneMode }">
    <template v-if="authenticated">
      <div class="translucent" v-if="song" :style="{ backgroundImage: 'url('+song.album.cover+')' }">
      </div>
      <div id="main">
        <p class="collapse">
          <i class="fa fa-angle-down"></i>
        </p>
        <template v-if="connected">
          <div class="details" v-if="song">
            <div class="cover" :style="{ backgroundImage: 'url('+song.album.cover+')' }"></div>
            <div class="info">
              <div class="wrap">
                <p class="title text">{{ song.title }}</p>
                <p class="artist text">{{ song.artist.name }}</p>
                <p class="album text">{{ song.album.name }}</p>
              </div>
            </div>
          </div>
          <footer>
            <a class="favorite" @click.prevent="toggleFavorite">
              <i class="fa fa-heart yep" v-if="song && song.liked"></i>
              <i class="fa fa-heart-o" v-else></i>
            </a>
            <a class="prev" @click="playPrev">
              <i class="fa fa-step-backward"></i>
            </a>
            <a class="play-pause" @click.prevent="togglePlayback">
              <i class="fa fa-pause" v-if="playing"></i>
              <i class="fa fa-play" v-else></i>
            </a>
            <a class="next" @click="playNext">
              <i class="fa fa-step-forward"></i>
            </a>
            <a class="volume">
              <i class="fa fa-volume-up"></i>
            </a>
          </footer>
        </template>
        <div v-else class="loader">
          <p><span>Searching for Koel…</span></p>
          <div class="signal"></div>
        </div>
      </div>
    </template>

    <div class="login-wrapper" v-else>
      <login-form @loggedin="onUserLoggedIn"/>
    </div>
  </div>
</template>

<script>
  import { socket, ls } from '../services'
  import { userStore } from '../stores'
  import loginForm from '../components/auth/login-form.vue'

  export default {
    components: { loginForm },

    data () {
      return {
        authenticated: false,
        song: null,
        lastActiveTime: new Date().getTime(),
        inStandAloneMode: false,
        connected: false
      }
    },

    methods: {
      onUserLoggedIn () {
        this.authenticated = true
        this.init()
      },

      async init() {
        try {
          const user = await userStore.getProfile()
          userStore.init([], user)

          await socket.init()

          socket.listen('song', ({ song }) => {
            this.connected = true
            this.song = song
          }).listen('playback:stopped', () => {
            if (this.song) {
              this.song.playbackState = 'stopped'
            }
          })

          this.getStatus()
        } catch (e) {
          console.log(e)
          this.authenticated = false
        }
      },

      toggleFavorite () {
        if (!this.song) {
          return;
        }

        this.song.liked = !this.song.liked
        socket.broadcast('favorite:toggle')
      },

      togglePlayback () {
        if (this.song) {
          this.song.playbackState = this.song.playbackState === 'playing' ? 'paused' : 'playing'
        }

        socket.broadcast('playback:toggle')
      },

      playNext () {
        socket.broadcast('playback:next')
      },

      playPrev () {
        socket.broadcast('playback:prev')
      },

      getStatus() {
        socket.broadcast('song:getcurrent')
      },

      /**
       * As iOS will put a web app into standby/sleep mode (and halt all JS execution), 
       * this method will keep track of the last active time and keep the status always fresh.
       */
      heartbeat () {
        const now = new Date().getTime()
        if (now - this.lastActiveTime > 2000) {
          this.getStatus()
        }
        this.lastActiveTime = now
      }
    },

    computed: {
      playing () {
        return this.song && this.song.playbackState === 'playing'
      }
    },

    created () {
      window.setInterval(this.heartbeat, 500)
      this.inStandAloneMode = window.navigator.standalone
    },

    mounted () {
      // The app has just been initialized, check if we can get the user data with an already existing token
      const token = ls.get('jwt-token')
      if (token) {
        this.authenticated = true
        this.init()
      }
    }
  }
</script>

<style lang="scss"><commit_msg>Keep scanning for a desktop Koel<commit_after><template>
  <div id="app" :class="{ 'standalone' : inStandAloneMode }">
    <template v-if="authenticated">
      <div class="translucent" v-if="song" :style="{ backgroundImage: 'url('+song.album.cover+')' }">
      </div>
      <div id="main">
        <p class="collapse">
          <i class="fa fa-angle-down"></i>
        </p>
        <template v-if="connected">
          <div class="details" v-if="song">
            <div class="cover" :style="{ backgroundImage: 'url('+song.album.cover+')' }"></div>
            <div class="info">
              <div class="wrap">
                <p class="title text">{{ song.title }}</p>
                <p class="artist text">{{ song.artist.name }}</p>
                <p class="album text">{{ song.album.name }}</p>
              </div>
            </div>
          </div>
          <footer>
            <a class="favorite" @click.prevent="toggleFavorite">
              <i class="fa fa-heart yep" v-if="song && song.liked"></i>
              <i class="fa fa-heart-o" v-else></i>
            </a>
            <a class="prev" @click="playPrev">
              <i class="fa fa-step-backward"></i>
            </a>
            <a class="play-pause" @click.prevent="togglePlayback">
              <i class="fa fa-pause" v-if="playing"></i>
              <i class="fa fa-play" v-else></i>
            </a>
            <a class="next" @click="playNext">
              <i class="fa fa-step-forward"></i>
            </a>
            <a class="volume">
              <i class="fa fa-volume-up"></i>
            </a>
          </footer>
        </template>
        <div v-else class="loader">
          <p><span>Searching for Koel…</span></p>
          <div class="signal"></div>
        </div>
      </div>
    </template>

    <div class="login-wrapper" v-else>
      <login-form @loggedin="onUserLoggedIn"/>
    </div>
  </div>
</template>

<script>
  import { socket, ls } from '../services'
  import { userStore } from '../stores'
  import loginForm from '../components/auth/login-form.vue'

  export default {
    components: { loginForm },

    data () {
      return {
        authenticated: false,
        song: null,
        lastActiveTime: new Date().getTime(),
        inStandAloneMode: false,
        connected: false
      }
    },

    methods: {
      onUserLoggedIn () {
        this.authenticated = true
        this.init()
      },

      async init() {
        try {
          const user = await userStore.getProfile()
          userStore.init([], user)

          await socket.init()

          socket.listen('song', ({ song }) => {
            this.connected = true
            this.song = song
          }).listen('playback:stopped', () => {
            if (this.song) {
              this.song.playbackState = 'stopped'
            }
          })

          this.scan()
        } catch (e) {
          this.authenticated = false
        }
      },

      toggleFavorite () {
        if (!this.song) {
          return;
        }

        this.song.liked = !this.song.liked
        socket.broadcast('favorite:toggle')
      },

      togglePlayback () {
        if (this.song) {
          this.song.playbackState = this.song.playbackState === 'playing' ? 'paused' : 'playing'
        }

        socket.broadcast('playback:toggle')
      },

      playNext () {
        socket.broadcast('playback:next')
      },

      playPrev () {
        socket.broadcast('playback:prev')
      },

      getStatus() {
        socket.broadcast('song:getcurrent')
      },

      /**
       * As iOS will put a web app into standby/sleep mode (and halt all JS execution), 
       * this method will keep track of the last active time and keep the status always fresh.
       */
      heartbeat () {
        const now = new Date().getTime()
        if (now - this.lastActiveTime > 2000) {
          this.getStatus()
        }
        this.lastActiveTime = now
      },

      /**
       * Scan for an active (desktop) Koel instance.
       */
      scan () {
        if (!this.connected) {
          this.getStatus()
          window.setTimeout(this.scan, 1000)
        }
      }
    },

    computed: {
      playing () {
        return this.song && this.song.playbackState === 'playing'
      }
    },

    created () {
      window.setInterval(this.heartbeat, 500)
      this.inStandAloneMode = window.navigator.standalone
    },

    mounted () {
      // The app has just been initialized, check if we can get the user data with an already existing token
      const token = ls.get('jwt-token')
      if (token) {
        this.authenticated = true
        this.init()
      }
    }
  }
</script>

<style lang="scss">
{'fraction_non_alphanumeric': 0.15637547476939773, 'fraction_numerical': 0.0019533369506239827, 'mean_word_length': 1.6582059417363715, 'pattern_counts': {'":': 0, '<': 143, '<?xml version=': 0, '>': 149, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, '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': '3933213', 'n_tokens_mistral': 2867, 'n_tokens_neox': 2730, 'n_words': 606}