hummingbird-me/kitsu-web

View on GitHub
app/components/media/media-sidebar.js

Summary

Maintainability
A
45 mins
Test Coverage
F
23%
import Component from '@ember/component';
import { get, set } from '@ember/object';
import { inject as service } from '@ember/service';
import { capitalize } from '@ember/string';
import { task } from 'ember-concurrency';
import RSVP from 'rsvp';

export default Component.extend({
  classNames: ['media-sidebar'],
  isFavorite: false,
  queryCache: service(),
  raven: service(),
  store: service(),

  didReceiveAttrs() {
    this._super(...arguments);
    if (get(this, 'session.hasUser')) {
      get(this, 'getFavorite').perform().then(results => {
        const record = get(results, 'firstObject');
        if (record) {
          set(this, 'favoriteRecord', record);
          set(this, 'isFavorite', true);
        } else {
          set(this, 'favoriteRecord', null);
          set(this, 'isFavorite', false);
        }
      }).catch(error => {
        get(this, 'raven').captureException(error);
      });
    }

    if (get(this, 'media.modelType') === 'anime') {
      get(this, 'getStreamersTask').perform();
    }
  },

  getFavorite: task(function* () {
    return yield get(this, 'queryCache').query('favorite', this._getRequestOptions());
  }).restartable(),

  getStreamersTask: task(function* () {
    const media = get(this, 'media');
    const streamingLinks = media.hasMany('streamingLinks');
    if (streamingLinks.value()) {
      return yield RSVP.all(streamingLinks.value().map(streamingLink => (
        streamingLink.belongsTo('streamer').load()
      )));
    }
    return yield streamingLinks.load().then(records => (
      RSVP.all(records.map(record => record.belongsTo('streamer').load()))
    ));
  }).restartable(),

  actions: {
    toggleFavorite() {
      if (!get(this, 'session.hasUser')) {
        return get(this, 'session').signUpModal();
      }

      if (get(this, 'getFavorite.isRunning')) { return; }
      if (get(this, 'isFavorite')) {
        this._destroyFavorite();
      } else {
        this._createFavorite();
      }
    }
  },

  _createFavorite() {
    const record = get(this, 'store').createRecord('favorite', {
      item: get(this, 'media'),
      user: get(this, 'session.account')
    });
    set(this, 'isFavorite', true);
    record.save().then(() => {
      set(this, 'favoriteRecord', record);
    }).catch(() => {
      set(this, 'isFavorite', false);
    });
  },

  _destroyFavorite() {
    set(this, 'isFavorite', false);
    get(this, 'favoriteRecord').destroyRecord().then(() => {
      get(this, 'queryCache').invalidateQuery('favorite', this._getRequestOptions());
    }).catch(() => {
      set(this, 'isFavorite', true);
    });
  },

  _getRequestOptions() {
    const mediaType = get(this, 'media.modelType');
    const mediaId = get(this, 'media.id');
    return {
      filter: {
        item_type: capitalize(mediaType),
        item_id: mediaId,
        user_id: get(this, 'session.account.id')
      }
    };
  }
});