Untitled

 avatar
unknown
plain_text
a year ago
20 kB
5
Indexable
import { autoInjectable, container } from 'tsyringe';
import VrObject3D from '../Three/VrObject3D';
import { Block, Text } from 'three-mesh-ui';
import AxiosHttpClient from '../../Network/AxiosHttpClient';
import IntersectionContainer from '../Controllers/IntersectionContainer';
import { Color, TextureLoader } from 'three';
//@ts-ignore
import FontJSON from '../../../../static/assets/fonts/custom-roboto-regular-msdf.json';
//@ts-ignore
import FontImage from '../../../../static/assets/fonts/custom-roboto-regular.png';

//icons
import IconScrollUpWhite from '../../../../static/assets/icons/icon-name-scroll-up-white-full.png';
import IconScrollDownWhite from '../../../../static/assets/icons/icon-name-scroll-down-white-full.png';
import IconNotificationWhite from '../../../../static/assets/icons/icon-name-notification-white.png';
import FirebaseClient from '../../Network/Firebase/FirebaseClient';
import Utils from '../../Utils/Utils';

const NEW_MESSAGE = 'NEW_MESSAGE';
const NEW_ASSIGNMENT = 'NEW_ASSIGNMENT';
const NEW_ASSESSMENT_STUDENT = 'NEW_ASSESSMENT_STUDENT';
const NEW_ASSESSMENT_TEACHER = 'NEW_ASSESSMENT_TEACHER';
const NEW_ATTENDANCE = 'NEW_ATTENDANCE';
const NEW_GRADE = 'NEW_GRADE';
const UPDATE_GRADE = 'UPDATE_GRADE';
const DELETE_GRADE = 'DELETE_GRADE';
const CHAT_CREATED = 'CHAT_CREATED';
const UPDATE_ATTENDANCE = 'UPDATE_ATTENDANCE';
const NEW_ASSIGN_TEACHER_TO_GROUP = 'NEW_ASSIGN_TEACHER_TO_GROUP';

@autoInjectable()
export class NotificationsBoard extends VrObject3D {
    public container: Block;
    private textureLoader: TextureLoader;

    constructor(
        public httpClient?: AxiosHttpClient,
        public intersectionContainer?: IntersectionContainer,
    ) {
        super();

        this.textureLoader = new TextureLoader();

        const firebaseClient = container.resolve(FirebaseClient);

        firebaseClient
            .getDataOnce(
                firebaseClient.getUniversalNotificationPath(
                    this.resources.items.user.id,
                ),
            )
            .subscribe((data) => {
                this.fetchNotificationsBoard(data);
            });
    }

    public setDefaultState(block: Block, click?: Function) {
        let selectedAttribute: any = {
            state: 'selected',
            attributes: {
                backgroundColor: new Color(0xffffff),
                backgroundOpacity: 0.1,
            },
        };

        if (click) {
            selectedAttribute = {
                state: 'selected',
                attributes: {
                    // backgroundColor: new Color(0x6A6C6C),
                    backgroundColor: new Color(0xffffff),
                    backgroundOpacity: 0.1,
                },
                onSet: () => {
                    click();
                },
            };
        }

        //@ts-ignore
        block.setupState({
            state: 'idle',
            attributes: {
                // backgroundColor: new Color (0xffffff),
                backgroundOpacity: 0.001,
            },
        });
        //@ts-ignore
        block.setupState({
            state: 'hovered',
            attributes: {
                backgroundColor: new Color(0xffffff),
                backgroundOpacity: 0.1,
            },
        });

        //@ts-ignore
        block.setupState(selectedAttribute);
    }

    removeHtmlTags(htmlTags: string) {
        let html = htmlTags.replace('<img>', '||img||');
        let tmp = document.createElement('DIV');
        tmp.innerHTML = html;
        html = tmp.textContent || tmp.innerText;
        return html.replace('||img||', '<img>');
    }

    formatPublicationDate(date: string) {
        //  2019-11-27T08:24:13.000Z
        //  27.11.2019, 08:24

        let fd, y, mm, d, h, m;
        fd = new Date(date);
        y = fd.getUTCFullYear();
        mm = fd.getUTCMonth();
        d = fd.getUTCDate();
        // h=fd.getUTCHours().toString()
        // m=fd.getUTCMinutes().toString()

        return (
            y +
            '.' +
            (mm.toString().length === 1 ? '0' + mm.toString() : mm) +
            '.' +
            (d.toString().length === 1 ? '0' + d.toString() : d)
        );
    }

    public async fetchNotificationsBoard(data) {
        //todo: brak info jakie dane pobierać
        // this.notificationsBoard = await this.httpClient.xxxx

        const textures = {
            IconScrollUpWhite: await this.textureLoader.loadAsync(
                IconScrollUpWhite,
            ),
            IconScrollDownWhite: await this.textureLoader.loadAsync(
                IconScrollDownWhite,
            ),
            IconNotificationWhite: await this.textureLoader.loadAsync(
                IconNotificationWhite,
            ),
        };

        let borderWidth = 0.01;
        let borderColor = new Color(0xffffff);
        let borderOpacity = 0.8;
        let offsetActiveObj = 0.07;

        this.container = new Block({
            width: 4.2,
            height: 2.5,
            contentDirection: 'column',
            fontFamily: FontJSON,
            fontTexture: FontImage,
            fontColor: new Color(0xffffff),
            backgroundOpacity: 0,
            borderRadius: 0,
            borderWidth: borderWidth,
            borderColor: borderColor,
            borderOpacity: 0,
        });

        this.intersectionContainer.addObjectToIntersect(this.container, true);
        this.setDefaultState(this.container);

        // panel main
        const panelMainWrapper = new Block({
            width: 4.2,
            height: 2.5,
            hiddenOverflow: true,
            contentDirection: 'row',
            backgroundOpacity: 0,
            borderRadius: 0,
            borderWidth: 0,
            borderOpacity: 0,
            offset: 0.0001, //
        });

        //panel for content
        const panelMainContent = new Block({
            width: 4,
            height: 2.5,
            alignItems: 'start',
            backgroundOpacity: 0,
            borderRadius: 0,
            borderWidth: 0,
            borderOpacity: 0,
            offset: 0.0001, //
        });

        this.intersectionContainer.addObjectToIntersect(
            panelMainContent,
            true,
            true,
        );
        this.setDefaultState(panelMainContent);

        const panelMainScrollWrapper = new Block({
            width: 0.2,
            height: 2.5,
            backgroundOpacity: 0,
            contentDirection: 'column',
            alignItems: 'right',
            borderRadius: 0,
            borderWidth: 0,
            borderOpacity: 0,
            offset: 0.0001, //
        });

        const panelBtnScrollOptions = {
            width: 0.1,
            height: 0.1,
            offset: offsetActiveObj,
            backgroundOpacity: 0,
            justifyContent: 'center',
            alignItems: 'center',
            borderRadius: 0,
            borderWidth: borderWidth,
            borderColor: borderColor,
            borderOpacity: borderOpacity,
        };

        const panelBtnScrollUp = new Block(panelBtnScrollOptions);
        const panelBtnScrollDown = new Block(panelBtnScrollOptions);

        // IconScrollUpWhite
        panelBtnScrollUp.add(
            new Block({
                width: 0.08,
                height: 0.08,
                backgroundTexture: textures.IconScrollUpWhite,
                borderWidth: 0,
            }),
        );
        // IconScrollDownWhite
        panelBtnScrollDown.add(
            new Block({
                width: 0.08,
                height: 0.08,
                backgroundTexture: textures.IconScrollDownWhite,
                borderWidth: 0,
            }),
        );

        const panelScrollSpace = new Block({
            width: 0.2,
            height: 2.3,
            backgroundOpacity: 0,
            borderWidth: 0,
            borderOpacity: 0,
        });

        this.container.add(panelMainWrapper);
        panelMainWrapper.add(panelMainContent, panelMainScrollWrapper);
        panelMainScrollWrapper.add(
            panelBtnScrollUp,
            panelScrollSpace,
            panelBtnScrollDown,
        );

        this.setDefaultState(panelBtnScrollUp, () => {
            // @ts-ignore
            panelMainContent.position.y <= -panelMainContent.size.y ||
            panelMainContent.position.y <= 0
                ? (panelMainContent.position.y -= 0)
                : (panelMainContent.position.y -= 0.2);
        });
        this.setDefaultState(panelBtnScrollDown, () => {
            //@ts-ignore
            panelMainContent.position.y >= panelMainContent.size.y
                ? (panelMainContent.position.y += 0)
                : (panelMainContent.position.y += 0.2);
        });

        this.intersectionContainer.addObjectToIntersect(
            panelBtnScrollUp,
            false,
            true,
        );
        this.intersectionContainer.addObjectToIntersect(
            panelBtnScrollDown,
            false,
            true,
        );

        //----------------------------------------
        //data panel main ('panelMainContent')

        if (data) {
            const notificationArray: {
                data: any;
                datetime: string;
                object_type: string;
                timestamp: number;
                sender: {
                    firstName: string;
                    lastName: string;
                };
            }[] = Object.values(data);
            notificationArray.sort(
                (a, b) =>
                    new Date(b.timestamp * 1000).getTime() -
                    new Date(a.timestamp * 1000).getTime(),
            );
            notificationArray.length = 10;

            notificationArray.forEach((notification, key) => {
                // Block for one notification (click)
                const notificationWrapper = new Block({
                    width: 4,
                    height: 0.3, //todo: w zależności od danych które przyjdą
                    contentDirection: 'row',
                    offset: offsetActiveObj,
                    backgroundOpacity: 0,
                    borderRadius: 0,
                    borderWidth: borderWidth,
                    borderColor: borderColor,
                    borderOpacity: borderOpacity,
                });

                this.intersectionContainer.addObjectToIntersect(
                    notificationWrapper,
                    true,
                );
                this.setDefaultState(notificationWrapper);

                const notificationExtraSpace = new Block({
                    width: 0.1,
                    height: 0.2,
                    backgroundOpacity: 0,
                    borderWidth: 0,
                    borderOpacity: 0,
                });

                const notificationIcon = new Block({
                    width: 0.26,
                    height: 0.2,
                    justifyContent: 'center',
                    backgroundOpacity: 0,
                    borderRadius: 0,
                    borderWidth: 0,
                    borderOpacity: 0,
                });
                notificationIcon.add(
                    new Block({
                        width: 0.1,
                        height: 0.1,
                        backgroundTexture: textures.IconNotificationWhite,
                    }),
                );

                const notificationContent = new Block({
                    width: 3.2,
                    height: 0.2,
                    justifyContent: 'center',
                    textAlign: 'left',
                    fontSize: 0.08,
                    backgroundOpacity: 0,
                    borderRadius: 0,
                    borderWidth: 0,
                    borderOpacity: 0,
                    offset: 0.0001, //
                });

                this.notificationCreator(notification, notificationContent);
                const date = new Date(notification.timestamp * 1000);

                const day = date.getDate().toString().padStart(2, '0');
                const month = (date.getMonth() + 1).toString().padStart(2, '0');
                const year = date.getFullYear().toString();
                const hour = date.getHours().toString().padStart(2, '0');
                const minutes = date.getMinutes().toString().padStart(2, '0');

                const notificationDate = new Block({
                    width: 0.4,
                    height: 0.2,
                    justifyContent: 'center',
                    backgroundOpacity: 0,
                    borderRadius: 0,
                    borderWidth: 0,
                    borderOpacity: 0,
                });
                notificationDate.add(
                    new Text({
                        content: `${day}.${month}.${year} ${hour}:${minutes}`,
                        fontSize: 0.07,
                    }),
                );

                this.intersectionContainer.addObjectToIntersect(
                    notificationWrapper,
                    false,
                    true,
                );
                this.setDefaultState(notificationWrapper);

                const space = new Block({
                    width: 4.2,
                    height: 0.02,
                    borderWidth: 0,
                    borderOpacity: 0,
                    backgroundOpacity: 0,
                });

                panelMainContent.add(notificationWrapper, space);
                notificationWrapper.add(
                    notificationExtraSpace,
                    notificationIcon,
                    notificationContent,
                    notificationDate,
                    notificationExtraSpace,
                );

                this.setDefaultState(notificationWrapper, () => {
                    this.dispatchEvent({
                        type: 'notificationBtn',
                        data: [],
                    });
                });
            });
        } else {
            // console.log('!!notification NO DATA!!');
        }

        //.
        this.add(this.container);
    }

    public notificationCreator(notification: any, notificationContent: Block) {
        switch (notification.object_type) {
            case NEW_MESSAGE:
                notificationContent.add(
                    new Text({
                        content: `New message from ${
                            notification.sender?.firstName
                                ? Utils.stripNonAplhaNumericAndHtml(
                                      notification.sender?.firstName,
                                  ) +
                                  Utils.stripNonAplhaNumericAndHtml(
                                      notification.sender?.lastName,
                                  )
                                : ''
                        }  "${notification.data}"`,
                    }),
                );
                break;
            case NEW_ASSESSMENT_STUDENT:
                notificationContent.add(
                    new Text({
                        content: `Assessment has been created. The assessment "${Utils.stripNonAplhaNumericAndHtml(
                            notification.data.lesson_name,
                        )}" is now on the list and starts at ${
                            notification.data.start_date
                        }`,
                    }),
                );
                break;
            case NEW_ATTENDANCE:
                notificationContent.add(
                    new Text({
                        content: `New attendance ${Utils.stripNonAplhaNumericAndHtml(
                            notification.data,
                        )}`,
                    }),
                );
                break;
            case NEW_ASSIGNMENT:
                let content = '';
                if (typeof notification.data === 'string') {
                    content = `New assignment ${Utils.stripNonAplhaNumericAndHtml(
                        notification.data,
                    )}`;
                } else {
                    content = `New assignment ${Utils.stripNonAplhaNumericAndHtml(
                        notification.data.title,
                    )}`;
                }
                notificationContent.add(
                    new Text({
                        content: Utils.stripNonAplhaNumericAndHtml(content),
                    }),
                );
                break;
            case NEW_GRADE:
                notificationContent.add(
                    new Text({
                        content:
                            'New grade ' +
                            Utils.stripNonAplhaNumericAndHtml(
                                notification.data,
                            ),
                    }),
                );
                break;
            case UPDATE_GRADE:
                notificationContent.add(
                    new Text({
                        content:
                            'Update grade ' +
                            Utils.stripNonAplhaNumericAndHtml(
                                notification.data,
                            ),
                    }),
                );
                break;
            case CHAT_CREATED:
                notificationContent.add(
                    new Text({
                        content:
                            'Teacher created a chat ' +
                            Utils.stripNonAplhaNumericAndHtml(
                                notification.sender.firstName,
                            ) +
                            ' ' +
                            Utils.stripNonAplhaNumericAndHtml(
                                notification.sender.lastName,
                            ) +
                            ' created a chat',
                    }),
                );
                break;
            case UPDATE_ATTENDANCE:
                notificationContent.add(
                    new Text({
                        content:
                            'Update ' +
                            Utils.stripNonAplhaNumericAndHtml(
                                notification.data,
                            ),
                    }),
                );
                break;
            case NEW_ASSESSMENT_TEACHER:
                notificationContent.add(
                    new Text({
                        content: `New assignment ${Utils.stripNonAplhaNumericAndHtml(
                            notification.data.lesson_name,
                        )}`,
                    }),
                );
                break;
            case NEW_ASSIGN_TEACHER_TO_GROUP:
                notificationContent.add(
                    new Text({
                        content: 'You have been assigned to a group',
                    }),
                );
        }
    }
}
Editor is loading...
Leave a Comment