Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to use Web API in Slidedown and Tagging Container #681

Merged
merged 8 commits into from
Aug 17, 2020
Merged
2 changes: 2 additions & 0 deletions src/managers/tagManager/page/TagManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ export default class TagManager implements ITagManager {
// no change detected, return {}
return finalTagsObject;
}

/**
* @param {TagsObject} tags - values of type "boolean"
* @returns void
*/
storeTagValuesToUpdate(tags: TagsObjectWithBoolean): void {
this.tagsFromTaggingContainer = tags;
}

/**
* @param {TagsObject} remoteTags - values of type "number"
* @returns void
Expand Down
95 changes: 59 additions & 36 deletions src/slidedown/Slidedown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import { SlidedownPermissionMessageOptions } from '../models/Prompts';
import { SERVER_CONFIG_DEFAULTS_SLIDEDOWN } from '../config';
import { getLoadingIndicatorWithColor } from './LoadingIndicator';
import { getRetryIndicator } from './RetryIndicator';
import { SlidedownCssClasses, SlidedownCssIds, COLORS } from "./constants";
import { SLIDEDOWN_CSS_CLASSES, SLIDEDOWN_CSS_IDS, COLORS } from "./constants";
import { Categories } from '../../src/models/Tags';
import Log from '../../src/libraries/Log';
import { getSlidedownHtml } from './SlidedownHtml';
import { getSlidedownElement } from './SlidedownElement';

export default class Slidedown {
public options: SlidedownPermissionMessageOptions;
Expand Down Expand Up @@ -59,16 +59,16 @@ export default class Slidedown {
}
}

async create(isInUpdateMode?: boolean) {
async create(isInUpdateMode?: boolean): Promise<void> {
// TODO: dynamically change btns depending on if its first or repeat display of slidedown (subscribe vs update)
if (this.notificationIcons === null) {
const icons = await MainHelper.getNotificationIcons();

this.notificationIcons = icons;

// Remove any existing container
if (this.container.className.includes(SlidedownCssClasses.container)) {
removeDomElement(`#${SlidedownCssIds.container}`);
if (this.container.className.includes(SLIDEDOWN_CSS_CLASSES.container)) {
removeDomElement(`#${SLIDEDOWN_CSS_IDS.container}`);
}
const positiveButtonText = isInUpdateMode && !!this.categoryOptions ?
this.categoryOptions.positiveUpdateButton : this.options.acceptButtonText;
Expand All @@ -78,22 +78,30 @@ export default class Slidedown {
this.categoryOptions.updateMessage : this.options.actionMessage;

const icon = this.getPlatformNotificationIcon();
const slidedownHtml = getSlidedownHtml({
const slidedownElement = getSlidedownElement({
messageText,
icon,
positiveButtonText,
negativeButtonText
});

const slidedownContainer = document.createElement("div");
const dialogContainer = document.createElement("div");

// Insert the container
addDomElement('body', 'beforeend', `<div id="${SlidedownCssIds.container}"` +
`class="${SlidedownCssClasses.container} ${SlidedownCssClasses.reset}"></div>`);
slidedownContainer.id = SLIDEDOWN_CSS_IDS.container;
addCssClass(slidedownContainer, SLIDEDOWN_CSS_CLASSES.container);
addCssClass(slidedownContainer, SLIDEDOWN_CSS_CLASSES.reset);
getDomElementOrStub('body').appendChild(slidedownContainer);

// Insert the dialog
addDomElement(this.container, 'beforeend',
`<div id="${SlidedownCssIds.dialog}" class="${SlidedownCssClasses.dialog}">${slidedownHtml}</div>`);
dialogContainer.id = SLIDEDOWN_CSS_IDS.dialog;
addCssClass(dialogContainer, SLIDEDOWN_CSS_CLASSES.dialog);
dialogContainer.appendChild(slidedownElement);
this.container.appendChild(dialogContainer);

// Animate it in depending on environment
addCssClass(this.container, bowser.mobile ? 'slide-up' : 'slide-down');
addCssClass(this.container, bowser.mobile ? SLIDEDOWN_CSS_CLASSES.slideUp : SLIDEDOWN_CSS_CLASSES.slideDown);

// Add click event handlers
this.allowButton.addEventListener('click', this.onSlidedownAllowed.bind(this));
Expand All @@ -102,22 +110,22 @@ export default class Slidedown {
}
}

async onSlidedownAllowed(_: any) {
async onSlidedownAllowed(_: any): Promise<void> {
await Event.trigger(Slidedown.EVENTS.ALLOW_CLICK);
}

onSlidedownCanceled(_: any) {
onSlidedownCanceled(_: any): void {
Event.trigger(Slidedown.EVENTS.CANCEL_CLICK);
this.close();
}

close() {
addCssClass(this.container, 'close-slidedown');
close(): void {
addCssClass(this.container, SLIDEDOWN_CSS_CLASSES.closeSlidedown);
once(this.dialog, 'animationend', (event: any, destroyListenerFn: () => void) => {
if (event.target === this.dialog &&
(event.animationName === 'slideDownExit' || event.animationName === 'slideUpExit')) {
// Uninstall the event listener for animationend
removeDomElement(`#${SlidedownCssIds.container}`);
removeDomElement(`#${SLIDEDOWN_CSS_IDS.container}`);
destroyListenerFn();
Event.trigger(Slidedown.EVENTS.CLOSED);
}
Expand All @@ -127,83 +135,98 @@ export default class Slidedown {
/**
* only used with Category Slidedown
*/
setSaveState(state: boolean) {
setSaveState(state: boolean): void {
if (!this.categoryOptions) {
Log.debug("Slidedown private category options are not defined");
return;
}

if (state) {
// note: savingButtonText is hardcoded in constructor. TODO: pull from config & set defaults for future release
this.allowButton.innerHTML = this.getIndicatorHolderHtmlWithText(this.categoryOptions!.savingButtonText!);
addDomElement(this.buttonIndicatorHolder, 'beforeend',
getLoadingIndicatorWithColor(COLORS.whiteLoadingIndicator));
this.allowButton.disabled = true;
this.allowButton.textContent = null;

this.allowButton.insertAdjacentElement('beforeend', this.getTextSpan(this.categoryOptions.savingButtonText));
this.allowButton.insertAdjacentElement('beforeend', this.getIndicatorHolder());

addDomElement(this.buttonIndicatorHolder,'beforeend', getLoadingIndicatorWithColor(COLORS.whiteLoadingIndicator));
addCssClass(this.allowButton, 'disabled');
addCssClass(this.allowButton, SlidedownCssClasses.savingStateButton);
addCssClass(this.allowButton, SLIDEDOWN_CSS_CLASSES.savingStateButton);
} else {
// positiveUpdateButton should be defined as written in MainHelper.getSlidedownPermissionMessageOptions
this.allowButton.innerHTML = this.categoryOptions!.positiveUpdateButton!;
removeDomElement(`#${SlidedownCssClasses.buttonIndicatorHolder}`);
this.allowButton.textContent = this.categoryOptions.positiveUpdateButton;
removeDomElement(`#${SLIDEDOWN_CSS_CLASSES.buttonIndicatorHolder}`);
this.allowButton.disabled = false;
removeCssClass(this.allowButton, 'disabled');
removeCssClass(this.allowButton, SlidedownCssClasses.savingStateButton);
removeCssClass(this.allowButton, SLIDEDOWN_CSS_CLASSES.savingStateButton);
}
}

setFailureState(state: boolean) {
setFailureState(state: boolean): void {
if (!this.categoryOptions) {
Log.debug("Slidedown private category options are not defined");
return;
}

if (state) {
// note: errorButtonText is hardcoded in constructor. TODO: pull from config & set defaults for future release
this.allowButton.innerHTML = this.getIndicatorHolderHtmlWithText(this.categoryOptions!.errorButtonText);
this.allowButton.textContent = null;
this.allowButton.insertAdjacentElement('beforeend', this.getTextSpan(this.categoryOptions.errorButtonText));
this.allowButton.insertAdjacentElement('beforeend', this.getIndicatorHolder());

addDomElement(this.buttonIndicatorHolder, 'beforeend', getRetryIndicator());
addCssClass(this.allowButton, 'onesignal-error-state-button');
} else {
removeDomElement('#onesignal-button-indicator-holder');
removeCssClass(this.allowButton, 'onesignal-error-state-button');
}

this.isShowingFailureState = state;
}

getPlatformNotificationIcon(): string {
return getPlatformNotificationIcon(this.notificationIcons);
}

getIndicatorHolderHtmlWithText(text: string) {
return `${text}<div id="${SlidedownCssIds.buttonIndicatorHolder}"` +
`class="${SlidedownCssClasses.buttonIndicatorHolder}"></div>`;
getIndicatorHolder(): Element {
const indicatorHolder = document.createElement("div");
indicatorHolder.id = SLIDEDOWN_CSS_IDS.buttonIndicatorHolder;
addCssClass(indicatorHolder, SLIDEDOWN_CSS_CLASSES.buttonIndicatorHolder);
return indicatorHolder;
}

getTextSpan(text: string): Element {
const textHolder = document.createElement("span");
textHolder.textContent = text;
return textHolder;
}

get container() {
return getDomElementOrStub(`#${SlidedownCssIds.container}`);
return getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.container}`);
}

get dialog() {
return getDomElementOrStub(`#${SlidedownCssIds.dialog}`);
return getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.dialog}`);
}

get allowButton() {
return getDomElementOrStub(`#${SlidedownCssIds.allowButton}`) as HTMLButtonElement;
return getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.allowButton}`) as HTMLButtonElement;
}

get cancelButton() {
return getDomElementOrStub(`#${SlidedownCssIds.cancelButton}`) as HTMLButtonElement;
return getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.cancelButton}`) as HTMLButtonElement;
}

get buttonIndicatorHolder() {
return getDomElementOrStub(`#${SlidedownCssIds.buttonIndicatorHolder}`);
return getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.buttonIndicatorHolder}`);
}

get slidedownFooter() {
return getDomElementOrStub(`#${SlidedownCssIds.footer}`);
return getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.footer}`);
}
}

export function manageNotifyButtonStateWhileSlidedownShows() {
export function manageNotifyButtonStateWhileSlidedownShows(): void {
const notifyButton = OneSignal.notifyButton;
if (notifyButton &&
notifyButton.options.enable &&
Expand Down
69 changes: 69 additions & 0 deletions src/slidedown/SlidedownElement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { SlidedownHtmlProps } from "./types";
import { DEFAULT_ICON, SLIDEDOWN_CSS_IDS, SLIDEDOWN_CSS_CLASSES, SLIDEDOWN_BUTTON_CLASSES } from "./constants";
import { addCssClass } from '../../src/utils';

export function getSlidedownElement(dialogProps: SlidedownHtmlProps): Element {
const { icon, messageText, positiveButtonText, negativeButtonText } = dialogProps;

const finalIcon = icon === SLIDEDOWN_CSS_CLASSES.defaultIcon ? DEFAULT_ICON : icon;
const finalIconClass = icon === SLIDEDOWN_CSS_CLASSES.defaultIcon ? SLIDEDOWN_CSS_CLASSES.defaultIcon : '';

const normalSlidedown = document.createElement("div");
const slidedownBody = document.createElement("div");
const bodyMessage = document.createElement("div");
const slidedownBodyIcon = document.createElement("div");
const loadingContainer = document.createElement("div");
const slidedownFooter = document.createElement("div");
const positiveButton = document.createElement("button");
const negativeButton = document.createElement("button");
const clearfix = document.createElement("div");
const clearfix2 = document.createElement("div");
const image = document.createElement("img");

addCssClass(slidedownBody, SLIDEDOWN_CSS_CLASSES.body);
addCssClass(slidedownBodyIcon, SLIDEDOWN_CSS_CLASSES.icon);
addCssClass(bodyMessage, SLIDEDOWN_CSS_CLASSES.message);
addCssClass(slidedownFooter, SLIDEDOWN_CSS_CLASSES.footer);
addCssClass(clearfix, SLIDEDOWN_CSS_CLASSES.clearfix);
addCssClass(clearfix2, SLIDEDOWN_CSS_CLASSES.clearfix);
addCssClass(positiveButton, SLIDEDOWN_BUTTON_CLASSES.alignRight);
addCssClass(positiveButton, SLIDEDOWN_BUTTON_CLASSES.primary);
addCssClass(positiveButton, SLIDEDOWN_BUTTON_CLASSES.slidedownButton);
addCssClass(negativeButton, SLIDEDOWN_BUTTON_CLASSES.alignRight);
addCssClass(negativeButton, SLIDEDOWN_BUTTON_CLASSES.secondary);
addCssClass(negativeButton, SLIDEDOWN_BUTTON_CLASSES.slidedownButton);

normalSlidedown.id = SLIDEDOWN_CSS_IDS.normalSlidedown;
slidedownBody.id = SLIDEDOWN_CSS_IDS.body;
loadingContainer.id = SLIDEDOWN_CSS_IDS.loadingContainer;
positiveButton.id = SLIDEDOWN_CSS_IDS.allowButton;
negativeButton.id = SLIDEDOWN_CSS_IDS.cancelButton;
slidedownFooter.id = SLIDEDOWN_CSS_IDS.footer;

if (finalIconClass) {
addCssClass(image, finalIconClass);
}

image.setAttribute("alt", "notification icon");
image.setAttribute("src", finalIcon || '');

bodyMessage.innerText = messageText || '';
positiveButton.innerText = positiveButtonText || '';
negativeButton.innerText = negativeButtonText || '';

slidedownBodyIcon.appendChild(image);

slidedownBody.appendChild(slidedownBodyIcon);
slidedownBody.appendChild(bodyMessage);
slidedownBody.appendChild(clearfix);
slidedownBody.appendChild(loadingContainer);

slidedownFooter.appendChild(positiveButton);
slidedownFooter.appendChild(negativeButton);
slidedownFooter.appendChild(clearfix2);

normalSlidedown.appendChild(slidedownBody);
normalSlidedown.appendChild(slidedownFooter);

return normalSlidedown;
}
28 changes: 0 additions & 28 deletions src/slidedown/SlidedownHtml.ts

This file was deleted.

Loading