Initial implementation of Flash client Toaster component.

This commit is contained in:
Ghazi Triki 2018-05-28 15:24:29 +01:00
parent 9eec0ffa89
commit 7de1159f20
17 changed files with 924 additions and 6 deletions

View File

@ -13,6 +13,7 @@
@namespace skins "org.bigbluebutton.skins.*";
@namespace phonecomponents "org.bigbluebutton.modules.phone.views.components.*";
@namespace tabBarClasses "flexlib.controls.tabBarClasses.*";
@namespace toast "org.bigbluebutton.common.toaster.message.*";
/*
//------------------------------
@ -902,8 +903,8 @@ views|LoadingBar {
}
.loadingBarLabel {
color : #8A9AA7;
fontWeight : bold;
color : #8A9AA7;
fontWeight : bold;
}
/*
@ -1579,11 +1580,11 @@ mx|ScrollBar {
borderAlphaOver : 1;
borderAlphaDown : 1;
borderAlphaDisabled : 0;
fillColorUp : #EFF5FA;
borderColorOver : #1070D7;
borderColorDown : #1070D7;
fontWeight : bold;
borderThickness : 5;
cornerRadius : 70;
@ -1733,6 +1734,48 @@ mx|TitleWindow {
upSkin : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Button_Up");
}
/*
//------------------------------
// ToastMessageRenderer
//------------------------------
*/
toast|ToastMessageRenderer {
backgroundColor : #FFFFFF;
cornerRadius : 4;
borderStyle : none;
color : #4E5A66;
fontSize : 15;
dropShadowEnabled : true;
shadowDirection : center;
shadowDistance : 0;
iconCornerRadius : 20;
iconColor : #FFFFFF;
iconBackgroundColorDefault : #4E5A66;
iconBackgroundColorInfo : #0F70D7;
iconBackgroundColorSuccess : #008081;
iconBackgroundColorError : #DF2721;
iconBackgroundColorWarning : #800080;
iconClose : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Close_Circle");
iconDefault : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Notification_Default");
iconInfo : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Notification_Info");
iconSuccess : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Notification_Success");
iconError : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Notification_Error");
iconWarning : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Notification_Warning");
}
.toasterContainer {
horizontalGap : 6;
paddingTop : 8;
paddingBottom : 16;
paddingLeft : 12;
paddingRight : 12;
verticalAlign : middle;
}
/*
//------------------------------
// ToolTip

View File

@ -25,6 +25,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
xmlns:userMap="org.bigbluebutton.modules.users.maps.*"
xmlns:apimap="org.bigbluebutton.main.api.maps.*"
xmlns:coreMap="org.bigbluebutton.core.controllers.maps.*"
xmlns:toaster="org.bigbluebutton.common.toaster.*"
xmlns:mate="http://mate.asfusion.com/"
width="100%" height="100%"
backgroundColor="white"
@ -237,6 +238,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mate:Listener type="{ShortcutEvent.FOCUS_AWAY_EVENT}" method="loseFocusFromApp" />
</fx:Declarations>
<views:MainApplicationShell id="mainShell"/>
<views:MainApplicationShell id="mainShell"/>
<toaster:Toaster id="toasterContainer" width="100%" height="100%"/>
</mx:Canvas>

View File

@ -0,0 +1,104 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.common.toaster {
import flash.media.Sound;
import flash.media.SoundTransform;
import mx.containers.Canvas;
import mx.core.UIComponent;
import org.bigbluebutton.common.toaster.container.ToastContainerBase;
import org.bigbluebutton.common.toaster.message.ToastMessageBase;
import org.bigbluebutton.common.toaster.message.ToastMessageRenderer;
import org.bigbluebutton.common.toaster.message.ToastType;
/**
* Main class that will contain multiple containers (one for each corner)
*/
public class Toaster extends Canvas {
private static var instance:Toaster = null;
[Embed(source = "./assets/notify.mp3")]
private static const NOTIFY_SOUND:Class;
public static var notifySound:Sound;
private var _toastContainerParent:UIComponent = null;
/**
* Specifies a custom parent for the toasts (not the Application)
*/
public function get toastContainerParent():UIComponent {
return _toastContainerParent;
}
public function set toastContainerParent(value:UIComponent):void {
_toastContainerParent = value;
}
private var _useLocalPosition:Boolean = false;
/**
* Tells the container wether to use a global positionning or a local one
*/
public function get useLocalPosition():Boolean {
return _useLocalPosition;
}
public function set useLocalPosition(value:Boolean):void {
_useLocalPosition = value;
}
// CONSTRUCTOR
public function Toaster() {
super();
setStyle("horizontalScrollPolicy", "off");
setStyle("verticalScrollPolicy", "off");
instance = this;
notifySound = new NOTIFY_SOUND();
}
private static var container:ToastContainerBase;
// PUBLIC STATIC METHODS
public static function toast(message:String, type:String = ToastType.DEFAULT, icon:String = null):void {
if (!container) {
// container wasn't defined in MXML, we create a basic one
container = new ToastContainerBase();
container.useLocalPosition = instance.useLocalPosition;
instance.addChild(container);
}
var toast:ToastMessageRenderer = new ToastMessageRenderer();
toast.message = message;
toast.type = type;
toast.iconName = icon;
container.addToastMessage(toast as ToastMessageBase);
}
/**
* Plays a sound notification of a specific type
*/
public static function playSound():void {
notifySound.play(0, 0, new SoundTransform(0.8));
}
}
}

View File

@ -0,0 +1,28 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.common.toaster.container {
import flash.events.IEventDispatcher;
import org.bigbluebutton.common.toaster.message.ToastMessageBase;
public interface IToastContainer extends IEventDispatcher {
function addToastMessage(toastMessage:ToastMessageBase):void;
function closeToastMessage(toastMessage:ToastMessageBase):void;
}
}

View File

@ -0,0 +1,315 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
This program is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 3.0 of the License, or (at your option) any later
version.
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
-->
<mx:Canvas xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:fx="http://ns.adobe.com/mxml/2009"
implements="org.bigbluebutton.common.toaster.container.IToastContainer"
horizontalScrollPolicy="off"
verticalScrollPolicy="off"
height="100%">
<fx:Metadata>
[Event(name="onToastAdded", type="org.bigbluebutton.common.toaster.event.ToastEvent")]
[Event(name="onToastRemoved", type="org.bigbluebutton.common.toaster.event.ToastEvent")]
</fx:Metadata>
<fx:Script>
<![CDATA[
import flash.utils.setTimeout;
import mx.core.FlexGlobals;
import mx.core.UIComponent;
import mx.effects.Effect;
import mx.events.EffectEvent;
import mx.events.FlexEvent;
import mx.events.ResizeEvent;
import org.bigbluebutton.common.toaster.Toaster;
import org.bigbluebutton.common.toaster.effects.IToasterEffectDescriptor;
import org.bigbluebutton.common.toaster.effects.ToasterEffectDescriptorBase;
import org.bigbluebutton.common.toaster.event.ToastEvent;
import org.bigbluebutton.common.toaster.message.ToastMessageBase;
private const YOFFSET:int = -80;
/**
* Parent component for coordinate calculation
*/
private var _toastContainerParent:UIComponent = FlexGlobals.topLevelApplication as UIComponent;
public function get toastContainerParent():UIComponent {
return _toastContainerParent;
}
public function set toastContainerParent(value:UIComponent):void {
if (value != _toastContainerParent) {
if (_toastContainerParent) {
removeResizeListeners(_toastContainerParent);
}
_toastContainerParent = value;
addResizeListeners(value);
}
}
/**
* Tells the container wether to use a global positionning or a local one
*/
private var _useLocalPosition:Boolean = false;
public function get useLocalPosition():Boolean {
return _useLocalPosition;
}
public function set useLocalPosition(value:Boolean):void {
_useLocalPosition = value;
}
/**
* list of ToastMessageBase components
*/
private var _messages:Array = [];
/**
* list of queued ToastMessageBase components to display
*/
private var _messagesQueue:Array = [];
/**
* effects given to the toastmessages
*/
private var _effectDescriptor:IToasterEffectDescriptor = new ToasterEffectDescriptorBase();
public function set effectDescriptor(value:IToasterEffectDescriptor):void {
_effectDescriptor = value;
}
////////////////////////////////////////////////////////////////////////////
/**
* Add a toast message
*/
public function addToastMessage(toastMessage:ToastMessageBase):void {
if (_messages.indexOf(toastMessage) != -1) {
trace("ToastMessage aleady added to the container");
return;
}
// add to the display list
// keep it in local memory
_messagesQueue.push(toastMessage);
showNextToast();
}
private function showNextToast():void {
// Show only one notification at once
if (_messagesQueue.length > 0 && numChildren == 0) {
var container:ToastContainerBase = this;
var toastMessage:ToastMessageBase = _messagesQueue.shift();
toastMessage.addEventListener(FlexEvent.CREATION_COMPLETE, function(event:FlexEvent):void {
_messages.push(toastMessage);
// setting the parent reference on the message
toastMessage.container = container;
// mark it
toastMessage.markedForAddition = true;
// play the associated effect
var addedEffect:Effect = _effectDescriptor.getAddedEffect(toastMessage);
addedEffect.addEventListener(EffectEvent.EFFECT_END, onAddedEffectEnd);
addedEffect.play();
// inform everyone
dispatchEvent(new ToastEvent(ToastEvent.ON_TOAST_ADDED));
// move the message to the top of the stack
moveToStackTop(toastMessage);
});
addChildAt(toastMessage, 0);
setTimeout(toastMessage.close, 2000);
Toaster.playSound();
}
}
private function onAddedEffectEnd(event:EffectEvent):void {
(event.effectInstance as IEventDispatcher).removeEventListener(EffectEvent.EFFECT_END, onAddedEffectEnd);
var toastMessageTarget:ToastMessageBase = event.effectInstance.target as ToastMessageBase
toastMessageTarget.markedForAddition = false;
}
////////////////////////////////////////////////////////////////////////////
/**
* Move a toast message
*/
private function moveToStackTop(toastMessage:ToastMessageBase):void {
var globalPosition:Point = _useLocalPosition ? _toastContainerParent.localToGlobal(new Point()) : new Point();
var totalHeightValue:int = getTotalToastHeightValue(toastMessage);
var moveFromPoint:Point = new Point();
var moveToPoint:Point = new Point();
moveFromPoint.y = globalPosition.y + totalHeightValue - toastMessage.height;
moveToPoint.y = globalPosition.y + totalHeightValue;
x = globalPosition.x + _toastContainerParent.width - toastMessage.width;
var moveEffect:Effect = _effectDescriptor.getMoveToStackTopEffect(toastMessage, moveFromPoint, moveToPoint);
moveEffect.play();
}
/**
* get the highest y value so far (top of the stack)
*/
public function getTotalToastHeightValue(toastMessage:ToastMessageBase = null):int {
var max:Number = 0;
var nbItems:int = 0;
var hasElementMarkedForDeletion:Boolean = false;
for each (var toastMessageMemory:ToastMessageBase in _messages) {
if (toastMessageMemory.markedForDeletion) {
hasElementMarkedForDeletion = true;
continue;
}
max += toastMessageMemory.height;
nbItems++;
}
if (toastMessage) {
max -= toastMessage.height;
}
return max;
}
/////////////////////////////////////////////////////////////////////////////////
/**
* Close a toast message
*/
public function closeToastMessage(toastMessage:ToastMessageBase):void {
var idx:int = _messages.indexOf(toastMessage);
if (idx == -1) {
trace("Impossible to close the toast message: not referenced by the container");
return;
}
var moveToPoint:Point = new Point();
moveToPoint.y = toastMessage.y;
var removeEffect:Effect = _effectDescriptor.getRemovedEffect(toastMessage, moveToPoint);
toastMessage.markedForDeletion = true;
removeEffect.addEventListener(EffectEvent.EFFECT_END, onCloseEffectEnd);
removeEffect.play();
}
/**
* called at the end of the effect
*/
private function onCloseEffectEnd(event:EffectEvent):void {
(event.effectInstance as IEventDispatcher).removeEventListener(EffectEvent.EFFECT_END, onCloseEffectEnd);
var toastMessageTarget:ToastMessageBase = event.effectInstance.target as ToastMessageBase
var idx:int = _messages.indexOf(toastMessageTarget);
if (idx == -1) {
trace("Impossible to close the toast message: not referenced by the container");
return;
}
dispatchEvent(new ToastEvent(ToastEvent.ON_TOAST_REMOVED));
// move all the rest of the stack
moveMessagesToStackBottom();
_messages.splice(idx, 1);
removeChild(toastMessageTarget);
showNextToast();
}
private function getPreviousMessagesHeight(toastMessage:ToastMessageBase):int {
var heightUnder:int = 0;
for each (var memToastMessage:ToastMessageBase in _messages) {
if (memToastMessage == toastMessage) {
return heightUnder;
}
if (memToastMessage.markedForDeletion) {
heightUnder += memToastMessage.height;
}
}
return heightUnder;
}
////////////////////////////////////////////////////////////////////////////////
/**
* RE ORDER THE MESSAGES
*/
private function moveMessagesToStackBottom():void {
for each (var toastMessage:ToastMessageBase in _messages) {
if (toastMessage.markedForAddition) {
continue;
}
var heightDiff:int = getPreviousMessagesHeight(toastMessage);
heightDiff = heightDiff > 0 ? heightDiff : -heightDiff;
var moveToPoint:Point = new Point();
moveToPoint.y = toastMessage.y + heightDiff;
var moveEffect:Effect = _effectDescriptor.getMoveToStackBottomEffect(toastMessage, moveToPoint);
moveEffect.play();
}
}
////////////////////////////////////////////////////////////////////////////////
/**
* PARENT RESIZING
*/
private function addResizeListeners(uiComp:UIComponent):void {
uiComp.addEventListener(ResizeEvent.RESIZE, onParentResize);
}
private function removeResizeListeners(uiComp:UIComponent):void {
uiComp.removeEventListener(ResizeEvent.RESIZE, onParentResize);
}
private function onParentResize(event:ResizeEvent):void {
var target:UIComponent = event.target as UIComponent;
if (!target) {
return;
}
var wDiff:Number = event.oldWidth - target.width;
var hDiff:Number = event.oldHeight - target.measuredHeight;
// calculate X Offset depending on the position
var containerXOffset:Number = 0;
containerXOffset = wDiff / 2;
if (containerXOffset != 0) {
//if (position == ToasterPosition.BOTTOM_RIGHT) {
// rien
//} else {
x -= containerXOffset;
//}
}
// calculate Y Offset depending on the position
var containerYOffset:Number = 0;
if (containerYOffset != 0) {
y -= containerYOffset;
}
// setting correct width
var maxMessageWidth:Number = Number.POSITIVE_INFINITY;
var changeWidth:Boolean = false;
for each (var toastMessage:ToastMessageBase in _messages) {
toastMessage.y -= hDiff;
if (toastMessage.width < maxWidth) {
maxMessageWidth = toastMessage.width;
changeWidth = true;
}
}
// set the container width to the maximum width of the messages
if (changeWidth) {
width = maxMessageWidth;
}
}
]]>
</fx:Script>
</mx:Canvas>

View File

@ -0,0 +1,32 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.common.toaster.effects {
import flash.geom.Point;
import mx.effects.Effect;
import org.bigbluebutton.common.toaster.message.ToastMessageBase;
public interface IToasterEffectDescriptor {
function getAddedEffect(toastMessage:ToastMessageBase):Effect;
function getMoveToStackTopEffect(toastMessage:ToastMessageBase, moveFrom:Point, moveTo:Point):Effect;
function getMoveToStackBottomEffect(toastMessage:ToastMessageBase, moveTo:Point):Effect;
function getRemovedEffect(toastMessage:ToastMessageBase, moveTo:Point):Effect;
}
}

View File

@ -0,0 +1,80 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.common.toaster.effects {
import flash.geom.Point;
import mx.effects.Effect;
import mx.effects.Fade;
import mx.effects.Move;
import mx.effects.Parallel;
import mx.effects.easing.Bounce;
import org.bigbluebutton.common.toaster.message.ToastMessageBase;
public class ToasterEffectDescriptorBase implements IToasterEffectDescriptor {
private var _moveDuration:int = 750;
private var _fadeDuration:int = 750;
public function getAddedEffect(toastMessage:ToastMessageBase):Effect {
var fadeIn:Fade = new Fade(toastMessage);
fadeIn.alphaFrom = 0;
fadeIn.alphaTo = 1;
fadeIn.duration = _fadeDuration;
return fadeIn;
}
public function getMoveToStackTopEffect(toastMessage:ToastMessageBase, moveFrom:Point, moveTo:Point):Effect {
var move:Move = new Move(toastMessage);
move.xFrom = moveFrom.x;
move.yFrom = moveFrom.y;
move.xTo = moveTo.x;
move.yTo = moveTo.y;
move.duration = _moveDuration;
move.easingFunction = Bounce.easeOut;
return move;
}
public function getMoveToStackBottomEffect(toastMessage:ToastMessageBase, moveTo:Point):Effect {
var move:Move = new Move(toastMessage);
move.yTo = moveTo.y < 0 ? 0 : moveTo.y;
move.duration = _moveDuration;
return move;
}
public function getRemovedEffect(toastMessage:ToastMessageBase, moveTo:Point):Effect {
var parallel:Parallel = new Parallel(toastMessage);
var move:Move = new Move(toastMessage);
move.xTo = moveTo.x;
move.yTo = moveTo.y;
move.duration = _moveDuration;
parallel.addChild(move);
var fadeOut:Fade = new Fade();
fadeOut.alphaFrom = 1;
fadeOut.alphaTo = 0;
fadeOut.duration = _fadeDuration;
parallel.addChild(fadeOut);
parallel.end();
return parallel;
}
}
}

View File

@ -0,0 +1,32 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.common.toaster.event {
import flash.events.Event;
public class ToastEvent extends Event {
public static const ON_TOAST_ADDED:String = "onToastAdded";
public static const ON_TOAST_REMOVED:String = "onToastRemoved";
public function ToastEvent(type:String) {
super(type);
}
}
}

View File

@ -0,0 +1,29 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.common.toaster.event {
import flash.events.Event;
public class ToasterEvent extends Event {
public function ToasterEvent(type:String) {
super(type);
}
}
}

View File

@ -0,0 +1,35 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.common.toaster.message {
import org.bigbluebutton.common.toaster.container.IToastContainer;
public interface IToastMessage {
function set container(value:IToastContainer):void;
function set message(value:String):void;
function get message():String;
function set type(value:String):void;
function get type():String;
function set iconName(value:String):void;
function get iconName():String;
function get markedForDeletion():Boolean;
function set markedForDeletion(value:Boolean):void;
function get markedForAddition():Boolean;
function set markedForAddition(value:Boolean):void;
}
}

View File

@ -0,0 +1,15 @@
package org.bigbluebutton.common.toaster.message {
import mx.core.UIComponent;
public class IconCircle extends UIComponent {
public var x:int;
public var y:int;
public var radius:int;
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
graphics.drawCircle(x, y, radius);
}
}
}

View File

@ -0,0 +1,113 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.common.toaster.message {
import mx.containers.Canvas;
import org.as3commons.lang.StringUtils;
import org.bigbluebutton.common.toaster.container.IToastContainer;
/**
* This class is a basic container implementation for your toast.
* It just handles basic tasks (open, delay, close).
* This is the class you need to extend to create your own messages.
*/
public class ToastMessageBase extends Canvas implements IToastMessage {
// container
private var _container:IToastContainer = null;
public function set container(value:IToastContainer):void {
if (_container != value) {
_container = value;
}
}
// message
private var _message:String;
[Bindable]
public function set message(value:String):void {
_message = value;
}
public function get message():String {
return _message;
}
// type
private var _type:String;
[Bindable]
public function set type(value:String):void {
_type = value;
}
public function get type():String {
return _type;
}
// iconName
private var _iconName:String;
[Bindable]
public function set iconName(value:String):void {
_iconName = value;
}
public function get iconName():String {
return _iconName;
}
private var _markedForDeletion:Boolean = false;
public function get markedForDeletion():Boolean {
return _markedForDeletion;
}
public function set markedForDeletion(value:Boolean):void {
_markedForDeletion = value;
}
private var _markedForAddition:Boolean = false;
public function get markedForAddition():Boolean {
return _markedForAddition;
}
public function set markedForAddition(value:Boolean):void {
_markedForAddition = value;
}
public function get iconBackgroundColor():uint {
return getStyle('iconBackgroundColor' + StringUtils.capitalize(type));
}
public function get iconImageClass():Class {
var icon:Class = getStyle("icon" + StringUtils.capitalize(iconName));
if (!icon) {
icon = getStyle("icon" + StringUtils.capitalize(type));
}
return icon;
}
public function close():void {
_container.closeToastMessage(this);
}
}
}

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<message:ToastMessageBase xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:message="org.bigbluebutton.common.toaster.message.*"
height="75"
minWidth="320"
toolTip="{message}">
<mx:HBox styleName="toasterContainer"
horizontalScrollPolicy="off"
verticalScrollPolicy="off"
verticalCenter="0">
<mx:Canvas id="iconCanvas"
width="32"
height="32"
horizontalScrollPolicy="off"
verticalScrollPolicy="off">
<!-- Circle background -->
<s:Group verticalCenter="0"
horizontalCenter="0"
width="32"
height="32">
<s:Ellipse width="32"
height="32"
verticalCenter="0"
horizontalCenter="0">
<s:fill>
<s:SolidColor color="{iconBackgroundColor}" />
</s:fill>
</s:Ellipse>
</s:Group>
<mx:Image id="iconImage"
verticalCenter="0"
horizontalCenter="0"
source="{iconImageClass}" />
</mx:Canvas>
<mx:Text id="messageText"
selectable="false"
text="{message}"
textAlign="center" />
</mx:HBox>
<mx:Image id="closeButton"
top="10"
right="10"
width="14"
height="14"
source="{getStyle('iconClose')}" />
<mx:Canvas width="100%"
height="8"
backgroundColor="#E4ECF2"
bottom="0" />
</message:ToastMessageBase>

View File

@ -0,0 +1,32 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.common.toaster.message {
public final class ToastType {
public static const DEFAULT:String = "default";
public static const INFO:String = "info";
public static const SUCCESS:String = "success";
public static const WARNING:String = "warning";
public static const ERROR:String = "error";
}
}