Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/rospirotorg.ru/bitrix/js/ui/vue/components/socialvideo/src/ |
Upload File : |
/** * Bitrix UI * Social Video Vue component * * @package bitrix * @subpackage ui * @copyright 2001-2021 Bitrix */ import 'ui.fonts.opensans'; import "./socialvideo.css"; import 'ui.vue.directives.lazyload'; import 'main.polyfill.intersectionobserver'; import {BitrixVue} from 'ui.vue'; import {BaseEvent} from "main.core.events"; const State = Object.freeze({ play: 'play', pause: 'pause', stop: 'stop', none: 'none', }); BitrixVue.component('bx-socialvideo', { props: { id: { default: 0 }, src: { default: '' }, preview: { default: '' }, autoplay: { default: true }, containerClass: { default: null }, containerStyle: { default: null }, elementStyle: { default: null }, showControls: { default: true } }, data() { return { preload: "none", previewLoaded: false, loaded: false, loading: false, playAfterLoad: false, enterFullscreen: false, playBeforeMute: 2, state: State.none, progress: 0, timeCurrent: 0, timeTotal: 0, muteFlag: true, } }, created() { if (!this.preview) { this.previewLoaded = true; this.preload = 'metadata'; } this.$Bitrix.eventEmitter.subscribe('ui:socialvideo:unmute', this.onUnmute); }, mounted() { this.getObserver().observe(this.$refs.body); }, beforeDestroy() { this.$Bitrix.eventEmitter.unsubscribe('ui:socialvideo:unmute', this.onUnmute); this.getObserver().unobserve(this.$refs.body); }, watch: { id(value) { this.registeredId = value; }, }, methods: { loadFile(play = false) { if (this.loaded) { return true; } if (this.loading) { return true; } this.preload = 'auto'; this.loading = true; this.playAfterLoad = play; return true; }, clickToButton(event) { if (!this.src) { return false; } if (this.state === State.play) { this.getObserver().unobserve(this.$refs.body); this.pause(); } else { this.play(); } event.stopPropagation(); }, clickToMute() { if (!this.src) { return false; } if (!this.muteFlag) { this.mute(); } else { this.unmute(); } event.stopPropagation(); }, click(event) { if (this.autoPlayDisabled) { this.play(); event.stopPropagation(); return false; } if (this.isMobile) { if (this.source().webkitEnterFullscreen) { this.unmute(); this.enterFullscreen = true; this.source().webkitEnterFullscreen(); } else if (this.source().requestFullscreen) { this.unmute(); this.enterFullscreen = true; this.source().requestFullscreen(); } else { this.$emit('click', event); } } else { this.$emit('click', event); } event.stopPropagation(); }, play(event) { if (!this.loaded) { this.loadFile(true); return false; } if (!this.source()) { return false; } this.source().play(); }, pause() { if (!this.source()) { return false; } this.playAfterLoad = false; this.source().pause(); }, stop() { if (!this.source()) { return false; } this.state = State.stop; this.source().pause(); }, mute() { if (!this.source()) { return false; } this.muteFlag = true; this.playBeforeMute = 2; this.source().muted = true; }, unmute() { if (!this.source()) { return false; } this.muteFlag = false; this.source().muted = false; if (this.id > 0) { this.$Bitrix.eventEmitter.emit('ui:socialvideo:unmute', {initiator: this.id}); } }, setProgress(percent, pixel = -1) { this.progress = percent; }, formatTime(second) { second = Math.floor(second); const hour = Math.floor(second/60/60); if (hour > 0) { second -= hour*60*60; } const minute = Math.floor(second/60); if (minute > 0) { second -= minute*60; } return (hour > 0? hour+':': '') + (hour > 0? minute.toString().padStart(2, "0")+':': minute+':') + second.toString().padStart(2, "0") }, onUnmute(event: BaseEvent) { event = event.getData(); if (event.initiator === this.id) { return false; } this.mute(); }, source() { return this.$refs.source; }, videoEventRouter(eventName, event) { if ( eventName === 'durationchange' || eventName === 'loadeddata' ) { if (!this.source()) { return false; } this.timeTotal = this.source().duration; } else if (eventName === 'loadedmetadata') { if (!this.source()) { return false; } this.timeTotal = this.source().duration; this.loaded = true; if (this.playAfterLoad) { this.play(); } } else if ( eventName === 'abort' || eventName === 'error' ) { console.error('BxSocialVideo: load failed', this.id, event); this.loading = false; this.state = State.none; this.timeTotal = 0; this.preload = 'none'; } else if ( eventName === 'canplaythrough' ) { this.loading = false; this.loaded = true; if (this.playAfterLoad) { this.play(); } } else if (eventName === 'volumechange') { if (!this.source()) { return false; } if (this.source().muted) { this.mute(); } else { this.unmute(); } } else if (eventName === 'timeupdate') { if (!this.source()) { return false; } this.timeCurrent = this.source().currentTime; if (!this.muteFlag && !this.enterFullscreen && this.timeCurrent === 0) { if (this.playBeforeMute <= 0) { this.mute(); } this.playBeforeMute -= 1; } this.setProgress(Math.round(100/this.timeTotal*this.timeCurrent)); } else if (eventName === 'pause') { if (this.state !== State.stop) { this.state = State.pause; } if (this.enterFullscreen) { this.enterFullscreen = false; this.mute(); this.play(); } } else if (eventName === 'play') { this.state = State.play; if (this.state === State.stop) { this.progress = 0; this.timeCurrent = 0; } if (this.enterFullscreen) { this.enterFullscreen = false; } } }, getObserver() { if (this.observer) { return this.observer; } this.observer = new IntersectionObserver((entries, observer) => { if (this.autoPlayDisabled) { return false; } entries.forEach((entry) => { if (entry.isIntersecting) { this.play(); } else { this.pause(); } }); },{ threshold: [0, 1] }); return this.observer; }, lazyLoadCallback(element) { this.previewLoaded = element.state === 'success'; } }, computed: { State: () => State, autoPlayDisabled() { return !this.autoplay && this.state === State.none; }, showStartButton() { return this.autoPlayDisabled && this.previewLoaded; }, showInterface() { return this.previewLoaded && !this.showStartButton; }, labelTime() { if (!this.loaded && !this.timeTotal) { return '--:--'; } let time; if (this.state === State.play) { time = this.timeTotal - this.timeCurrent; } else { time = this.timeTotal; } return this.formatTime(time); }, isMobile() { const UA = navigator.userAgent.toLowerCase(); return ( UA.includes('android') || UA.includes('iphone') || UA.includes('ipad') || UA.includes('bitrixmobile') ) }, }, template: ` <div :class="['ui-vue-socialvideo', containerClass, { 'ui-vue-socialvideo-mobile': isMobile, }]" :style="containerStyle" @click="click"> <transition name="ui-vue-socialvideo-animation-fade"> <div v-if="showStartButton && showControls" class="ui-vue-socialvideo-button-start"> <span class="ui-vue-socialvideo-button-start-icon"></span> </div> </transition> <transition name="ui-vue-socialvideo-animation-fade"> <div v-if="showInterface && showControls" class="ui-vue-socialvideo-overlay-container"> <div class="ui-vue-socialvideo-controls-container" @click="clickToButton"> <button :class="['ui-vue-socialvideo-control', { 'ui-vue-socialvideo-control-loader': loading, 'ui-vue-socialvideo-control-play': !loading && state !== State.play, 'ui-vue-socialvideo-control-pause': !loading && state === State.play, }]"></button> </div> <div class="ui-vue-socialvideo-info-container" @click="clickToMute"> <span class="ui-vue-socialvideo-time-current">{{labelTime}}</span> <span :class="['ui-vue-socialvideo-sound', { 'ui-vue-socialvideo-sound-on': state !== State.none && !muteFlag, 'ui-vue-socialvideo-sound-off': state !== State.none && muteFlag }]"></span> </div> </div> </transition> <div v-if="!preview" class="ui-vue-socialvideo-background" :style="{position: (src? 'absolute': 'relative')}"></div> <div class="ui-vue-socialvideo-container" ref="body"> <img v-bx-lazyload="{callback: lazyLoadCallback}" data-lazyload-dont-hide v-if="preview" class="ui-vue-socialvideo-image-source" :data-lazyload-src="preview" :style="{position: (src? 'absolute': 'relative'), ...elementStyle}" /> <video v-if="src" :src="src" class="ui-vue-socialvideo-source" ref="source" :preload="preload" playsinline loop muted :style="{opacity: (loaded? 1: 0), ...elementStyle}" @abort="videoEventRouter('abort', $event)" @error="videoEventRouter('error', $event)" @suspend="videoEventRouter('suspend', $event)" @canplay="videoEventRouter('canplay', $event)" @canplaythrough="videoEventRouter('canplaythrough', $event)" @durationchange="videoEventRouter('durationchange', $event)" @loadeddata="videoEventRouter('loadeddata', $event)" @loadedmetadata="videoEventRouter('loadedmetadata', $event)" @volumechange="videoEventRouter('volumechange', $event)" @timeupdate="videoEventRouter('timeupdate', $event)" @play="videoEventRouter('play', $event)" @playing="videoEventRouter('playing', $event)" @pause="videoEventRouter('pause', $event)" ></video> </div> </div> ` });