<commit_before><template>
  <div class="media-gallery-carousel">
    <carousel
      :per-page="1"
      :mouse-drag="false"
      :navigation-enabled="true"
      pagination-active-color="#828282"
      pagination-color="transparent"
      navigation-next-label="<i class='material-icons p15 cl-bg-tertiary pointer'>keyboard_arrow_right</i>"
      navigation-prev-label="<i class='material-icons p15 cl-bg-tertiary pointer'>keyboard_arrow_left</i>"
      ref="carousel"
      :speed="carouselTransitionSpeed"
      @pageChange="pageChange"
    >
      <slide
        v-for="(images, index) in gallery"
        :key="images.src">
        <div class="product-image-container bg-cl-secondary" :class="{'video-container w-100 h-100 flex relative': images.video}">
          <img
            v-show="placeholderImagesMap[index]"
            key="placeholderImage"
            class="inline-flex mw-100"
            src="/assets/placeholder.svg"
            ref="images"
            :alt="productName | htmlDecode"
          >
          <img
            v-show="lowerQualityImagesMap[index]"
            key="lowQualityImage"
            class="product-image inline-flex mw-100"
            :src="images.loading"
            @load="lowerQualityImageLoaded(index)"
            ref="images"
            :alt="productName | htmlDecode"
            data-testid="productGalleryImage"
            itemprop="image"
          >
          <img
            v-show="highQualityImagesLoadedMap[index]"
            key="highQualityImage"
            :src="images.src"
            @load="highQualityImageLoaded(index)"
            class="product-image inline-flex pointer mw-100"
            ref="images"
            @dblclick="openOverlay"
            :alt="productName | htmlDecode"
            data-testid="productGalleryImage"
            itemprop="image"
          >
          <product-video
            v-if="images.video && (index === currentPage)"
            v-bind="images.video"
            :index="index"
            @video-started="onVideoStarted"/>
        </div>
      </slide>
    </carousel>
    <i
      class="zoom-in material-icons p15 cl-bgs-tertiary pointer"
      @click="openOverlay"
    >zoom_in</i>
  </div>
</template>

<script>
import store from '@vue-storefront/core/store'
import { Carousel, Slide } from 'vue-carousel'
import ProductVideo from './ProductVideo'

export default {
  name: 'ProductGalleryCarousel',
  components: {
    Carousel,
    Slide,
    ProductVideo
  },
  props: {
    gallery: {
      type: Array,
      required: true
    },
    productName: {
      type: String,
      required: true
    },
    configuration: {
      type: Object,
      required: true
    }
  },
  data () {
    return {
      carouselTransitionSpeed: 0,
      currentPage: 0,
      hideImageAtIndex: null,
      lowerQualityImagesLoadedMap: {},
      highQualityImagesLoadedMap: {}
    }
  },
  computed: {
    placeholderImagesMap () {
      let visibilityMap = {}
      this.gallery.forEach((image, index) => {
        visibilityMap[index] = !this.lowerQualityImagesLoadedMap[index] && !this.highQualityImagesLoadedMap[index]
      })
      return visibilityMap
    },
    lowerQualityImagesMap () {
      let visibilityMap = {}
      this.gallery.forEach((image, index) => {
        visibilityMap[index] = !!this.lowerQualityImagesLoadedMap[index] && !this.highQualityImagesLoadedMap[index] && this.hideImageAtIndex !== index
      })
      return visibilityMap
    },
    highQualityImagesMap () {
      let visibilityMap = {}
      this.gallery.forEach((image, index) => {
        visibilityMap[index] = !!this.highQualityImagesLoadedMap[index] && this.hideImageAtIndex !== index
      })
      return visibilityMap
    }
  },
  beforeMount () {
    this.$bus.$on('filter-changed-product', this.selectVariant)
    this.$bus.$on('product-after-load', this.selectVariant)
  },
  mounted () {
    this.selectVariant()
    if (this.$refs.carousel) {
      let navigation = this.$refs.carousel.$children.find(c => c.$el.className === 'VueCarousel-navigation')
      let pagination = this.$refs.carousel.$children.find(c => c.$el.className === 'VueCarousel-pagination')
      if (navigation !== undefined) {
        navigation.$on('navigationclick', this.increaseCarouselTransitionSpeed)
      }
      if (pagination !== undefined) {
        pagination.$on('paginationclick', this.increaseCarouselTransitionSpeed)
      }
    }
    this.$emit('loaded')
  },
  beforeDestroy () {
    this.$bus.$off('filter-changed-product', this.selectVariant)
    this.$bus.$off('product-after-load', this.selectVariant)
  },
  methods: {
    navigate (index) {
      if (this.$refs.carousel) {
        this.$refs.carousel.goToPage(index)
      }
    },
    selectVariant () {
      if (store.state.config.products.gallery.mergeConfigurableChildren) {
        let option = this.configuration[store.state.config.products.gallery.variantsGroupAttribute]
        if (typeof option !== 'undefined' && option !== null) {
          let index = this.gallery.findIndex(obj => obj.id && Number(obj.id) === Number(option.id))
          this.navigate(index)
        }
      }
    },
    openOverlay () {
      const currentSlide = this.$refs.carousel.currentPage
      this.$emit('toggle', currentSlide)
    },
    increaseCarouselTransitionSpeed () {
      this.carouselTransitionSpeed = 500
    },
    pageChange (index) {
      this.currentPage = index
      this.hideImageAtIndex = null
    },
    onVideoStarted (index) {
      this.hideImageAtIndex = index
    },
    lowerQualityImageLoaded (index) {
      this.$set(this.lowerQualityImagesLoadedMap, index, true)
    },
    highQualityImageLoaded (index) {
      this.$set(this.highQualityImagesLoadedMap, index, true)
    }
  }
}
</script>

<style lang="scss" scoped>
.media-gallery-carousel {
  position: relative;
  text-align: center;
  height: 100%;
}
.zoom-in {
  position: absolute;
  bottom: 0;
  right: 0;
}
.product-image-container {
  display: flex;
  flex-direction: column;
  flex-grow: 1;
  justify-content: center;
  align-items: center;<commit_msg>fix image load after comming back to online<commit_after><template>
  <div class="media-gallery-carousel">
    <carousel
      :per-page="1"
      :mouse-drag="false"
      :navigation-enabled="true"
      pagination-active-color="#828282"
      pagination-color="transparent"
      navigation-next-label="<i class='material-icons p15 cl-bg-tertiary pointer'>keyboard_arrow_right</i>"
      navigation-prev-label="<i class='material-icons p15 cl-bg-tertiary pointer'>keyboard_arrow_left</i>"
      ref="carousel"
      :speed="carouselTransitionSpeed"
      @pageChange="pageChange"
    >
      <slide
        v-for="(images, index) in gallery"
        :key="images.src">
        <div class="product-image-container bg-cl-secondary" :class="{'video-container w-100 h-100 flex relative': images.video}">
          <img
            v-show="placeholderImagesMap[index]"
            key="placeholderImage"
            class="inline-flex mw-100"
            src="/assets/placeholder.svg"
            ref="images"
            :alt="productName | htmlDecode"
          >
          <img
            v-if="!lowerQualityImagesErrorsMap[index] || isOnline"
            v-show="lowerQualityImagesMap[index]"
            key="lowQualityImage"
            class="product-image inline-flex mw-100"
            :src="images.loading"
            @load="lowerQualityImageLoaded(index, true)"
            @error="lowerQualityImageLoaded(index, false)"
            ref="images"
            :alt="productName | htmlDecode"
            data-testid="productGalleryImage"
            itemprop="image"
          >
          <img
            v-if="!highQualityImagesErrorsMap[index] || isOnline"
            v-show="highQualityImagesLoadedMap[index]"
            key="highQualityImage"
            :src="images.src"
            @load="highQualityImageLoaded(index, true)"
            @error="highQualityImageLoaded(index, false)"
            class="product-image inline-flex pointer mw-100"
            ref="images"
            @dblclick="openOverlay"
            :alt="productName | htmlDecode"
            data-testid="productGalleryImage"
            itemprop="image"
          >
          <product-video
            v-if="images.video && (index === currentPage)"
            v-bind="images.video"
            :index="index"
            @video-started="onVideoStarted"/>
        </div>
      </slide>
    </carousel>
    <i
      class="zoom-in material-icons p15 cl-bgs-tertiary pointer"
      @click="openOverlay"
    >zoom_in</i>
  </div>
</template>

<script>
import store from '@vue-storefront/core/store'
import { Carousel, Slide } from 'vue-carousel'
import ProductVideo from './ProductVideo'
import { onlineHelper } from '@vue-storefront/core/helpers'

export default {
  name: 'ProductGalleryCarousel',
  components: {
    Carousel,
    Slide,
    ProductVideo
  },
  props: {
    gallery: {
      type: Array,
      required: true
    },
    productName: {
      type: String,
      required: true
    },
    configuration: {
      type: Object,
      required: true
    }
  },
  data () {
    return {
      carouselTransitionSpeed: 0,
      currentPage: 0,
      hideImageAtIndex: null,
      lowerQualityImagesLoadedMap: {},
      highQualityImagesLoadedMap: {},
      lowerQualityImagesErrorsMap: {},
      highQualityImagesErrorsMap: {}
    }
  },
  computed: {
    placeholderImagesMap () {
      let visibilityMap = {}
      this.gallery.forEach((image, index) => {
        visibilityMap[index] = !this.lowerQualityImagesLoadedMap[index] && !this.highQualityImagesLoadedMap[index]
      })
      return visibilityMap
    },
    lowerQualityImagesMap () {
      let visibilityMap = {}
      this.gallery.forEach((image, index) => {
        visibilityMap[index] = !!this.lowerQualityImagesLoadedMap[index] && !this.highQualityImagesLoadedMap[index] && this.hideImageAtIndex !== index
      })
      return visibilityMap
    },
    highQualityImagesMap () {
      let visibilityMap = {}
      this.gallery.forEach((image, index) => {
        visibilityMap[index] = !!this.highQualityImagesLoadedMap[index] && this.hideImageAtIndex !== index
      })
      return visibilityMap
    },
    isOnline () {
      return onlineHelper.isOnline
    }
  },
  beforeMount () {
    this.$bus.$on('filter-changed-product', this.selectVariant)
    this.$bus.$on('product-after-load', this.selectVariant)
  },
  mounted () {
    this.selectVariant()
    if (this.$refs.carousel) {
      let navigation = this.$refs.carousel.$children.find(c => c.$el.className === 'VueCarousel-navigation')
      let pagination = this.$refs.carousel.$children.find(c => c.$el.className === 'VueCarousel-pagination')
      if (navigation !== undefined) {
        navigation.$on('navigationclick', this.increaseCarouselTransitionSpeed)
      }
      if (pagination !== undefined) {
        pagination.$on('paginationclick', this.increaseCarouselTransitionSpeed)
      }
    }
    this.$emit('loaded')
  },
  beforeDestroy () {
    this.$bus.$off('filter-changed-product', this.selectVariant)
    this.$bus.$off('product-after-load', this.selectVariant)
  },
  methods: {
    navigate (index) {
      if (this.$refs.carousel) {
        this.$refs.carousel.goToPage(index)
      }
    },
    selectVariant () {
      if (store.state.config.products.gallery.mergeConfigurableChildren) {
        let option = this.configuration[store.state.config.products.gallery.variantsGroupAttribute]
        if (typeof option !== 'undefined' && option !== null) {
          let index = this.gallery.findIndex(obj => obj.id && Number(obj.id) === Number(option.id))
          this.navigate(index)
        }
      }
    },
    openOverlay () {
      const currentSlide = this.$refs.carousel.currentPage
      this.$emit('toggle', currentSlide)
    },
    increaseCarouselTransitionSpeed () {
      this.carouselTransitionSpeed = 500
    },
    pageChange (index) {
      this.currentPage = index
      this.hideImageAtIndex = null
    },
    onVideoStarted (index) {
      this.hideImageAtIndex = index
    },
    lowerQualityImageLoaded (index, success = true) {
      this.$set(this.lowerQualityImagesLoadedMap, index, success)
      this.$set(this.lowerQualityImagesErrorsMap, index, !success)
    },
    highQualityImageLoaded (index, success = true) {
      this.$set(this.highQualityImagesLoadedMap, index, success)
      this.$set(this.highQualityImagesErrorsMap, index, !success)
    }
  }
}
</script>

<style lang="scss" scoped>
.media-gallery-carousel {
  position: relative;
  text-align: center;
  height: 100%;
}
.zoom-in {
  position: absolute;
  bottom: 0;
  right: 0;
}
.product-image-container {
  display: flex;
  flex-direction: column;
  flex-grow: 1;
  justify-content: center;
  align-items: center;
{'fraction_non_alphanumeric': 0.13359253499222395, 'fraction_numerical': 0.006065318818040436, 'mean_word_length': 2.590452261306533, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 61, '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': '5105950', 'n_tokens_mistral': 3897, 'n_tokens_neox': 3756, 'n_words': 623}