Your IP : 3.144.93.79


Current Path : /var/www/www-root/data/www/monolith-realty.ru/bitrix/js/ui/vue/components/reaction/src/
Upload File :
Current File : /var/www/www-root/data/www/monolith-realty.ru/bitrix/js/ui/vue/components/reaction/src/reaction.js

/**
 * Bitrix UI
 * Reaction picker Vue component
 *
 * @package bitrix
 * @subpackage ui
 * @copyright 2001-2019 Bitrix
 */

import 'ui.fonts.opensans';
import "./reaction.css";
import "./icons.css";

import {BitrixVue} from 'ui.vue';
import { BaseEvent, EventEmitter } from 'main.core.events';

const ReactionType = Object.freeze({
	none: 'none',
	like: 'like',
	kiss: 'kiss',
	laugh: 'laugh',
	wonder: 'wonder',
	cry: 'cry',
	angry: 'angry',
});

const ReactionOrder = ['like', 'kiss', 'laugh', 'wonder', 'cry', 'angry'];

BitrixVue.component('bx-reaction',
{
	/**
	 * @emits 'set' {values: object}
	 * @emits 'list' {action: string, type: string}
	 */
	props:
	{
		id: { default: ''},
		values: { default: {}},
		userId: { default: 0},
		openList: { default: true},
	},
	data()
	{
		return {
			localValues: {},
			userReaction: ReactionType.none,
			buttonAnimate: false,
		}
	},
	created()
	{
		this.localValues = Object.assign({}, this.values);
		EventEmitter.subscribe('ui:reaction:press', this.onPress);
	},
	destroy()
	{
		EventEmitter.unsubscribe('ui:reaction:press', this.onPress);
	},
	watch:
	{
		values(values)
		{
			this.localValues = Object.assign({}, values);
		},
	},
	methods:
	{
		list()
		{
			if (this.openList)
			{
				// todo open list
			}
			this.$emit('list', {values: this.localValues});
		},

		press(emotion = ReactionType.like)
		{
			if (this.userReaction === ReactionType.none)
			{
				if (!this.localValues[emotion])
				{
					this.localValues = Object.assign({}, this.localValues, {[emotion]: []});
				}

				this.localValues[emotion].push(this.userId);

				this.buttonAnimate = true;
				setTimeout(() => this.buttonAnimate = false, 400);

				this.$emit('set', {action: 'set', type: emotion});
			}
			else
			{

				if (this.localValues[this.userReaction])
				{
					this.localValues[this.userReaction] = this.localValues[this.userReaction].filter(element => element !== this.userId);
				}

				this.$emit('set', {action: 'remove', type: this.userReaction});
			}
		},

		onPress(event: BaseEvent)
		{
			const data = event.getData();
			if (!this.id || data.id !== this.id)
			{
				return false;
			}

			if (!data.emotion)
			{
				data.emotion = ReactionType.like
			}

			this.press(data.emotion);
		}
	},
	computed:
	{
		types()
		{
			this.userReaction = ReactionType.none;

			return ReactionOrder.filter(type =>
			{
				if (
					typeof this.localValues[type] === 'undefined'
					|| !(this.localValues[type] instanceof Array)
					|| this.localValues[type].length <= 0
				)
				{
					return false;
				}

				if (
					this.userId > 0
					&& this.userReaction === ReactionType.none
					&& this.localValues[type].includes(this.userId)
				)
				{
					this.userReaction = type;
				}

				return true;

			}).map(type => {
				return {type, count: this.localValues[type].length}
			});
		},

		counter()
		{
			return this.types.map(element => element.count).reduce((result, value) => result + value, 0);
		},

		isTypesShowed()
		{
			if (this.counter <= 0)
			{
				return false;
			}

			if (this.userReaction !== ReactionType.none && this.counter === 1)
			{
				return false;
			}

			return true;
		},

		isMobile()
		{
			const UA = navigator.userAgent.toLowerCase();

			return (
				UA.includes('android')
				|| UA.includes('iphone')
				|| UA.includes('ipad')
				|| UA.includes('bitrixmobile')
			)
		},
	},
	template: `
		<div :class="['ui-vue-reaction', {'ui-vue-reaction-mobile': isMobile}]">
			<transition name="ui-vue-reaction-result-animation">
				<div v-if="isTypesShowed" class="ui-vue-reaction-result" @click="list">
					<transition-group tag="div" class="ui-vue-reaction-result-types" name="ui-vue-reaction-result-type-animation" >
						<span v-for="element in types" :class="['ui-vue-reaction-result-type', 'ui-vue-reaction-icon-'+element.type]" :key="element.type"></span>
					</transition-group>	
					<div class="ui-vue-reaction-result-counter">{{counter}}</div>
				</div>
			</transition>
			<div v-if="userId > 0"  class="ui-vue-reaction-button" @click.prevent="press()">
				<div class="ui-vue-reaction-button-container">
					<div :class="['ui-vue-reaction-button-icon', 'ui-vue-reaction-icon-'+userReaction, {'ui-vue-reaction-button-pressed': buttonAnimate}]"></div>
				</div>
			</div>
		</div>
	`
});