/** * 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 () { $.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") { 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); } }