403Webshell
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/cvetdv.ru/bitrix/js/im/v2/component/call-background/src/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/cvetdv.ru/bitrix/js/im/v2/component/call-background/src/call-background.js
import 'ui.vue3';
import 'ui.buttons';
import 'ui.fonts.opensans';

import {BaseEvent} from 'main.core.events';
import { DesktopApi } from 'im.v2.lib.desktop-api';

import {Utils} from 'im.v2.lib.utils';
import {Logger} from 'im.v2.lib.logger';

import {BackgroundComponent} from './components/background';
import {ActionComponent} from './components/action';
import {MaskComponent} from './components/mask';
import {Loader} from './components/loader';
import {TabPanel} from './components/tab-panel';
import {VideoPreview} from './components/video-preview';

import {Action} from './classes/items/action';
import {Background} from './classes/items/background';
import {Mask} from './classes/items/mask';
import {BackgroundService} from './classes/background-service';
import {UploadManager} from './classes/upload-manager';
import {LimitManager} from './classes/limit-manager';
import {TabId, MASK_HELP_ARTICLE_CODE} from './const';

import './css/call-background.css';
import './css/call-background-dark.css';

import type {ElementListRestResult, BackgroundListRestResult, BackgroundRestResult, MaskListRestResult, MaskRestResult} from './types/rest';

// @vue/component
export const CallBackground = {
	name: 'CallBackground',
	components: {BackgroundComponent, ActionComponent, MaskComponent, Loader, TabPanel, VideoPreview},
	props: {
		tab: {
			type: String,
			default: TabId.background,
		}
	},
	data()
	{
		return {
			selectedTab: '',
			selectedBackgroundId: '',
			selectedMaskId: '',
			loadingItems: true,
			actions: [],
			defaultBackgrounds: [],
			customBackgrounds: [],
			masks: [],
			listIsScrolled: false
		};
	},
	computed:
	{
		TabId: () => TabId,
		backgrounds(): Background[]
		{
			return [...this.customBackgrounds, ...this.defaultBackgrounds];
		},
		containerClasses(): string[]
		{
			const classes = [];

			if (this.isDesktop)
			{
				classes.push('--desktop');
			}

			return classes;
		},
		uploadTypes(): string
		{
			return UploadManager.allowedFileTypes.join(', ');
		},
		descriptionText(): string
		{
			const replaces = {
				'#HIGHLIGHT_START#': '<span class="bx-im-call-background__description_highlight">',
				'#HIGHLIGHT_END#': '</span>',
				'#BR#': '</br></br>'
			};
			if (this.selectedTab === TabId.mask)
			{
				return this.loc('BX_IM_CALL_BG_DESCRIPTION_MASK_2', replaces);
			}

			return this.loc('BX_IM_CALL_BG_DESCRIPTION_BG', replaces);
		},
		isDesktop()
		{
			return Utils.platform.isBitrixDesktop();
		}
	},
	created()
	{
		this.initSelectedTab();

		this.getBackgroundService().getElementsList().then((result: ElementListRestResult) => {
			const {backgroundResult, maskResult} = result;

			this.initLimitManager(backgroundResult);
			this.initBackgroundList(backgroundResult);

			this.uploadManager.setDiskFolderId(backgroundResult.upload.folderId);
			const uploadActionIsAvailable = !!backgroundResult.upload.folderId;
			this.initActions(uploadActionIsAvailable);

			this.initMasks(maskResult);
			this.initMaskLoadEventHandler();

			this.initPreviouslySelectedItem();
			this.loadingItems = false;

			this.hideLoader();
		}).catch(() => {
			this.loadingItems = false;
		});
	},
	mounted()
	{
		this.initUploader();
	},
	methods:
	{
		// region init
		initSelectedTab()
		{
			if (this.tab === TabId.mask && !LimitManager.isMaskFeatureAvailable())
			{
				this.selectedTab = TabId.background;
				return;
			}

			if (this.tab === TabId.mask && !LimitManager.isMaskFeatureSupportedByDesktopVersion())
			{
				this.selectedTab = TabId.background;
				LimitManager.showHelpArticle(MASK_HELP_ARTICLE_CODE);
				return;
			}

			this.selectedTab = this.tab;
		},
		initPreviouslySelectedItem()
		{
			this.initPreviouslySelectedMask();
			this.initPreviouslySelectedBackground();
		},
		initPreviouslySelectedMask()
		{
			if (this.isDesktop)
			{
				const {id: maskId} = DesktopApi.getCallMask();
				let foundMask = this.masks.find(mask => mask.id === maskId);
				if (!foundMask)
				{
					foundMask = Mask.createEmpty();
				}
				this.previouslySelectedMask = foundMask;
				Logger.warn('CallBackground: previously selected mask', this.previouslySelectedMask);
			}
			else
			{
				this.previouslySelectedMask = Mask.createEmpty();
			}

			this.selectedMaskId = this.previouslySelectedMask.id;
		},
		initPreviouslySelectedBackground()
		{
			if (this.isDesktop)
			{
				const {id: backgroundId} = DesktopApi.getBackgroundImage();
				const itemsToSearch = [...this.actions, ...this.backgrounds];
				let foundBackground = itemsToSearch.find(item => item.id === backgroundId);
				if (!foundBackground)
				{
					foundBackground = new Action(Action.type.none);
				}
				this.previouslySelectedBackground = foundBackground;
				Logger.warn('CallBackground: previously selected background', this.previouslySelectedBackground);
			}
			else
			{
				this.previouslySelectedBackground = new Action(Action.type.none);
			}

			this.selectedBackgroundId = this.previouslySelectedBackground.id;
		},
		initActions(uploadActionIsAvailable: boolean)
		{
			this.actions = [
				new Action(Action.type.none),
				...uploadActionIsAvailable ? [new Action(Action.type.upload)]: [],
				new Action(Action.type.gaussianBlur),
				new Action(Action.type.blur),
			];
		},
		initBackgroundList(restResult: BackgroundListRestResult)
		{
			this.defaultBackgrounds = [];
			restResult.backgrounds.default.forEach((background: BackgroundRestResult) => {
				this.defaultBackgrounds.push(Background.createDefaultFromRest(background));
			});

			this.customBackgrounds = [];
			restResult.backgrounds.custom.forEach((background: BackgroundRestResult) => {
				this.customBackgrounds.push(Background.createCustomFromRest(background));
			});
		},
		initLimitManager(result: BackgroundListRestResult)
		{
			const {limits, infoHelperParams} = result;
			this.limitManager = new LimitManager({
				limits,
				infoHelperUrlTemplate: infoHelperParams.frameUrlTemplate
			});
		},
		initUploader()
		{
			this.uploadManager = new UploadManager({
				inputNode: this.$refs['uploadInput']
			});

			this.uploadManager.subscribe(UploadManager.event.uploadStart, (event: BaseEvent) => {
				const backgroundsInstance = Background.createCustomFromUploaderEvent(event.getData());
				this.customBackgrounds.unshift(backgroundsInstance);
			});
			this.uploadManager.subscribe(UploadManager.event.uploadProgress, (event: BaseEvent) => {
				const {id, progress} = event.getData();
				const background = this.findCustomBackgroundById(id);
				if (!background)
				{
					return;
				}
				background.setUploadProgress(progress);
			});
			this.uploadManager.subscribe(UploadManager.event.uploadComplete, (event: BaseEvent) => {
				const {id, fileResult} = event.getData();
				const background = this.findCustomBackgroundById(id);
				if (!background)
				{
					return;
				}
				background.onUploadComplete(fileResult);

				this.onBackgroundClick(background);

				this.getBackgroundService().commitBackground(background.id);
			});
			this.uploadManager.subscribe(UploadManager.event.uploadError, (event: BaseEvent) => {
				const {id} = event.getData();
				const background = this.findCustomBackgroundById(id);
				if (!background)
				{
					return;
				}
				background.setUploadError();
			});
		},
		initMasks(result: MaskListRestResult)
		{
			const {masks} = result;
			this.masks.push(Mask.createEmpty());
			masks.forEach((mask: MaskRestResult) => {
				this.masks.push(Mask.createFromRest(mask));
			});
		},
		initMaskLoadEventHandler()
		{
			if (!this.isDesktop)
			{
				return;
			}
			this.maskLoadTimeouts = {};
			DesktopApi.setCallMaskLoadHandlers(this.onMaskLoad.bind(this));
		},
		// endregion init
		// region component events
		onActionClick(action: Action)
		{
			if (this.getLimitManager().isLimitedAction(action))
			{
				this.getLimitManager().showLimitSlider(LimitManager.limitCode.blur);
				return;
			}

			if (action.isUpload())
			{
				this.$refs['uploadInput'].click();
				return;
			}

			this.selectedBackgroundId = action.id;

			if (action.isEmpty())
			{
				this.removeCallBackground();
				return;
			}

			this.selectedMaskId = '';
			this.setCallBlur(action);
		},
		onBackgroundClick(background: Background)
		{
			if (this.getLimitManager().isLimitedBackground())
			{
				this.getLimitManager().showLimitSlider(LimitManager.limitCode.image);
				return;
			}

			if (!background.isSupported || background.isLoading)
			{
				return;
			}

			this.selectedBackgroundId = background.id;
			this.selectedMaskId = '';
			this.setCallBackground(background);
		},
		onBackgroundRemove(background: Background)
		{
			if (background.id === this.selectedBackgroundId)
			{
				this.selectedBackgroundId = Action.type.none;
				this.removeCallBackground();
			}

			if (background.isLoading)
			{
				this.uploadManager.cancelUpload(background.id);
			}
			else
			{
				this.getBackgroundService().deleteFile(background.id);
			}

			this.customBackgrounds = this.customBackgrounds.filter(element => element.id !== background.id);
		},
		onMaskClick(mask: Mask)
		{
			if (!mask.active)
			{
				return;
			}

			if (mask.isEmpty())
			{
				this.selectedMaskId = mask.id;
				this.removeCallMask();
			}

			this.setCallMask(mask);
		},
		onSaveButtonClick()
		{
			window.close();
		},
		onCancelButtonClick()
		{
			const backgroundWasChanged = this.previouslySelectedBackground.id !== this.selectedBackgroundId;
			const maskWasChanged = this.previouslySelectedMask.id !== this.selectedMaskId;
			if (!backgroundWasChanged && !maskWasChanged)
			{
				window.close();
				return;
			}

			let backgroundPromise = Promise.resolve();
			if (backgroundWasChanged)
			{
				backgroundPromise = this.setCallBackground(this.previouslySelectedBackground);
			}

			backgroundPromise.then(() => {
				if (maskWasChanged && !this.previouslySelectedMask.isEmpty())
				{
					this.setCallMask(this.previouslySelectedMask);
					this.isWaitingForMaskToCancel = true;
				}
				else if (this.previouslySelectedMask.isEmpty())
				{
					this.removeCallMask();
					window.close();
				}
				else
				{
					window.close();
				}
			});
		},
		onListScroll(event: Event)
		{
			if (event.target.scrollTop === 0)
			{
				this.listIsScrolled = false;
				return;
			}

			this.listIsScrolled = true;
		},
		onTabChange(newTabId: string)
		{
			if (newTabId === TabId.mask && !LimitManager.isMaskFeatureSupportedByDesktopVersion())
			{
				LimitManager.showHelpArticle(MASK_HELP_ARTICLE_CODE);
				return;
			}

			this.selectedTab = newTabId;
		},
		onMaskLoad(url: string)
		{
			Logger.warn('CallBackground: onMaskLoad', url);
			if (this.isWaitingForMaskToCancel)
			{
				window.close();
				return;
			}

			const masksWithoutEmpty = this.masks.filter((mask: Mask) => !mask.isEmpty());
			const loadedMask = masksWithoutEmpty.find((mask: Mask) => url.includes(mask.mask));
			Logger.warn('CallBackground: loaded mask', loadedMask);
			if (!loadedMask)
			{
				return;
			}

			clearTimeout(this.maskLoadTimeouts[loadedMask.id]);
			loadedMask.isLoading = false;
			if (this.lastRequestedMaskId === loadedMask.id)
			{
				this.selectedMaskId = loadedMask.id;
			}
		},
		// endregion component events
		// region desktop interactions
		onSetCallBackgroundHandle(id, source)
		{
			return DesktopApi.setCallBackground(id, source)
				.then((id) =>
					{
						if (id === 'none' && this.selectedBackgroundId !== 'none')
						{
							Logger.warn('CallBackground: background settings limit exceeded');
							this.selectedBackgroundId = Action.type.none;
						}
					}
				);
		},
		setCallBackground(backgroundInstance: Background): Promise
		{
			Logger.warn('CallBackground: trying set background', backgroundInstance);
			if (!this.isDesktop)
			{
				return;
			}

			return this.onSetCallBackgroundHandle(backgroundInstance.id, backgroundInstance.background);
		},
		setCallBlur(action: Action): Promise
		{
			Logger.warn('CallBackground: trying set blur', action);
			if (!this.isDesktop)
			{
				return;
			}

			return this.onSetCallBackgroundHandle(action.id, action.background);
		},
		removeCallBackground(): Promise
		{
			if (!this.isDesktop)
			{
				return;
			}

			return this.onSetCallBackgroundHandle(Action.type.none, Action.type.none);
		},
		setCallMask(mask: Mask)
		{
			Logger.warn('CallBackground: set mask', mask);
			if (!this.isDesktop)
			{
				return;
			}

			if (mask.isEmpty())
			{
				Logger.warn('CallBackground: empty mask - removing it');
				DesktopApi.setCallMask();
				return;
			}

			this.lastRequestedMaskId = mask.id;

			const MASK_LOAD_STATUS_DELAY = 500;
			this.maskLoadTimeouts[mask.id] = setTimeout(() => {
				mask.isLoading = true;
			}, MASK_LOAD_STATUS_DELAY);
			DesktopApi.setCallMask(mask.id, mask.mask, mask.background);
		},
		removeCallMask()
		{
			if (!this.isDesktop)
			{
				return;
			}

			DesktopApi.setCallMask();
		},
		hideLoader()
		{
			if (!this.isDesktop)
			{
				return;
			}

			DesktopApi.hideLoader();
		},
		// endregion desktop interactions
		findCustomBackgroundById(id: string): ?Background
		{
			return this.customBackgrounds.find(element => element.id === id);
		},
		getBackgroundService(): BackgroundService
		{
			if (!this.backgroundService)
			{
				this.backgroundService = new BackgroundService();
			}

			return this.backgroundService;
		},
		getLimitManager(): LimitManager
		{
			return this.limitManager;
		},
		loc(phraseCode: string, replacements: {[p: string]: string} = {}): string
		{
			return this.$Bitrix.Loc.getMessage(phraseCode, replacements);
		}
	},
	template:
	`
		<div :class="{'--desktop': isDesktop}" class="bx-im-call-background__scope bx-im-call-background__container">
			<div v-if="loadingItems" class="bx-im-call-background__loader_container">
				<Loader />
			</div>
			<div v-else class="bx-im-call-background__content">
				<div class="bx-im-call-background__left">
					<VideoPreview />
					<div v-html="descriptionText" class="bx-im-call-background__description"></div>
				</div>
				<div :class="{'--scrolled': listIsScrolled}" class="bx-im-call-background__right">
					<TabPanel :selectedTab="selectedTab" @tabChange="onTabChange" />
					<div v-if="selectedTab === TabId.background" @scroll="onListScroll" class="bx-im-call-background__list">
						<ActionComponent
							v-for="action in actions"
							:element="action"
							:key="action.id"
							:isSelected="selectedBackgroundId === action.id"
							@click="onActionClick(action)"
						/>
						<BackgroundComponent
							v-for="background in backgrounds"
							:element="background"
							:key="background.id"
							:isSelected="selectedBackgroundId === background.id"
							@click="onBackgroundClick(background)"
							@cancel="onBackgroundRemove(background)"
							@remove="onBackgroundRemove(background)"
						/>
					</div>
					<div v-else-if="selectedTab === TabId.mask" @scroll="onListScroll" class="bx-im-call-background__list">
						<MaskComponent
							v-for="mask in masks"
							:element="mask"
							:key="mask.id"
							:isSelected="selectedMaskId === mask.id"
							@click="onMaskClick(mask)"
						/>
					</div>
				</div>	
			</div>
			<div class="bx-im-call-background__button-panel">
				<button @click="onSaveButtonClick" :class="{'ui-btn-wait ui-btn-disabled': loadingItems}" class="ui-btn ui-btn-success">
					{{ loc('BX_IM_CALL_BG_SAVE') }}
				</button>
				<button @click="onCancelButtonClick" class="ui-btn ui-btn-link">
					{{ loc('BX_IM_CALL_BG_CANCEL') }}
				</button>
			</div>
		</div>
		<div class="bx-im-call-background__upload-input">
			<input type="file" :accept="uploadTypes" ref="uploadInput"/>
		</div>
	`
};

Youez - 2016 - github.com/yon3zu
LinuXploit