/** * YourTeam Notice 訊息彈出小視窗 (on base bootstrap v4 toast) * * 使用方式: *
* * * */ class YTNotice { constructor(option = {}) { this.id = option.id ?? null; this.title = option.title ?? ""; this.content = option.content ?? ""; this.type = option.type ?? null; this.hasCloseBtn = option.hasCloseBtn ?? true; this.keepTime = 0; this.timeText = option.timeText ?? "剛剛"; this.iconClass = option.iconClass ?? ""; this.container = ""; this.eIcon = ""; this.eTitle = ""; this.eTimeAgo = ""; this.eCloseBtn = ""; this.eContent = ""; this.init(); } init = function () { this.setNoticeId(); this.setIconClass(); this.setContainer(); if (this.title) { this.setTitle(this.title); } if (this.content) { this.setContent(this.content); } if (this.timeText) { this.setTimeAgo(this.timeText); } $(this.container)[0]._ytNotice = this; }; setNoticeId = function () { if (this.id == null) { this.id = YT.Math.Random(10000000, 99999999); } }; setContainer = function () { this.container = $(``); this.setIcon(this.iconClass); this.eTitle = $(``); this.eTimeAgo = $(``); this.eCloseBtn = $( `` ); this.eContent = $(`
`); if (this.type != null) { this.container.find(".toast-header").append(this.eIcon); this.eIcon.addClass("text-" + this.type); } this.container.find(".toast-header").append(this.eTitle); this.container.find(".toast-header").append(this.eTimeAgo); if (this.hasCloseBtn) { this.container.find(".toast-header").append(this.eCloseBtn); } this.container.find(".toast-body").append(this.eContent); }; setIconClass = function () { if (this.type == "success") { this.iconClass = `fas fa-check`; } else if (this.type == "warning") { this.iconClass = `fas fa-exclamation-triangle`; } else if (this.type == "danger") { this.iconClass = `fas fa-times`; } }; setIcon = function (iconClass) { this.eIcon = $(``); this.eIcon.addClass(iconClass); }; setTitle = function (title = "") { this.eTitle.html(title); }; setTimeAgo = function (timeAgo = "") { this.eTimeAgo.text(timeAgo); }; setContent = function (content = "") { this.eContent.html(content); }; } class YTNoticeBlock { constructor(option = {}) { this.element = option.element; this.offsetBottom = 200; this.noticeArr = []; this.eScroll = $(`
`); this.noticeContainer = ""; this.scrollY = option.scrollY ?? true; this.init(); } init = function () { this.drawInitScroll(); this.drawElement(); if (this.scrollY) { this.noticeContainer = this.eScroll; } else { this.noticeContainer = this.element; } this.updEleObj(); }; drawInitScroll = function () { if (this.scrollY) { $(this.eScroll).css("height", "100%"); $(this.eScroll).css("overflow-y", "auto"); $(this.element).append(this.eScroll); } }; drawElement = function () { $(this.element).addClass("yt-notice-block"); }; showOneNotice = function (obj = null, append = "prepend") { if (obj) { if (append == "prepend") { $(this.noticeContainer).prepend(obj.container); } else if (append == "append") { $(this.noticeContainer).append(obj.container); } $(obj.container).toast("show"); } }; hideOneNotice = function (obj = null) { if (obj) { let toast = ""; if (obj.is("div.toast")) { toast = obj; } else { toast = obj.container; } $(toast).toast("dispose"); setTimeout(() => { $(toast).remove(); let tarNoticeId = $(toast)[0]._ytNotice.id; let tarNoticeIdx = this.noticeArr.findIndex( (x) => x.obj.id == tarNoticeId ); if (tarNoticeIdx != -1) { this.noticeArr[tarNoticeIdx].canShow = false; } this.showNotices(); }, 100); } this.updEleObj(); }; checkCanShow = function (notice = null) { let lastNoticeOffset = $(this.noticeContainer) .find(".toast") .last() .offset(); if ($(this.noticeContainer).find(".toast").last().length == 0) { return notice.canShow; } if ($(notice.obj.container).is(":visible")) { return false; } if (!notice.canShow) { return false; } if (lastNoticeOffset.top + this.offsetBottom > $(window).height()) { return false; } else { return true; } }; showNotices = function () { if (this.noticeArr.length === 0) { $(this.noticeContainer).empty(); } else { $.each(this.noticeArr, (idx, notice) => { if (this.checkCanShow(notice)) { this.showOneNotice(notice.obj, "append"); } }); } }; pushNotice = function (option = {}) { if (this.noticeArr.findIndex((x) => x.obj.id == option.id) == -1) { let notice = new YTNotice(option); this.noticeArr.push({ obj: notice, time: new Date().getTime(), canShow: true, }); this.setEvent(notice); } this.updEleObj(); }; updEleObj = function () { $(this.element)[0]._noticeBlock = this; }; setEvent = function (notice) { let _this = this; $(notice.container).on("hidden.bs.toast", function () { setTimeout(() => { $(notice.container).remove(); let tarNoticeId = $(notice.container)[0]._ytNotice.id; let tarNoticeIdx = _this.noticeArr.findIndex( (x) => x.obj.id == tarNoticeId ); if (tarNoticeIdx != -1) { _this.noticeArr[tarNoticeIdx].canShow = false; } _this.showNotices(); }, 100); }); }; } $.fn.YTNotice = function (method = "init", ...args) { let _this = this; if (method == "init") { initNoticeBlock(); } let noticeBlock = _this[0]._noticeBlock; if (!noticeBlock) { initNoticeBlock(); noticeBlock = _this[0]._noticeBlock; } if (method == "add") { noticeBlock.pushNotice(args[0] ?? {}); noticeBlock.showNotices(); } else if (method == "add_many") { noticeBlock.noticeArr = []; args[0].forEach((arg, idx) => { noticeBlock.pushNotice(arg); }); noticeBlock.showNotices(); } else if (method == "hide") { if (args.length == 0) { noticeBlock = $(_this).parents(".yt-notice-block")[0]._noticeBlock; noticeBlock.hideOneNotice(this); } } function initNoticeBlock() { let option = {}; option.element = _this; let noticeBlock = new YTNoticeBlock(option); } };