Procházet zdrojové kódy

[+] 房间Banner初始化

yanxuyao před 8 hodinami
rodič
revize
f4eab3aef8

+ 9 - 2
Lanu.xcodeproj/project.pbxproj

@@ -366,6 +366,7 @@
 				Views/Room/Base/ViewModel/Message/LNRoomUserMessage.swift,
 				Views/Room/Base/ViewModel/Message/LNRoomUserMessage.swift,
 				Views/Room/Base/ViewModel/RoomInfo/LNRoomInfo.swift,
 				Views/Room/Base/ViewModel/RoomInfo/LNRoomInfo.swift,
 				Views/Room/Base/ViewModel/Seat/LNRoomSeatItem.swift,
 				Views/Room/Base/ViewModel/Seat/LNRoomSeatItem.swift,
+				Views/Room/Base/Views/Banner/LNRoomBannerView.swift,
 				Views/Room/Base/Views/Create/LNCreateRoomPanel.swift,
 				Views/Room/Base/Views/Create/LNCreateRoomPanel.swift,
 				Views/Room/Base/Views/Create/LNRoomNameInputPanel.swift,
 				Views/Room/Base/Views/Create/LNRoomNameInputPanel.swift,
 				Views/Room/Base/Views/Gift/List/LNRoomGiftItemCell.swift,
 				Views/Room/Base/Views/Gift/List/LNRoomGiftItemCell.swift,
@@ -448,8 +449,6 @@
 		};
 		};
 		FBB67E232EC48B440070E686 /* ThirdParty */ = {
 		FBB67E232EC48B440070E686 /* ThirdParty */ = {
 			isa = PBXFileSystemSynchronizedRootGroup;
 			isa = PBXFileSystemSynchronizedRootGroup;
-			exceptions = (
-			);
 			path = ThirdParty;
 			path = ThirdParty;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
@@ -602,10 +601,14 @@
 			inputFileListPaths = (
 			inputFileListPaths = (
 				"${PODS_ROOT}/Target Support Files/Pods-Gami/Pods-Gami-resources-${CONFIGURATION}-input-files.xcfilelist",
 				"${PODS_ROOT}/Target Support Files/Pods-Gami/Pods-Gami-resources-${CONFIGURATION}-input-files.xcfilelist",
 			);
 			);
+			inputPaths = (
+			);
 			name = "[CP] Copy Pods Resources";
 			name = "[CP] Copy Pods Resources";
 			outputFileListPaths = (
 			outputFileListPaths = (
 				"${PODS_ROOT}/Target Support Files/Pods-Gami/Pods-Gami-resources-${CONFIGURATION}-output-files.xcfilelist",
 				"${PODS_ROOT}/Target Support Files/Pods-Gami/Pods-Gami-resources-${CONFIGURATION}-output-files.xcfilelist",
 			);
 			);
+			outputPaths = (
+			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
 			shellPath = /bin/sh;
 			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Gami/Pods-Gami-resources.sh\"\n";
 			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Gami/Pods-Gami-resources.sh\"\n";
@@ -641,10 +644,14 @@
 			inputFileListPaths = (
 			inputFileListPaths = (
 				"${PODS_ROOT}/Target Support Files/Pods-Gami/Pods-Gami-frameworks-${CONFIGURATION}-input-files.xcfilelist",
 				"${PODS_ROOT}/Target Support Files/Pods-Gami/Pods-Gami-frameworks-${CONFIGURATION}-input-files.xcfilelist",
 			);
 			);
+			inputPaths = (
+			);
 			name = "[CP] Embed Pods Frameworks";
 			name = "[CP] Embed Pods Frameworks";
 			outputFileListPaths = (
 			outputFileListPaths = (
 				"${PODS_ROOT}/Target Support Files/Pods-Gami/Pods-Gami-frameworks-${CONFIGURATION}-output-files.xcfilelist",
 				"${PODS_ROOT}/Target Support Files/Pods-Gami/Pods-Gami-frameworks-${CONFIGURATION}-output-files.xcfilelist",
 			);
 			);
+			outputPaths = (
+			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
 			shellPath = /bin/sh;
 			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Gami/Pods-Gami-frameworks.sh\"\n";
 			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Gami/Pods-Gami-frameworks.sh\"\n";

+ 151 - 0
Lanu/Views/Room/Base/Views/Banner/LNRoomBannerView.swift

@@ -0,0 +1,151 @@
+//
+//  LNRoomBannerView.swift
+//  Gami
+//
+//  Created by SuperC on 2026/4/9.
+//
+
+import Foundation
+import UIKit
+import SnapKit
+
+class LNRoomBannerView: UIView {
+    var onTapBanner: ((_ item: LNBannerInfoVO, _ index: Int) -> Void)?
+
+    private let pagerView = LNCyclePager()
+    private let pageControl = LNCyclePageControl()
+    private var items: [LNBannerInfoVO] = []
+    private var loading = false
+    private var loaded = false
+
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        setupViews()
+        setupPager()
+    }
+
+    required init?(coder: NSCoder) {
+        super.init(coder: coder)
+        setupViews()
+        setupPager()
+    }
+
+    func loadBanner(adSlot: Int = 2, force: Bool = false) {
+        if loading { return }
+        if loaded && !force { return }
+        loading = true
+        LNConfigManager.shared.getBannerList(adSlot: adSlot) { [weak self] list in
+            guard let self else { return }
+            self.loading = false
+            self.loaded = true
+            self.update(items: list ?? [])
+        }
+    }
+
+    func update(items: [LNBannerInfoVO]) {
+        self.items = items
+        isHidden = items.isEmpty
+        pageControl.numberOfPages = items.count
+        pageControl.currentPage = 0
+        pageControl.isHidden = items.count <= 1
+        pagerView.reloadData()
+    }
+}
+
+private extension LNRoomBannerView {
+    func setupViews() {
+        isHidden = true
+        self.backgroundColor = .clear
+
+        addSubview(pagerView)
+        pagerView.snp.makeConstraints { make in
+            make.top.leading.trailing.equalToSuperview()
+            make.bottom.equalToSuperview().offset(-12)
+        }
+
+        pagerView.addSubview(pageControl)
+        pageControl.snp.makeConstraints { make in
+            make.centerX.equalToSuperview()
+            make.bottom.equalToSuperview()
+            make.height.equalTo(4)
+        }
+    }
+
+    func setupPager() {
+        pagerView.layer.masksToBounds = true
+        pagerView.layer.cornerRadius = 16
+        pagerView.isInfiniteLoop = true
+        pagerView.autoScrollInterval = 3
+        pagerView.reloadDataNeedResetIndex = true
+        pagerView.bindPageControl(pageControl)
+
+        pagerView.register(LNRoomBannerImageCell.self, forCellWithReuseIdentifier: LNRoomBannerImageCell.className)
+        pagerView.numberOfItemsProvider = { [weak self] in
+            self?.items.count ?? 0
+        }
+        pagerView.cellProvider = { [weak self] pager, index in
+            guard let self else { return UICollectionViewCell() }
+            let cell = pager.dequeueReusableCell(
+                withReuseIdentifier: LNRoomBannerImageCell.className,
+                for: index
+            ) as! LNRoomBannerImageCell
+            cell.update(items[index])
+            return cell
+        }
+        pagerView.layoutProvider = { [weak self] in
+            let layout = LNCyclePagerViewLayout()
+            layout.itemSize = self?.pagerView.bounds.size ?? .zero
+            layout.itemSpacing = 0
+            layout.scrollDirection = .horizontal
+            layout.layoutType = .normal
+            return layout
+        }
+        pagerView.didScrollFromIndexToIndex = { [weak self] _, toIndex in
+            self?.pageControl.currentPage = toIndex
+        }
+        pagerView.didSelectItem = { [weak self] _, index in
+            guard let self, index >= 0, index < self.items.count else { return }
+            let item = self.items[index]
+            self.onTapBanner?(item, index)
+            guard !item.jump.isEmpty else { return }
+            self.pushToWebView(.init(url: item.jump))
+        }
+        
+        pageControl.pageIndicatorSize = CGSize(width: 4, height: 4)
+        pageControl.currentPageIndicatorSize = CGSize(width: 4, height: 4)
+        pageControl.pageIndicatorTintColor = .init(hex: "#FFFFFF4D")
+        pageControl.currentPageIndicatorTintColor = .white
+        pageControl.pageIndicatorSpacing = 5
+    }
+}
+
+private final class LNRoomBannerImageCell: UICollectionViewCell {
+    private let imageView = UIImageView()
+
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        contentView.layer.masksToBounds = true
+        contentView.layer.cornerRadius = 12
+
+        imageView.layer.masksToBounds = true
+        imageView.layer.cornerRadius = 16
+        imageView.contentMode = .scaleAspectFill
+        contentView.addSubview(imageView)
+        imageView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+    }
+
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    override func prepareForReuse() {
+        super.prepareForReuse()
+        imageView.image = nil
+    }
+
+    func update(_ item: LNBannerInfoVO) {
+        imageView.sd_setImage(with: URL(string: item.img))
+    }
+}