diff --git a/app/deploy_prod.sh b/app/deploy_prod.sh index 86b9c19..edb1f6b 100755 --- a/app/deploy_prod.sh +++ b/app/deploy_prod.sh @@ -1,16 +1,29 @@ #!/bin/bash +# 任意一步失败立即退出,避免没编出二进制也照样上传重启 +set -e +cd "$(dirname "$0")" + +# 终端 PATH 里没有 go 时兜底用 ~/sdk/go +if ! command -v go >/dev/null 2>&1 && [ -x "$HOME/sdk/go/bin/go" ]; then + export PATH="$HOME/sdk/go/bin:$PATH" +fi + echo "开始" rm -rf ./web_huangguo_h5 ./web_huangguo_h5.tar.gz GOOS=linux GOARCH=amd64 go build -o web_huangguo_h5 -tar zvcf web_huangguo_h5.tar.gz web_huangguo_h5 templates/ static/ \ + +# --exclude 必须放在文件列表前面,macOS 的 bsdtar 会把后面的参数当文件名; +# COPYFILE_DISABLE / --no-xattrs 不打包 macOS 扩展属性,免得服务器 tar 报 LIBARCHIVE.xattr +COPYFILE_DISABLE=1 tar zvcf web_huangguo_h5.tar.gz --no-xattrs \ --exclude='templates/page/sitemaps/sitemap.xml' \ --exclude='templates/page/sitemaps/sitemap-*.xml' \ --exclude='templates/page/rss.xml' \ --exclude='templates/page/llms.txt' \ - --exclude='templates/page/llms-full.txt' + --exclude='templates/page/llms-full.txt' \ + web_huangguo_h5 templates/ static/ scp web_huangguo_h5.tar.gz root@172.104.166.87:/data/uzip ssh root@172.104.166.87 "/server/web_huangguo/h5/up_app.sh" -rm -rf ./web_huangguo_h5 ./web_huangguo_h5.tar.gz \ No newline at end of file +rm -rf ./web_huangguo_h5 ./web_huangguo_h5.tar.gz diff --git a/app/service/configser/types.go b/app/service/configser/types.go index 8796101..c97e7c4 100644 --- a/app/service/configser/types.go +++ b/app/service/configser/types.go @@ -87,6 +87,11 @@ type AdvitiseData struct { TitleList []Advertisement `json:"titleList"` PlayList []Advertisement `json:"playList"` PauseyList []Advertisement `json:"pauseyList"` + // 本站后台(webhgdjapi)的字段名:横幅 / 播放页小图标 / 首页小图标 + VideoTopList []Advertisement `json:"videoTopList"` + VideoDownList []Advertisement `json:"videoDownList"` + AppInfoAList []Advertisement `json:"appInfoAList"` + AppInfoBList []Advertisement `json:"appInfoBList"` } // Advertisement 对应 swagger proxy.AdvitiseInfo。 diff --git a/app/service/configser/view.go b/app/service/configser/view.go index 7d75eeb..aa0d7a7 100644 --- a/app/service/configser/view.go +++ b/app/service/configser/view.go @@ -7,29 +7,31 @@ import ( // AppConfigVM 注入全站页面的公共配置(字段名与接口 newAddressInfo / seoInfo 对齐)。 type AppConfigVM struct { - ForeverURLAddr string `json:"foreverUrlAddr"` - NewURLAddr string `json:"newUrlAddr"` - NewURLAddr1 string `json:"newUrlAddr1"` - NewURLAddr2 string `json:"newUrlAddr2"` - GmailAddr string `json:"gmailAddr"` - QQ string `json:"qq"` - TGGroup string `json:"tgGroup"` - Telegram string `json:"telegram"` - PotaoGroup string `json:"potaoGroup"` - CustomerServiceHost string `json:"customerServiceHost"` - AppAddr string `json:"appAddr"` - OfficialAppAddr string `json:"officialAppAddr"` - PDFAddr string `json:"pdfAddr"` - TwitterAddr string `json:"twitterAddr"` - SeoInfo SeoInfo `json:"seoInfo,omitempty"` - SeoNavInfo SeoNavInfo `json:"seoNavInfo,omitempty"` - NavPageList []NavPageItem `json:"navPageList,omitempty"` - Advitise AdvitiseData `json:"advitise"` - DetailTopList []Advertisement `json:"detailTopList,omitempty"` - NineGridList []Advertisement `json:"nineGridList,omitempty"` - DetailBannerList []Advertisement `json:"detailbannerList,omitempty"` - BottomBanner []Advertisement `json:"bottomBanner,omitempty"` - DialogList []Advertisement `json:"dialogList,omitempty"` + ForeverURLAddr string `json:"foreverUrlAddr"` + NewURLAddr string `json:"newUrlAddr"` + NewURLAddr1 string `json:"newUrlAddr1"` + NewURLAddr2 string `json:"newUrlAddr2"` + GmailAddr string `json:"gmailAddr"` + QQ string `json:"qq"` + TGGroup string `json:"tgGroup"` + Telegram string `json:"telegram"` + PotaoGroup string `json:"potaoGroup"` + CustomerServiceHost string `json:"customerServiceHost"` + AppAddr string `json:"appAddr"` + OfficialAppAddr string `json:"officialAppAddr"` + PDFAddr string `json:"pdfAddr"` + TwitterAddr string `json:"twitterAddr"` + SeoInfo SeoInfo `json:"seoInfo,omitempty"` + SeoNavInfo SeoNavInfo `json:"seoNavInfo,omitempty"` + NavPageList []NavPageItem `json:"navPageList,omitempty"` + Advitise AdvitiseData `json:"advitise"` + // 网页只用后台「站点」的 5 个广告位: + // 弹窗 / 9宫格(弹窗广告后弹出)/ 详情横幅 / 播放页小图标 / 首页小图标 + DialogList []Advertisement `json:"dialogList,omitempty"` + NineGridList []Advertisement `json:"nineGridList,omitempty"` + DetailBannerList []Advertisement `json:"detailbannerList,omitempty"` + AList []Advertisement `json:"AList,omitempty"` + BList []Advertisement `json:"BList,omitempty"` } // BuildAppConfigVM 从上游配置组装前端可用字段。 @@ -55,11 +57,12 @@ func BuildAppConfigVM(info *ConfigInfoResp) AppConfigVM { TwitterAddr: sanitizeURL(addr.TwitterAddr), NavPageList: buildNavPageList(info.NavPageList), Advitise: info.Advitise, - DetailTopList: buildAdvertisementList(info.Advitise.DetailTopList), - NineGridList: buildAdvertisementList(info.Advitise.NineGridList), - DetailBannerList: buildAdvertisementList(info.Advitise.DetailBannerList), - BottomBanner: buildAdvertisementList(info.Advitise.BottomBanner), DialogList: buildAdvertisementList(info.Advitise.DialogList), + NineGridList: buildAdvertisementList(info.Advitise.NineGridList), + // 本站后台用 videoTopList / appInfoAList / appInfoBList;兼容 detailbannerList / AList / BList 命名 + DetailBannerList: firstAdvertisementList(info.Advitise.VideoTopList, info.Advitise.DetailBannerList), + AList: firstAdvertisementList(info.Advitise.AppInfoAList, info.Advitise.AList), + BList: firstAdvertisementList(info.Advitise.AppInfoBList, info.Advitise.BList), SeoInfo: SeoInfo{ Title: strings.TrimSpace(info.SeoInfo.Title), Description: strings.TrimSpace(info.SeoInfo.Description), @@ -94,20 +97,14 @@ func buildAdvertisementList(list []Advertisement) []Advertisement { return out } -// NineGridRow 按首页设计每行返回两个 banner,超出当前行时返回空切片。 -func (c AppConfigVM) NineGridRow(row int) []Advertisement { - if row < 0 { - return nil +// firstAdvertisementList 返回第一个有可用广告的列表(按字段优先级)。 +func firstAdvertisementList(lists ...[]Advertisement) []Advertisement { + for _, list := range lists { + if built := buildAdvertisementList(list); len(built) > 0 { + return built + } } - start := row * 2 - if start >= len(c.NineGridList) { - return nil - } - end := start + 2 - if end > len(c.NineGridList) { - end = len(c.NineGridList) - } - return c.NineGridList[start:end] + return nil } // QRText 下载弹窗二维码、跳转及复制链接内容:仅使用应用下载地址 appAddr。 diff --git a/app/service/configser/view_test.go b/app/service/configser/view_test.go index 3ce05f9..46f1005 100644 --- a/app/service/configser/view_test.go +++ b/app/service/configser/view_test.go @@ -18,8 +18,7 @@ func TestBuildAppConfigVMIncludesValidAdvertisements(t *testing.T) { NewAddressInfo: NewAddressInfo{Telegram: " https://t.me/business ", QQ: " 2168045324 ", OfficialAppAddr: " https://app.example.com/download\\ "}, Config: ConfigInfo{PotaoGroup: " https://potato.example.com/group\\ "}, Advitise: AdvitiseData{ - HomeList: []Advertisement{{ID: "home", Images: "https://cdn.example.com/home.gif"}}, - DetailTopList: []Advertisement{{ID: "top", Images: " https://cdn.example.com/top.gif "}}, + HomeList: []Advertisement{{ID: "home", Images: "https://cdn.example.com/home.gif"}}, NineGridList: []Advertisement{ {ID: "banner-1", Images: "https://cdn.example.com/banner-1.gif"}, {ID: "banner-empty", Images: " "}, @@ -27,10 +26,13 @@ func TestBuildAppConfigVMIncludesValidAdvertisements(t *testing.T) { {ID: "banner-3", Images: "https://cdn.example.com/banner-3.gif"}, }, DetailBannerList: []Advertisement{{ID: "detail", Images: "https://cdn.example.com/detail.gif"}}, - BottomBanner: []Advertisement{ - {ID: " bottom ", Images: " https://cdn.example.com/bottom.gif ", Link: " https://example.com/bottom "}, - {ID: "bottom-empty", Images: " "}, + VideoTopList: []Advertisement{ + {ID: " video-top ", Images: " https://cdn.example.com/video-top.gif ", Link: " https://example.com/top "}, + {ID: "video-top-empty", Images: " "}, }, + AList: []Advertisement{{ID: "a-legacy", Images: "https://cdn.example.com/a.gif"}}, + AppInfoAList: []Advertisement{{ID: "a", Images: "https://cdn.example.com/app-a.gif"}}, + BList: []Advertisement{{ID: "b", Images: "https://cdn.example.com/b.gif"}}, DialogList: []Advertisement{ {ID: " 1 ", Images: " https://cdn.example.com/ad.webp\\ ", Link: " https://example.com ", Title: " 广告一 "}, {ID: "2", Images: " ", Title: "无图广告"}, @@ -56,17 +58,19 @@ func TestBuildAppConfigVMIncludesValidAdvertisements(t *testing.T) { if len(vm.Advitise.NineGridList) != 4 { t.Fatalf("Advitise.NineGridList length = %d, want raw length 4", len(vm.Advitise.NineGridList)) } - if len(vm.DetailTopList) != 1 || vm.DetailTopList[0].ID != "top" { - t.Fatalf("DetailTopList = %#v", vm.DetailTopList) - } if len(vm.NineGridList) != 3 { t.Fatalf("NineGridList length = %d, want 3", len(vm.NineGridList)) } - if len(vm.DetailBannerList) != 1 || vm.DetailBannerList[0].ID != "detail" { + // 详情横幅优先 videoTopList(本站后台字段),无效图片被过滤 + if len(vm.DetailBannerList) != 1 || vm.DetailBannerList[0].ID != "video-top" || vm.DetailBannerList[0].Images != "https://cdn.example.com/video-top.gif" { t.Fatalf("DetailBannerList = %#v", vm.DetailBannerList) } - if len(vm.BottomBanner) != 1 || vm.BottomBanner[0].ID != "bottom" || vm.BottomBanner[0].Images != "https://cdn.example.com/bottom.gif" { - t.Fatalf("BottomBanner = %#v", vm.BottomBanner) + // 播放页小图标优先 appInfoAList;首页小图标无 appInfoBList 时回退 BList + if len(vm.AList) != 1 || vm.AList[0].ID != "a" { + t.Fatalf("AList = %#v", vm.AList) + } + if len(vm.BList) != 1 || vm.BList[0].ID != "b" { + t.Fatalf("BList = %#v", vm.BList) } if len(vm.DialogList) != 1 { t.Fatalf("DialogList length = %d, want 1", len(vm.DialogList)) @@ -76,16 +80,3 @@ func TestBuildAppConfigVMIncludesValidAdvertisements(t *testing.T) { t.Fatalf("DialogList[0] = %#v", got) } } - -func TestNineGridRowReturnsTwoItemsPerRow(t *testing.T) { - cfg := AppConfigVM{NineGridList: []Advertisement{{ID: "1"}, {ID: "2"}, {ID: "3"}}} - if got := cfg.NineGridRow(0); len(got) != 2 || got[0].ID != "1" || got[1].ID != "2" { - t.Fatalf("NineGridRow(0) = %#v", got) - } - if got := cfg.NineGridRow(1); len(got) != 1 || got[0].ID != "3" { - t.Fatalf("NineGridRow(1) = %#v", got) - } - if got := cfg.NineGridRow(2); len(got) != 0 { - t.Fatalf("NineGridRow(2) = %#v, want empty", got) - } -} diff --git a/app/static/css/detail.css b/app/static/css/detail.css index dd95c3e..aef02bf 100644 --- a/app/static/css/detail.css +++ b/app/static/css/detail.css @@ -737,13 +737,13 @@ width: 100%; } -/* Figma: 1431×178 banner frame — stretch, 178px, radius 12, image cover-crop */ +/* 详情横幅:按素材 720×150 等比展示,避免裁切 */ .content-ad-stack a { display: block; position: relative; align-self: stretch; width: 100%; - height: 178px; + aspect-ratio: 720 / 150; overflow: hidden; border-radius: 12px; } @@ -865,7 +865,6 @@ .content-ad-stack { gap: calc(12px * var(--detail-s)); } .content-ad-stack a { - height: calc(166px * var(--detail-s)); border-radius: calc(12px * var(--detail-s)); } @@ -1001,9 +1000,11 @@ .detail-h5-top-actions, .square-promo--pc-only, .content-official-info, - .content-ad-stack, .content-column-divider { display: none !important; } + .content-ad-stack { gap: 10px; } + .content-ad-stack a { border-radius: 8px; } + .detail-layout, .detail-main, .detail-sidebar { display: contents; } diff --git a/app/static/css/homeAdRow.css b/app/static/css/homeAdRow.css deleted file mode 100644 index f6a39c0..0000000 --- a/app/static/css/homeAdRow.css +++ /dev/null @@ -1,100 +0,0 @@ -/* Shared home banner ad row (PC 2-col flex / H5 stack). */ - -/* PC Figma: stretch row, 94px, gap 36, two equal flex slots */ -.home-ad-row { - align-self: stretch; - display: flex; - flex-wrap: wrap; - justify-content: flex-start; - align-items: flex-start; - gap: 36px; - width: 100%; - flex-shrink: 0; - box-sizing: border-box; -} - -.home-ad-row.home-ad-row--mobile { - display: none; -} - -.home-ad-row .home-ad-banner { - position: relative; - flex: 1 1 calc((100% - 36px) / 2); - width: auto; - min-width: 0; - max-width: calc((100% - 36px) / 2); - height: 94px; - overflow: hidden; - border-radius: 12px; - box-sizing: border-box; -} - -.home-ad-row .home-ad-banner img { - position: absolute; - left: 0; - top: 0; - display: block; - width: 100%; - height: 100%; - object-fit: cover; -} - -@media (min-width: 768px) { - .home-ad-row { - gap: 36px; - } - - .home-ad-row .home-ad-banner { - flex: 1 1 calc((100% - 36px) / 2); - max-width: calc((100% - 36px) / 2); - height: 94px; - border-radius: 12px; - } - - .home-ad-row .home-ad-banner img { - position: absolute; - left: 0; - top: 0; - width: 100%; - height: 100%; - object-fit: cover; - } -} - -@media (max-width: 767px) { - .home-ad-row, - .home-ad-row.home-ad-row--mobile { - height: auto; - display: flex; - flex-direction: column; - flex-wrap: nowrap; - align-self: stretch; - gap: 12px; - } - - .home-ad-row.home-ad-row--desktop { - display: none; - } - - /* H5 Figma: 343×43 banner — stretch, 43px, radius 6, image cover-crop */ - .home-ad-row .home-ad-banner { - position: relative; - align-self: stretch; - flex: 0 0 43px; - width: 100%; - max-width: none; - height: 43px; - overflow: hidden; - border-radius: 6px; - } - - .home-ad-row .home-ad-banner img { - position: absolute; - left: 0; - top: 0; - width: 100%; - height: 100%; - object-fit: cover; - background: #464646; - } -} diff --git a/app/static/css/nineGridDialog.css b/app/static/css/nineGridDialog.css new file mode 100644 index 0000000..8b7edf3 --- /dev/null +++ b/app/static/css/nineGridDialog.css @@ -0,0 +1,104 @@ +/* 九宫格弹窗:深色模糊遮罩 + 4 列应用图标 + 底部关闭按钮(对齐 huangguocg.com) */ +.nine-grid-mask { + position: fixed; + inset: 0; + z-index: 1900; + padding: 40px 24px; + display: none; + align-items: center; + justify-content: center; + background: rgba(0, 0, 0, 0.85); + -webkit-backdrop-filter: blur(12px); + backdrop-filter: blur(12px); + box-sizing: border-box; +} + +.nine-grid-mask.is-open { + display: flex; +} + +.nine-grid-panel { + width: min(520px, 100%); + display: flex; + flex-direction: column; + align-items: center; + gap: 24px; +} + +.nine-grid-list { + width: 100%; + max-height: 70vh; + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 28px 24px; + overflow-y: auto; + overscroll-behavior: contain; +} + +.nine-grid-item { + min-width: 0; + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + color: #fff; + text-decoration: none; +} + +.nine-grid-item[hidden] { + display: none; +} + +.nine-grid-icon { + width: 100%; + max-width: 80px; + aspect-ratio: 1; + display: block; + object-fit: cover; + border-radius: 18px; +} + +.nine-grid-name { + max-width: 100%; + overflow: hidden; + font-size: 15px; + line-height: 22px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.nine-grid-close { + width: 36px; + height: 36px; + padding: 0; + background: transparent; + border: 0; + border-radius: 50%; + cursor: pointer; +} + +.nine-grid-close img { + width: 100%; + height: 100%; + display: block; +} + +@media (max-width: 767px) { + .nine-grid-panel { + width: min(360px, 100%); + } + + .nine-grid-list { + gap: 20px 12px; + } + + .nine-grid-icon { + max-width: 70px; + border-radius: 16px; + } + + .nine-grid-name { + font-size: 13px; + line-height: 18px; + } +} diff --git a/app/static/css/play.css b/app/static/css/play.css index 5b3d413..cdc96c3 100644 --- a/app/static/css/play.css +++ b/app/static/css/play.css @@ -2784,7 +2784,6 @@ a.play-info-tag:focus-visible { .square-promo--pc-only, .content-official-info, - .content-ad-stack, .content-column-divider, .play-sidebar, .play-download-btn { display: none !important; } diff --git a/app/static/js/pages/dialogAd.js b/app/static/js/pages/dialogAd.js index 9acacc4..7ed4085 100644 --- a/app/static/js/pages/dialogAd.js +++ b/app/static/js/pages/dialogAd.js @@ -1,14 +1,21 @@ (function () { + // 弹窗广告队列结束(含没有 / 已关闭过)后通知九宫格弹窗:年龄确认 → 弹窗广告 → 九宫格 + function markDone() { + if (window.__dialogAdDone) return; + window.__dialogAdDone = true; + document.dispatchEvent(new CustomEvent("dialogad:done")); + } + var QUEUE_VERSION = "2"; var DISMISSED_KEY = "dialogAdDismissed"; var PROGRESS_KEY = "dialogAdProgress"; var mask = document.querySelector("[data-dialog-ad]"); var previousBodyOverflow = ""; var hasDisplayedItem = false; - if (!mask) return; + if (!mask) return markDone(); var items = Array.prototype.slice.call(mask.querySelectorAll("[data-dialog-ad-item]")); - if (!items.length) return; + if (!items.length) return markDone(); var queueSignature = QUEUE_VERSION + @@ -111,7 +118,8 @@ mask.classList.remove("is-open"); mask.hidden = true; mask.setAttribute("hidden", ""); - document.body.style.overflow = previousBodyOverflow; + document.body.style.overflow = previousBodyOverflow === "hidden" ? "" : previousBodyOverflow; + markDone(); } function showWhenAgeGateAllows() { @@ -215,7 +223,7 @@ } }); - if (isDismissed()) return; + if (isDismissed()) return markDone(); if (currentIndex >= items.length) { finishQueue(); return; diff --git a/app/static/js/pages/nineGridDialog.js b/app/static/js/pages/nineGridDialog.js new file mode 100644 index 0000000..45c38d0 --- /dev/null +++ b/app/static/js/pages/nineGridDialog.js @@ -0,0 +1,160 @@ +(function () { + // 九宫格弹窗(对齐 huangguocg.com):年龄确认 → 弹窗广告 → 九宫格。 + // 点任一应用 / 关闭按钮 / 空白处 / Esc 即关闭;同一会话内容不变时不再弹出。 + var DISMISSED_KEY = "gridAdDismissed"; + var mask = document.querySelector("[data-nine-grid]"); + if (!mask) return; + + var items = Array.prototype.slice.call(mask.querySelectorAll("[data-nine-grid-item]")); + if (!items.length) return; + + var signature = JSON.stringify( + items.map(function (item) { + var image = item.querySelector("[data-nine-grid-src]"); + return [ + item.getAttribute("data-creative-id") || "", + image ? image.getAttribute("data-nine-grid-src") : "", + item.getAttribute("href") || "", + ]; + }), + ); + + function readSession(key) { + try { + return window.sessionStorage.getItem(key) || ""; + } catch (error) { + return ""; + } + } + + function writeSession(key, value) { + try { + window.sessionStorage.setItem(key, value); + } catch (error) { + // sessionStorage 不可用时仅本页关闭。 + } + } + + if (readSession(DISMISSED_KEY) === signature) return; + + function waitForImage(image) { + return new Promise(function (resolve, reject) { + if (image.complete && image.naturalWidth > 0 && image.src.indexOf("placeholder") === -1) { + resolve(); + return; + } + var timeout = window.setTimeout(function () { + cleanup(); + reject(new Error("image load timeout")); + }, 12000); + function cleanup() { + window.clearTimeout(timeout); + image.removeEventListener("load", handleLoad); + image.removeEventListener("error", handleError); + } + function handleLoad() { + cleanup(); + if (image.naturalWidth > 0) resolve(); + else reject(new Error("image decode failed")); + } + function handleError() { + cleanup(); + reject(new Error("image load failed")); + } + image.addEventListener("load", handleLoad); + image.addEventListener("error", handleError); + }); + } + + function loadIcon(image) { + var source = image.getAttribute("data-nine-grid-src") || ""; + if (!source) return Promise.reject(new Error("image source is empty")); + if (typeof window.processImage === "function") { + return window.processImage(source, image).then(function (result) { + if (!result) throw new Error("image decrypt failed"); + return waitForImage(image); + }); + } + image.src = source; + return waitForImage(image); + } + + var opened = false; + + function open() { + if (opened) return; + opened = true; + mask.hidden = false; + mask.removeAttribute("hidden"); + mask.classList.add("is-open"); + document.body.style.overflow = "hidden"; + } + + function close() { + if (!opened) return; + opened = false; + writeSession(DISMISSED_KEY, signature); + mask.classList.remove("is-open"); + mask.hidden = true; + mask.setAttribute("hidden", ""); + document.body.style.overflow = ""; + } + + // 依次等待:年龄确认关闭 → 弹窗广告队列结束(没有弹窗广告时直接放行) + function whenStartupReady(callback) { + var ageGate = document.getElementById("eightPop"); + if (ageGate && ageGate.classList.contains("is-open")) { + document.addEventListener( + "eightpop:closed", + function () { + whenStartupReady(callback); + }, + { once: true }, + ); + return; + } + var hasDialogAd = !!document.querySelector("[data-dialog-ad]"); + if (hasDialogAd && !window.__dialogAdDone) { + document.addEventListener("dialogad:done", callback, { once: true }); + return; + } + callback(); + } + + // 只展示图标加载成功的应用;一个都没加载成功则不弹 + var ready = Promise.all( + items.map(function (item) { + var image = item.querySelector("[data-nine-grid-src]"); + if (!image) return Promise.resolve(false); + return loadIcon(image) + .then(function () { + item.hidden = false; + item.removeAttribute("hidden"); + return true; + }) + .catch(function () { + return false; + }); + }), + ); + + whenStartupReady(function () { + ready.then(function (loaded) { + if (loaded.some(Boolean)) open(); + }); + }); + + mask.addEventListener("click", function (event) { + if (event.target === mask || event.target.closest("[data-nine-grid-close]") || event.target.closest("[data-nine-grid-item]")) { + close(); + } + }); + + mask.querySelector(".nine-grid-panel").addEventListener("click", function (event) { + if (event.target === event.currentTarget) close(); + }); + + document.addEventListener("keydown", function (event) { + if (event.key === "Escape" && opened) close(); + }); +})(); diff --git a/app/templates/base/contentExtras.html b/app/templates/base/contentExtras.html index c1fa744..7bede11 100644 --- a/app/templates/base/contentExtras.html +++ b/app/templates/base/contentExtras.html @@ -1,5 +1,6 @@ {{define "contentPromo"}} -{{template "squarePromo" dict "Ads" .appConfig.DetailTopList "SlotKey" "detail_top" "SlotName" "详情顶部广告" "Label" "推广内容" "PCOnly" "1"}} +{{/* 播放页小图标:后台位置 12(AList) */}} +{{template "squarePromo" dict "Ads" .appConfig.AList "SlotKey" "play_icons" "SlotName" "播放页小图标" "Label" "推广"}} {{end}} {{define "contentOfficialInfo"}} @@ -34,6 +35,7 @@ {{end}} {{end}} +{{/* 详情横幅:后台位置 3(本站字段 videoTopList),素材 720×150 */}} {{define "contentAds"}} {{if .appConfig.DetailBannerList}}
{{end}} - + {{end}} {{end}} diff --git a/app/templates/base/header.html b/app/templates/base/header.html index 06e3a4e..70ce3f3 100644 --- a/app/templates/base/header.html +++ b/app/templates/base/header.html @@ -169,4 +169,4 @@ -{{template "toast" .}} {{template "eightPop" .}} {{template "dialogAd" .}} {{end}} +{{template "toast" .}} {{template "eightPop" .}} {{template "dialogAd" .}} {{template "nineGridDialog" .}} {{end}} diff --git a/app/templates/base/homeAdRow.html b/app/templates/base/homeAdRow.html deleted file mode 100644 index e1e4bd3..0000000 --- a/app/templates/base/homeAdRow.html +++ /dev/null @@ -1,30 +0,0 @@ -{{define "homeAdRow"}} -{{$ads := .Ads}} -{{if $ads}} - - -{{end}} -{{end}} diff --git a/app/templates/base/nineGridDialog.html b/app/templates/base/nineGridDialog.html new file mode 100644 index 0000000..e49de7f --- /dev/null +++ b/app/templates/base/nineGridDialog.html @@ -0,0 +1,28 @@ +{{define "nineGridDialog"}} +{{/* 九宫格弹窗:后台位置 2(nineGridList),在年龄确认、弹窗广告之后弹出 */}} +{{if .appConfig.NineGridList}} + +
+ {{if $ad.Title}}{{$ad.Title}}{{else}}推荐应用{{end}}
+
+ {{end}}
+