hummingbird-me/kitsu-web

View on GitHub
app/templates/media/index.hbs

Summary

Maintainability
Test Coverage
{{! @TODO: Componentize }}
<div class="media-browse col-sm-12">
  <div class="media-grid container">
    <div class="row">
      <div class="filter-options">
        <div class="filter-wrapper">
          {{! Year Filter }}
          <div class="filter-widget">
            <div class="filter-header">
              <label class="filter-title">
                {{t "media.index.filters.year"}}
              </label>
              <span class="filter-values">
                {{dirtyYear.firstObject}} -
                {{#if (eq dirtyYear.lastObject maxYear)}}
                  ∞
                {{else}}
                  {{dirtyYear.lastObject}}
                {{/if}}
              </span>
            </div>
            <div class="filter-slider--wrapper">
              {{range-slider
                class="slider"
                min=minYear
                max=maxYear
                start=year
                step=1
                connect=true
                formatTo=(action "formatValue")
                on-slide=(action (mut dirtyYear))
                on-change=(action (mut year) dirtyYear)
              }}
            </div>
            <div class="filter-legend">
              <div class="low-value">{{minYear}}</div>
              <div class="high-value">∞</div>
            </div>
          </div>

          {{! Rating Filter }}
          <div class="filter-widget">
            <div class="filter-header">
              <label class="filter-title">
                {{t "media.index.filters.score"}}
              </label>
              <span class="filter-values">
                {{dirtyRating.firstObject}}% - {{dirtyRating.lastObject}}%
              </span>
            </div>
            <div class="filter-slider--wrapper">
              {{range-slider
                class="slider"
                start=averageRating
                min=5
                connect=true
                step=1
                formatTo=(action "formatValue")
                on-slide=(action (mut dirtyRating))
                on-change=(action (mut averageRating) dirtyRating)
              }}
            </div>
            <div class="filter-legend">
              <div class="low-value">
                5%
              </div>
              <div class="high-value">
                100%
              </div>
            </div>
          </div>

          {{! Unit Filter }}
          <div class="filter-widget">
            <div class="filter-header">
              <label class="filter-title">
                {{#if isAnime}}
                  {{t "media.index.filters.units" type="anime"}}
                {{else}}
                  {{t "media.index.filters.units" type="manga"}}
                {{/if}}
              </label>
              <span class="filter-values">
                {{dirtyUnits.firstObject}}
                -
                {{#if (eq dirtyUnits.lastObject 100)}}
                  ∞
                {{else}}
                  {{dirtyUnits.lastObject}}
                {{/if}}
              </span>
            </div>
            <div class="filter-slider--wrapper">
              {{range-slider
                class="slider"
                min=1
                max=100
                start=unitCount
                step=1
                connect=true
                formatTo=(action "formatValue")
                on-slide=(action (mut dirtyUnits))
                on-change=(action (mut unitCount) dirtyUnits)
              }}
            </div>
            <div class="filter-legend">
              <div class="low-value">1</div>
              <div class="high-value">∞</div>
            </div>
          </div>

          {{! Anime Options }}
          {{#if isAnime}}
            {{! Age Rating Filter }}
            <div class="filter-widget">
              <div class="filter-header">
                <label class="filter-title">
                  {{t "media.index.filters.rating"}}
                </label>
                <span class="filter-values">
                  {{#if (is-empty ageRating)}}
                    {{availableRatings.length}}
                  {{else}}
                    {{ageRating.length}}
                  {{/if}}
                </span>
              </div>
              {{#media/filter-widgets/multi-select
                class="rating-select"
                includeAll=true
                selected=ageRating
                selection=availableRatings
                onChange=(action (mut ageRating)) as |option|
              }}
                {{capitalize option}}
              {{/media/filter-widgets/multi-select}}
            </div>

            {{! Streamer Filter }}
            <div class="filter-widget">
              {{#if availableStreamers}}
                <div class="filter-header">
                  <label class="filter-title">
                    {{t "media.index.filters.streamers"}}
                  </label>
                  <span class="filter-values">
                    {{#if (is-empty streamers)}}
                      {{availableStreamers.length}}
                    {{else}}
                      {{streamers.length}}
                    {{/if}}
                  </span>
                </div>
                {{#media/filter-widgets/multi-select
                  class="box-select"
                  tooltip=true
                  tooltipClasses="hint--top hint--bounce hint--rounded"
                  selected=streamers
                  selection=(map-by "siteName" availableStreamers)
                  onChange=(action (mut streamers)) as |option|
                }}
                  {{svg-jar (to-lower option) class=(to-lower option) width="32" height="32" data-test-filter-streamer="true"}}
                {{/media/filter-widgets/multi-select}}
              {{else}}
                <div class="filter-header">
                  <label class="filter-title">
                    {{t "media.index.filters.streamers"}}
                  </label>
                </div>
                <div class="text-xs-center m-t-1">
                  {{loading-spinner size="large" class="white"}}
                </div>
              {{/if}}
            </div>

            {{! Season Filter }}
            <div class="filter-widget category-filter">
              <div class="filter-header">
                <label class="filter-title">
                  {{t "media.index.filters.seasons"}}
                </label>
                <span class="filter-values">
                  {{#if (is-empty season)}}
                    {{availableSeasons.length}}
                  {{else}}
                    {{season.length}}
                  {{/if}}
                </span>
              </div>
              {{#media/filter-widgets/multi-select
                class="category-select"
                includeAll=true
                selected=season
                selection=availableSeasons
                onChange=(action (mut season)) as |option|
              }}
                <a href="#" data-test-filter-season>{{capitalize option}}</a>
                <span class="exclude-genre hint--left hint--bounce hint--rounded" aria-label="Remove">{{svg-jar "close"}}</span>
                <span class="include-genre hint--left hint--bounce hint--rounded" aria-label="Filter">{{svg-jar "checkmark"}}</span>
              {{/media/filter-widgets/multi-select}}
            </div>
          {{/if}}

          {{! Type Filter }}
          <div class="filter-widget category-filter">
            <div class="filter-header">
              <label class="filter-title">
                {{t "media.index.filters.types"}}
              </label>
              <span class="filter-values">
                {{#if (is-empty subtype)}}
                  {{availableSubtypes.length}}
                {{else}}
                  {{subtype.length}}
                {{/if}}
              </span>
            </div>
            {{#media/filter-widgets/multi-select
              class="category-select"
              includeAll=true
              selected=subtype
              selection=availableSubtypes
              onChange=(action (mut subtype)) as |option|
            }}
              <a href="#" data-test-filter-subtype>
                {{#if isAnime}}
                  {{t (concat "media-shared.types.anime." option)}}
                {{else}}
                  {{t (concat "media-shared.types.manga." option)}}
                {{/if}}
              </a>
              <span class="exclude-genre hint--left hint--bounce hint--rounded" aria-label="Remove">{{svg-jar "close"}}</span>
              <span class="include-genre hint--left hint--bounce hint--rounded" aria-label="Filter">{{svg-jar "checkmark"}}</span>
            {{/media/filter-widgets/multi-select}}
          </div>

          {{! Category Filter }}
          <div class="filter-widget category-filter">
            {{media/filter-widgets/category-list
              selection=categories
              update=(action (mut categories))
            }}
          </div>
        </div>
      </div>

      <div class="media-poster-header">
        {{! Search }}
        <span class="filter-container">
          {{search-input
            class="search-media tag-input"
            inputClass="form-control"
            text=text
            update=(action (mut text))
            placeholder=(t "media.index.search")
          }}
        </span>
      </div>

      {{! Media List }}
      <div class="media-posters">
        <div class="row">
          {{! Sort }}
          <span class="sort-container">
            {{#bootstrap/bs-dropdown as |dropdown|}}
              {{#dropdown.button type="button--dark-outline" class="button--small" disabled=(not (is-empty text))}}
                {{t (concat "media.index.sort." sort)}}
              {{/dropdown.button}}
              {{#dropdown.menu}}
                {{#each sortOptions as |sortOption|}}
                  {{#dropdown.menu-item onClick=(action (mut sort) sortOption)}}
                    {{t (concat "media.index.sort." sortOption)}}
                    {{#if (eq sort sortOption)}}
                      <span class="dropdown-checkmark">
                        {{svg-jar "checkmark"}}
                      </span>
                    {{/if}}
                  {{/dropdown.menu-item}}
                {{/each}}
              {{/dropdown.menu}}
            {{/bootstrap/bs-dropdown}}
          </span>
          {{#if model.taskInstance.isRunning}}
            <div class="text-xs-center w-100 m-t-1">
              {{loading-spinner size="large"}}
              <p>Loading Media...</p>
            </div>
          {{else if model.taskInstance.error}}
            <div class="text-xs-center w-100 m-t-1">
              {{t "errors.load"}}
            </div>
          {{else if taskValue}}
            {{#infinite-pagination onPagination=(route-action "onPagination")}}
              <div class="media-posters-list">
                {{#each taskValue as |media|}}
                  {{media/media-poster media=media}}
                {{/each}}
              </div>
            {{/infinite-pagination}}
          {{else}}
            <div class="text-xs-center w-100 m-t-1">
              {{t "media.none"}}
            </div>
          {{/if}}
        </div>
      </div>
    </div>
  </div>
</div>