Skip to content

Commit

Permalink
migrate managers from common
Browse files Browse the repository at this point in the history
  • Loading branch information
SivanA-Kaltura committed Nov 28, 2023
1 parent f84980e commit a8b656c
Show file tree
Hide file tree
Showing 24 changed files with 891 additions and 27 deletions.
121 changes: 121 additions & 0 deletions src/services/banner-manager/banner-manager.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { FloatingItem } from '../floating-manager/ui/floating-item';
import { FloatingManager } from '../floating-manager/floating-manager';
import { FloatingItemProps } from '../floating-manager/models/floating-item-data';
import { ComponentChild, h } from 'preact';
import { Banner } from './ui/banner';
import { BannerContainerProps, BannerContainer } from './ui/banner-container/banner-container';
import { getPlayerSize } from '@playkit-js/common/dist/ui-common/player-utils';

import { KalturaPlayer } from '@playkit-js/kaltura-player-js';
import { BannerContent } from './models/banner-content';

export interface BannerConfig {
theme: {
backgroundColor: string;
blur: string;
};
}

export interface BannerOptions {
content: BannerContent;
autoClose?: boolean;
duration?: number;
renderContent?: (content: BannerContent, floatingItemProps: FloatingItemProps) => ComponentChild;
}

export interface BannerManagerOptions {
floatingManager: FloatingManager;
kalturaPlayer: KalturaPlayer;
}

export interface BannerState {
visibilityMode: VisibilityMode;
}

export enum VisibilityMode {
VISIBLE = 'VISIBLE',
HIDDEN = 'HIDDEN'
}

const MinPlayerWidth = 480;
const DefaultDuration: number = 60 * 1000;
const MinDuration: number = 5 * 1000;

/**
* banner manager manages the display (add / remove) of a single banner in the player.
*/
export class BannerManager {
private _options: BannerManagerOptions;
private _floatingItem: FloatingItem | null = null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private _timerSubscription: any | undefined = undefined;
private _bannerConfig: BannerConfig;

constructor(private options: BannerManagerOptions) {
this._options = options;

this._bannerConfig = {
theme: {
backgroundColor: 'rgba(0, 0, 0, .7)',
blur: '10px'
}
};
}

public add(props: BannerOptions): BannerState {
if (this._floatingItem) {
this.remove();
}
this._floatingItem = this._options.floatingManager.add({
label: 'Banner',
mode: 'Immediate',
position: 'InteractiveArea',
renderContent: this._createRenderBanner(props, {
onClose: this._handleCloseEvent.bind(this),
theme: this._bannerConfig.theme
})
});
if (props.autoClose) {
this._startDurationTimer(props.duration);
}
return this._getState();
}

public remove(): void {
if (this._floatingItem) {
if (this._timerSubscription) clearTimeout(this._timerSubscription);
this._options.floatingManager.remove(this._floatingItem);
this._floatingItem = null;
}
}

public reset(): void {
this.remove();
}

private _createRenderBanner({ content, renderContent }: BannerOptions, { onClose, theme }: BannerContainerProps) {
function _renderContent(floatingItemProps: FloatingItemProps) {
return (
<BannerContainer onClose={onClose} theme={theme}>
{renderContent ? renderContent(content, floatingItemProps) : <Banner content={content} />}
</BannerContainer>
);
}
return _renderContent;
}

private _handleCloseEvent(): void {
this.remove();
}

private _startDurationTimer(displayDuration: number = DefaultDuration): void {
this._timerSubscription = setTimeout(this.remove.bind(this), Math.max(MinDuration, displayDuration));
}

private _getState(): BannerState {
const playerSize = getPlayerSize(this._options.kalturaPlayer);
return {
visibilityMode: !playerSize || playerSize.width < MinPlayerWidth ? VisibilityMode.HIDDEN : VisibilityMode.VISIBLE
};
}
}
6 changes: 6 additions & 0 deletions src/services/banner-manager/models/banner-content.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface BannerContent {
text: string;
title?: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
icon?: any;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
.bannerContainerRoot {
position: absolute;
max-width: 100%;
min-width: 270px;
padding: 0 16px 8px;
height: 88px;
bottom: 0;
left: 0;
transition: all 0.5s ease;
}

.bannerContainer {
position: relative;
width: 100%;
height: 100%;
border-radius: 4px;
transition: all 0.5s ease;
}

.closeButton {
position: absolute;
background-color: transparent;
padding: 0;
border: none;
top: 0;
right: 0;
width: 32px;
height: 32px;
padding: 0;
.small {
display: none;
}
}

.closeButton:hover,
.closeButton:active {
cursor: pointer;
}

:global {
.playkit-size-md {
:local {
.bannerContainerRoot {
height: 68px;
min-width: 230px;
}
.closeButton {
top: 8px;
right: 8px;
width: 10px;
height: 10px;
.large {
display: none;
}
.small {
display: block;
}
}
}
}
}

:global {
.playkit-size-sm,
.playkit-size-xs,
.playkit-size-ty {
:local .bannerContainerRoot {
display: none;
width: 0;
height: 0;
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Component, h } from 'preact';
import * as styles from './banner-container.scss';
import { CloseSmall } from './close-small';
import { CloseLarge } from './close-large';

export interface BannerContainerProps {
onClose: () => void;
theme: BannerTheme;
}

interface BannerTheme {
backgroundColor: string;
blur: string;
}

export class BannerContainer extends Component<BannerContainerProps> {
render(props: BannerContainerProps) {
const { backgroundColor, blur } = this.props.theme;

return (
<div className={styles.bannerContainerRoot} aria-live="polite">
<div
style={`
background-color:${backgroundColor};
backdrop-filter: blur(${blur});
`}
className={styles.bannerContainer}
>
<button className={styles.closeButton} onClick={props.onClose}>
<CloseSmall className={styles.small} />
<CloseLarge className={styles.large} />
</button>
{this.props.children}
</div>
</div>
);
}
}
22 changes: 22 additions & 0 deletions src/services/banner-manager/ui/banner-container/close-large.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { h } from 'preact';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const CloseLarge = (props: any) => (
<svg
width="32px"
height="32px"
viewBox="0 0 32 32"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
{...props}
>
<g id="Icons/32x32/Menu-Player-Close" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path
d="M17.4142136,16 L22.363961,20.9497475 C22.7544853,21.3402718 22.7544853,21.9734367 22.363961,22.363961 C21.9734367,22.7544853 21.3402718,22.7544853 20.9497475,22.363961 L16,17.4142136 L11.0502525,22.363961 C10.6597282,22.7544853 10.0265633,22.7544853 9.63603897,22.363961 C9.24551468,21.9734367 9.24551468,21.3402718 9.63603897,20.9497475 L14.5857864,16 L9.63603897,11.0502525 C9.24551468,10.6597282 9.24551468,10.0265633 9.63603897,9.63603897 C10.0265633,9.24551468 10.6597282,9.24551468 11.0502525,9.63603897 L16,14.5857864 L20.9497475,9.63603897 C21.3402718,9.24551468 21.9734367,9.24551468 22.363961,9.63603897 C22.7544853,10.0265633 22.7544853,10.6597282 22.363961,11.0502525 L17.4142136,16 Z"
id="Path"
fill="#FFFFFF"
/>
</g>
</svg>
);
13 changes: 13 additions & 0 deletions src/services/banner-manager/ui/banner-container/close-small.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { h } from 'preact';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const CloseSmall = (props: any) => (
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 10 10" {...props}>
<path
fill="#FFF"
fill-rule="evenodd"
d="M5.956 5l3.348-3.348A.674.674 0 0 0 9.3.7a.672.672 0 0 0-.952-.004L5 4.044 1.652.696A.674.674 0 0 0 .7.7a.672.672 0 0 0-.004.952L4.044 5 .696 8.348A.674.674 0 0 0 .7 9.3c.265.266.69.266.952.004L5 5.956l3.348 3.348c.262.262.689.26.952-.004a.672.672 0 0 0 .004-.952L5.956 5z"
opacity=".9"
/>
</svg>
);
112 changes: 112 additions & 0 deletions src/services/banner-manager/ui/banner/banner.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
.defaultBannerRoot {
display: flex;
max-width: 100%;
height: 100%;
transition: all 0.5s ease;
text-align: left;
}

.bannerWrapper {
padding: 18px 17px 17px 16px;
}

.iconContainer {
height: 100%;
width: 64px;
}

.iconWrapper {
position: relative;
height: 48px;
width: 48px;
background-color: rgba(255, 255, 255, 0.14);
border-radius: 50%;
transition: all 0.5s ease;
}

.iconImage {
position: absolute;
width: 32px;
height: 32px;
left: calc(50% - 16px);
top: calc(50% - 16px);
transition: all 0.5s ease;
padding: 0;
.small {
display: none;
}
}

.bannerBody {
height: 100%;
flex: 1 1 auto;
overflow: hidden;
}

.title {
opacity: 0.9;
font-size: 14px;
font-weight: normal;
font-style: normal;
font-stretch: normal;
line-height: 1;
letter-spacing: normal;
color: #ebebeb;
}

.text {
opacity: 0.9;
font-size: 24px;
font-weight: normal;
font-style: normal;
font-stretch: normal;
line-height: 1.21;
letter-spacing: normal;
color: #ffffff;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
transition: all 0.5s ease;
}

:global {
.playkit-size-md {
:local {
.bannerWrapper {
padding: 14px 16px 14px;
}
.iconContainer {
width: 44px;
}
.iconWrapper {
height: 32px;
width: 32px;
}
.iconImage {
width: 20px;
height: 20px;
left: calc(50% - 10px);
top: calc(50% - 10px);
.small {
display: block;
}
.large {
display: none;
}
}
.bannerBody {
flex: 1 1 auto;
}
.title {
font-size: 12px;
font-weight: bold;
line-height: 1.17;
}
.text {
font-size: 15px;
line-height: 1.27;
}
}
}
}

Loading

0 comments on commit a8b656c

Please sign in to comment.