diff --git a/MoviaBox/Base/Controller/SPTabBarController.swift b/MoviaBox/Base/Controller/SPTabBarController.swift index b32c02b..489d3a3 100644 --- a/MoviaBox/Base/Controller/SPTabBarController.swift +++ b/MoviaBox/Base/Controller/SPTabBarController.swift @@ -17,11 +17,13 @@ class SPTabBarController: UITabBarController { let nav2 = createNavigationController(viewController: SPExplorePageController(), title: "For You".localized, image: UIImage(named: "tabbar_icon_02"), selectedImage: UIImage(named: "tabbar_icon_02_selected")) - let nav4 = createNavigationController(viewController: SPMyListViewController(), title: "My list".localized, image: UIImage(named: "tabbar_icon_04"), selectedImage: UIImage(named: "tabbar_icon_04_selected")) + let nav3 = createNavigationController(viewController: SPMyListViewController(), title: "My list".localized, image: UIImage(named: "tabbar_icon_04"), selectedImage: UIImage(named: "tabbar_icon_04_selected")) + + let nav4 = createNavigationController(viewController: SPRewardsViewController(), title: "Rewards".localized, image: UIImage(named: "tabbar_icon_04"), selectedImage: UIImage(named: "tabbar_icon_04_selected")) let nav5 = createNavigationController(viewController: SPMineViewController(), title: "Profile".localized, image: UIImage(named: "tabbar_icon_05"), selectedImage: UIImage(named: "tabbar_icon_05_selected")) - self.viewControllers = [nav1, nav2, nav4, nav5] + self.viewControllers = [nav1, nav2, nav3, nav4, nav5] } diff --git a/MoviaBox/Base/Extension/UIColor+SPAdd.swift b/MoviaBox/Base/Extension/UIColor+SPAdd.swift index fd552e5..8e89033 100644 --- a/MoviaBox/Base/Extension/UIColor+SPAdd.swift +++ b/MoviaBox/Base/Extension/UIColor+SPAdd.swift @@ -252,5 +252,9 @@ extension UIColor { static func color0D0807(alpha: CGFloat = 1) -> UIColor { return color(hex: 0x0D0807, alpha: alpha) } + + static func colorF2C879(alpha: CGFloat = 1) -> UIColor { + return color(hex: 0xF2C879, alpha: alpha) + } } diff --git a/MoviaBox/Base/Networking/API/SPRewardsAPI.swift b/MoviaBox/Base/Networking/API/SPRewardsAPI.swift new file mode 100644 index 0000000..4ab9619 --- /dev/null +++ b/MoviaBox/Base/Networking/API/SPRewardsAPI.swift @@ -0,0 +1,25 @@ +// +// SPRewardsAPI.swift +// MoviaBox +// +// Created by 佳尔 on 2025/4/28. +// + +import UIKit + +class SPRewardsAPI: NSObject { + ///开启通知领金币 + static func requestUploadOpenNotify(completer: ((_ finish: Bool) -> Void)?) { + + var param = SPNetworkParameters(path: "openNotify") + + SPNetwork.request(parameters: param) { (response: SPNetworkResponse) in + if response.code == SPNetworkCodeSucceed { + completer?(true) + } else { + completer?(false) + } + } + } + +} diff --git a/MoviaBox/Base/Networking/API/SPVideoAPI.swift b/MoviaBox/Base/Networking/API/SPVideoAPI.swift index 1baf170..641aa01 100644 --- a/MoviaBox/Base/Networking/API/SPVideoAPI.swift +++ b/MoviaBox/Base/Networking/API/SPVideoAPI.swift @@ -10,7 +10,7 @@ import UIKit class SPVideoAPI: NSObject { ///获取视频详情 - static func requestVideoDetail(videoId: String?, shortPlayId: String, completer: ((_ model: SPVideoDetailModel?) -> Void)?) { + static func requestVideoDetail(videoId: String?, shortPlayId: String, activityId: String? = nil, completer: ((_ model: SPVideoDetailModel?) -> Void)?) { var parameters: [String : Any] = [ "short_play_id" : shortPlayId ] @@ -18,6 +18,10 @@ class SPVideoAPI: NSObject { if let videoId = videoId { parameters["video_id"] = videoId } + if let activityId = activityId { + parameters["activity_id"] = activityId + } + var param = SPNetworkParameters(path: "/getVideoDetails") param.method = .get param.parameters = parameters diff --git a/MoviaBox/Base/Networking/Base/SPURLPath.swift b/MoviaBox/Base/Networking/Base/SPURLPath.swift index 41d8fd5..35c5669 100644 --- a/MoviaBox/Base/Networking/Base/SPURLPath.swift +++ b/MoviaBox/Base/Networking/Base/SPURLPath.swift @@ -49,5 +49,7 @@ let SPFeedBackHomeWebUrl = SPCampaignWebURL + "/pages/leave/index" let SPFeedBackListWebUrl = SPCampaignWebURL + "/pages/leave/list" ///反馈详情 let SPFeedBackDetailWebUrl = SPCampaignWebURL + "/pages/leave/detail" +///活动页面 +let SPRewardsWebUrl = SPCampaignWebURL diff --git a/MoviaBox/Base/WebView/SPWebMessageModel.swift b/MoviaBox/Base/WebView/SPWebMessageModel.swift new file mode 100644 index 0000000..9efff82 --- /dev/null +++ b/MoviaBox/Base/WebView/SPWebMessageModel.swift @@ -0,0 +1,25 @@ +// +// SPWebMessageModel.swift +// MoviaBox +// +// Created by 佳尔 on 2025/4/28. +// + +import UIKit +import SmartCodable + +class SPWebMessageModel: SPModel, SmartCodable { + + var type: String? + + var data: SPWebMessageData? + +} + +struct SPWebMessageData: SmartCodable { + + var activity_id: String? + var short_play_id: String? + var link: String? + +} diff --git a/MoviaBox/Base/WebView/SPWebViewController+ScriptMessage.swift b/MoviaBox/Base/WebView/SPWebViewController+ScriptMessage.swift index afca080..de5ee0d 100644 --- a/MoviaBox/Base/WebView/SPWebViewController+ScriptMessage.swift +++ b/MoviaBox/Base/WebView/SPWebViewController+ScriptMessage.swift @@ -45,12 +45,68 @@ extension SPWebViewController { } else if name == WebMessageOpenPhotoPicker { let vc = SPImagePickerManager.createImagePicker(delegate: self) self.present(vc, animated: true) + + } else if name == WebMessageAPP { + guard let body = message.body as? [String : Any] else { return } + guard let model = SPWebMessageModel.deserialize(from: body) else { return } + let type = model.type + let data = model.data + + if type == "login" {//登录 + self.navigationController?.pushViewController(SPLoginViewController(), animated: true) + + } else if type == "open_notify" {//打开通知 + openNotify() + + } else if type == "watch_video" { //去看剧 + + let vc = SPPlayerDetailViewController() + vc.shortPlayId = data?.short_play_id + vc.activityId = data?.activity_id + self.navigationController?.pushViewController(vc, animated: true) + + } else { + guard let urlStr = data?.link else { return } + guard let url = URL(string: urlStr) else { return } + if UIApplication.shared.canOpenURL(url) { + UIApplication.shared.open(url) + } + + } + + + } } } +extension SPWebViewController { + ///打开系统通知 + func openNotify() { + UNUserNotificationCenter.current().getNotificationSettings { settings in + DispatchQueue.main.async { [weak self] in + guard let self = self else { return } + if settings.authorizationStatus != .authorized {//未开启通知打开设置 + if #available(iOS 16.0, *) { + if let url = URL(string: UIApplication.openNotificationSettingsURLString) { + UIApplication.shared.open(url) + } + } else { + if let url = URL(string: UIApplication.openSettingsURLString) { + UIApplication.shared.open(url) + } + } + } else {//开启通知上报结果 + SPRewardsAPI.requestUploadOpenNotify(completer: nil) + } + } + } + } + +} + //MARK: -------------- TZImagePickerControllerDelegate -------------- extension SPWebViewController: TZImagePickerControllerDelegate { diff --git a/MoviaBox/Base/WebView/SPWebViewController.swift b/MoviaBox/Base/WebView/SPWebViewController.swift index 52e23fc..a00dbaa 100644 --- a/MoviaBox/Base/WebView/SPWebViewController.swift +++ b/MoviaBox/Base/WebView/SPWebViewController.swift @@ -28,7 +28,7 @@ class SPWebViewController: SPViewController { override func viewDidLoad() { super.viewDidLoad() // self.edgesForExtendedLayout = .top - configNavigationBack() +// configNavigationBack() setBackgroundView(isShowGradient: false, bgImage: nil) diff --git a/MoviaBox/Class/Mine/View/SPMineHeaderView.swift b/MoviaBox/Class/Mine/View/SPMineHeaderView.swift index 7680903..d61cc4a 100644 --- a/MoviaBox/Class/Mine/View/SPMineHeaderView.swift +++ b/MoviaBox/Class/Mine/View/SPMineHeaderView.swift @@ -14,6 +14,8 @@ class SPMineHeaderView: UIView { var stackHeight = 0.0 stackHeight += memberView.intrinsicContentSize.height + + stackHeight += self.stackView.spacing stackHeight += walletView.intrinsicContentSize.height if playHistoryArr?.count ?? 0 > 0 { diff --git a/MoviaBox/Class/Player/Controller/SPPlayerDetailViewController.swift b/MoviaBox/Class/Player/Controller/SPPlayerDetailViewController.swift index 3be4808..c834acb 100644 --- a/MoviaBox/Class/Player/Controller/SPPlayerDetailViewController.swift +++ b/MoviaBox/Class/Player/Controller/SPPlayerDetailViewController.swift @@ -20,6 +20,7 @@ class SPPlayerDetailViewController: SPPlayerListViewController { var videoId: String? var shortPlayId: String? + var activityId: String? var playHistoryModel: SPShortModel? private var detailModel: SPVideoDetailModel? @@ -76,12 +77,19 @@ class SPPlayerDetailViewController: SPPlayerListViewController { } override func play() { - super.play() - if let _ = self.detailModel, - let videoInfo = self.viewModel.currentPlayer?.videoInfo - { - SPVideoAPI.requestRequestVideoPlayHistory(videoId: videoInfo.short_play_video_id ?? "", shortPlayId: videoInfo.short_play_id ?? "") + guard let videoInfo = self.viewModel.currentPlayer?.videoInfo else { return } + if videoInfo.is_lock == true { + self.pause() + + let view = SPPlayBuyView() + view.present(in: nil) + + return } + + super.play() + + SPVideoAPI.requestRequestVideoPlayHistory(videoId: videoInfo.short_play_video_id ?? "", shortPlayId: videoInfo.short_play_id ?? "") } } @@ -174,7 +182,7 @@ extension SPPlayerDetailViewController { private func requestDetailData() { guard let shortPlayId = self.shortPlayId else { return } - SPVideoAPI.requestVideoDetail(videoId: videoId, shortPlayId: shortPlayId) { [weak self] model in + SPVideoAPI.requestVideoDetail(videoId: videoId, shortPlayId: shortPlayId, activityId: activityId) { [weak self] model in guard let self = self else { return } if let model = model { self.detailModel = model diff --git a/MoviaBox/Class/Player/Controller/SPPlayerListViewController.swift b/MoviaBox/Class/Player/Controller/SPPlayerListViewController.swift index adba709..67f1d2b 100644 --- a/MoviaBox/Class/Player/Controller/SPPlayerListViewController.swift +++ b/MoviaBox/Class/Player/Controller/SPPlayerListViewController.swift @@ -112,6 +112,7 @@ class SPPlayerListViewController: SPViewController { super.viewDidAppear(animated) if getDataCount() > 0 && self.viewModel.isPlaying { self.viewModel.currentPlayer?.start() +// self.play() } } @@ -179,6 +180,11 @@ class SPPlayerListViewController: SPViewController { } } + func pause() { + self.viewModel.isPlaying = false + self.viewModel.currentPlayer?.pause() + } + func reloadData(completion: (() -> Void)? = nil) { CATransaction.setCompletionBlock { completion?() @@ -246,11 +252,14 @@ extension SPPlayerListViewController { // } if self.viewModel.isPlaying { - self.viewModel.isPlaying = false - self.viewModel.currentPlayer?.pause() + self.pause() +// self.viewModel.isPlaying = false +// self.viewModel.currentPlayer?.pause() } else { - self.viewModel.isPlaying = true - self.viewModel.currentPlayer?.start() + self.play() + +// self.viewModel.isPlaying = true +// self.viewModel.currentPlayer?.start() } } diff --git a/MoviaBox/Class/Player/View/SPEpisodeCell.swift b/MoviaBox/Class/Player/View/SPEpisodeCell.swift index 3070054..d6bd268 100644 --- a/MoviaBox/Class/Player/View/SPEpisodeCell.swift +++ b/MoviaBox/Class/Player/View/SPEpisodeCell.swift @@ -13,6 +13,8 @@ class SPEpisodeCell: SPCollectionViewCell { var videoInfoModel: SPVideoInfoModel? { didSet { textLabel.text = "\(videoInfoModel?.episode ?? "0")" + + lockImageView.isHidden = !(videoInfoModel?.is_lock ?? false) } } @@ -36,6 +38,14 @@ class SPEpisodeCell: SPCollectionViewCell { return label }() + private lazy var lockImageView: UIButton = { + let view = UIButton(type: .custom) + view.isUserInteractionEnabled = false + view.setImage(UIImage(named: "lock_icon_01"), for: .normal) + view.setBackgroundImage(UIImage(named: "lock_bg_01"), for: .normal) + return view + }() + override init(frame: CGRect) { super.init(frame: frame) @@ -56,11 +66,17 @@ extension SPEpisodeCell { private func _setupUI() { contentView.addSubview(textLabel) + contentView.addSubview(lockImageView) textLabel.snp.makeConstraints { make in make.center.equalToSuperview() } + lockImageView.snp.makeConstraints { make in + make.right.top.equalToSuperview() + } + + } diff --git a/MoviaBox/Class/Player/View/SPPlayBuyView.swift b/MoviaBox/Class/Player/View/SPPlayBuyView.swift new file mode 100644 index 0000000..e28c9cd --- /dev/null +++ b/MoviaBox/Class/Player/View/SPPlayBuyView.swift @@ -0,0 +1,43 @@ +// +// SPPlayBuyView.swift +// MoviaBox +// +// Created by 佳尔 on 2025/4/28. +// + +import UIKit + +class SPPlayBuyView: HWPanModalContentView { + + + + override init(frame: CGRect) { + super.init(frame: frame) + + self.backgroundColor = .red + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + + //MARK: HWPanModalPresentable + override func panScrollable() -> UIScrollView? { + return nil + } + + override func longFormHeight() -> PanModalHeight { + return PanModalHeightMake(.content, kSPScreenHeight * (3 / 4)) + } + + override func showDragIndicator() -> Bool { + return false + } + + override func backgroundConfig() -> HWBackgroundConfig { + let config = HWBackgroundConfig() + config.backgroundAlpha = 0.6 + return config + } +} diff --git a/MoviaBox/Class/Rewards/Controller/SPRewardsViewController.swift b/MoviaBox/Class/Rewards/Controller/SPRewardsViewController.swift new file mode 100644 index 0000000..bbd1f22 --- /dev/null +++ b/MoviaBox/Class/Rewards/Controller/SPRewardsViewController.swift @@ -0,0 +1,23 @@ +// +// SPRewardsViewController.swift +// MoviaBox +// +// Created by 佳尔 on 2025/4/28. +// + +import UIKit + +class SPRewardsViewController: SPCampaignWebViewController { + + override func viewDidLoad() { + self.urlStr = SPRewardsWebUrl + + super.viewDidLoad() + + + } + + + + +} diff --git a/MoviaBox/Source/Assets.xcassets/icon/lock_bg_01.imageset/Contents.json b/MoviaBox/Source/Assets.xcassets/icon/lock_bg_01.imageset/Contents.json new file mode 100644 index 0000000..12d6359 --- /dev/null +++ b/MoviaBox/Source/Assets.xcassets/icon/lock_bg_01.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Rectangle 85@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Rectangle 85@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MoviaBox/Source/Assets.xcassets/icon/lock_bg_01.imageset/Rectangle 85@2x.png b/MoviaBox/Source/Assets.xcassets/icon/lock_bg_01.imageset/Rectangle 85@2x.png new file mode 100644 index 0000000..c370593 Binary files /dev/null and b/MoviaBox/Source/Assets.xcassets/icon/lock_bg_01.imageset/Rectangle 85@2x.png differ diff --git a/MoviaBox/Source/Assets.xcassets/icon/lock_bg_01.imageset/Rectangle 85@3x.png b/MoviaBox/Source/Assets.xcassets/icon/lock_bg_01.imageset/Rectangle 85@3x.png new file mode 100644 index 0000000..15004e5 Binary files /dev/null and b/MoviaBox/Source/Assets.xcassets/icon/lock_bg_01.imageset/Rectangle 85@3x.png differ diff --git a/MoviaBox/Source/Assets.xcassets/icon/lock_icon_01.imageset/Contents.json b/MoviaBox/Source/Assets.xcassets/icon/lock_icon_01.imageset/Contents.json new file mode 100644 index 0000000..5c4d3b1 --- /dev/null +++ b/MoviaBox/Source/Assets.xcassets/icon/lock_icon_01.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Frame@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Frame@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MoviaBox/Source/Assets.xcassets/icon/lock_icon_01.imageset/Frame@2x.png b/MoviaBox/Source/Assets.xcassets/icon/lock_icon_01.imageset/Frame@2x.png new file mode 100644 index 0000000..af94b56 Binary files /dev/null and b/MoviaBox/Source/Assets.xcassets/icon/lock_icon_01.imageset/Frame@2x.png differ diff --git a/MoviaBox/Source/Assets.xcassets/icon/lock_icon_01.imageset/Frame@3x.png b/MoviaBox/Source/Assets.xcassets/icon/lock_icon_01.imageset/Frame@3x.png new file mode 100644 index 0000000..d39152b Binary files /dev/null and b/MoviaBox/Source/Assets.xcassets/icon/lock_icon_01.imageset/Frame@3x.png differ diff --git a/MoviaBox/Source/en.lproj/Localizable.strings b/MoviaBox/Source/en.lproj/Localizable.strings index 5bd93c9..a7765c4 100644 --- a/MoviaBox/Source/en.lproj/Localizable.strings +++ b/MoviaBox/Source/en.lproj/Localizable.strings @@ -58,6 +58,7 @@ "Stream Unlimited" = "Stream Unlimited"; "My wallet" = "My wallet"; "Store" = "Store"; +"Rewards" = "Rewards"; "kLoginAgreementText" = "By continuing, you agree to the User Agreement and Privacy Policy";