-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f84980e
commit a8b656c
Showing
24 changed files
with
891 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
74 changes: 74 additions & 0 deletions
74
src/services/banner-manager/ui/banner-container/banner-container.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} | ||
} | ||
|
38 changes: 38 additions & 0 deletions
38
src/services/banner-manager/ui/banner-container/banner-container.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
22
src/services/banner-manager/ui/banner-container/close-large.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
13
src/services/banner-manager/ui/banner-container/close-small.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} | ||
} | ||
} | ||
|
Oops, something went wrong.