Commit bc28e536 authored by pete谢兆麟's avatar pete谢兆麟

Merge branch 'yinhe-live-1212' of...

Merge branch 'yinhe-live-1212' of http://gitlab.galaxy-immi.com/mobile-group/galaxy-iOS into yinhe-live-1212
parents a074d0a3 800b0929
......@@ -7172,7 +7172,7 @@
CODE_SIGN_ENTITLEMENTS = galaxy/galaxyTestEnv.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3;
CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = RXHYW88XR7;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
FRAMEWORK_SEARCH_PATHS = (
......@@ -7314,7 +7314,7 @@
CODE_SIGN_ENTITLEMENTS = galaxy/galaxy.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3;
CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = RXHYW88XR7;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
FRAMEWORK_SEARCH_PATHS = (
......@@ -7519,7 +7519,7 @@
CODE_SIGN_ENTITLEMENTS = galaxy/galaxyDebug.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3;
CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = RXHYW88XR7;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
FRAMEWORK_SEARCH_PATHS = (
......@@ -7566,7 +7566,7 @@
CODE_SIGN_ENTITLEMENTS = galaxy/galaxy.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3;
CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = RXHYW88XR7;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
FRAMEWORK_SEARCH_PATHS = (
......
......@@ -10,6 +10,52 @@ import ESTabBarController_swift
class YHAITabBarItemContentView: ESTabBarItemContentView {
var timer: Timer?
lazy var tipsView: UIView = {
let v = UIView()
let grayView = UIView()
grayView.backgroundColor = UIColor(hex: 0x000000, alpha: 0.6)
grayView.layer.cornerRadius = 6.0
grayView.clipsToBounds = true
v.addSubview(grayView)
let label = UILabel()
label.textColor = UIColor.white
label.textAlignment = .center
label.font = UIFont.PFSC_R(ofSize:12)
label.text = "Hi 我是港小宝,有什么需要帮助的,来找我吧~"
grayView.addSubview(label)
let arrowImgV = UIImageView(image: UIImage(named: "ai_tab_down_arrow"))
v.addSubview(arrowImgV)
arrowImgV.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.width.equalTo(24)
make.height.equalTo(6)
make.bottom.equalTo(-4)
}
label.snp.makeConstraints { make in
make.left.equalTo(15)
make.right.equalTo(-15)
make.height.equalTo(34)
make.top.bottom.equalToSuperview()
}
grayView.snp.makeConstraints { make in
make.left.equalTo(0)
make.right.equalTo(0)
make.top.equalToSuperview()
make.bottom.equalTo(arrowImgV.snp.top)
}
return v
}()
lazy var bottomTitleLabel: UILabel = {
let label = UILabel()
label.textColor = UIColor.mainTextColor
......@@ -26,29 +72,66 @@ class YHAITabBarItemContentView: ESTabBarItemContentView {
override init(frame: CGRect) {
super.init(frame: frame)
createUI()
}
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func updateLayout() {
super.updateLayout()
}
func createUI() {
self.removeSubviews()
self.addSubview(iconImgView)
self.addSubview(bottomTitleLabel)
self.addSubview(tipsView)
bottomTitleLabel.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.height.equalTo(14)
}
iconImgView.snp.makeConstraints { make in
make.width.height.equalTo(48.0)
make.bottom.equalTo(bottomTitleLabel.snp.top)
make.centerX.equalToSuperview()
}
tipsView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.bottom.equalTo(iconImgView.snp.top)
}
startTimer()
}
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
func startTimer() {
// 每隔 1 秒调用 timerFired 方法
timer = Timer.scheduledTimer(timeInterval: 5.0,
target: self,
selector: #selector(timerFired),
userInfo: nil,
repeats: false)
}
override func updateLayout() {
super.updateLayout()
@objc func timerFired() {
stopTimer()
tipsView.isHidden = true
}
// 停止定时器
func stopTimer() {
timer?.invalidate()
timer = nil
}
deinit {
// 确保在视图控制器被销毁时停止定时器
stopTimer()
}
}
......@@ -159,16 +159,7 @@ class YHAIMainChatViewController: YHBaseViewController {
var results = self.viewModel.historyMessages.map {
return $0.convertToChatMessage()
}
if !isPull {
if results.count <= 0 { // 无聊天记录时隐藏下拉组件
tableView.header = nil
} else {
tableView.es.addYHPullToRefresh {
self.getHistoryMessages(true)
}
}
}
let uuids = messages.map {
return $0.messageId
}
......
......@@ -272,43 +272,43 @@ extension YHAIRequestManager {
UserDefaults.standard.synchronize()
}
func getSubRobotChatConversationId(robotId: String, completion:((String)->())?) {
func getSubRobotChatConversationId(listItemId: String, completion:((String)->())?) {
let localConversationId = getLobalSubRobotConversationId(robotId: robotId)
let localConversationId = getLobalSubRobotConversationId(listItemId: listItemId)
if !localConversationId.isEmpty {
completion?(localConversationId)
return
}
self.viewModel.requestConversationId { sessionId in
self.saveLobalSubRobotConversationId(sessionId, robotId: robotId)
self.saveLobalSubRobotConversationId(sessionId, listItemId: listItemId)
completion?(sessionId)
}
}
func getLobalSubRobotConversationId(robotId: String) -> String {
func getLobalSubRobotConversationId(listItemId: String) -> String {
let userId = YHLoginManager.shared.userModel?.id ?? ""
let key = Self.subrobotConversationConfigKey + userId
if let dict = UserDefaults.standard.dictionary(forKey: key) {
if let conversationId = dict["\(robotId)"] as? String, !conversationId.isEmpty {
if let conversationId = dict["\(listItemId)"] as? String, !conversationId.isEmpty {
return conversationId
}
}
return ""
}
func saveLobalSubRobotConversationId(_ converId: String, robotId: String) {
func saveLobalSubRobotConversationId(_ converId: String, listItemId: String) {
let userId = YHLoginManager.shared.userModel?.id ?? ""
let key = Self.subrobotConversationConfigKey + userId
var dict:[String : Any] = [:]
if let config = UserDefaults.standard.dictionary(forKey: key) {
dict = config
}
dict["\(robotId)"] = converId
dict["\(listItemId)"] = converId
UserDefaults.standard.set(dict, forKey: key)
UserDefaults.standard.synchronize()
}
func clearLobalSubRobotConversationIdForRobotId(_ robotId: String) {
saveLobalSubRobotConversationId("", robotId: robotId)
func clearLobalSubRobotConversationIdForListItemId(_ listItemId: String) {
saveLobalSubRobotConversationId("", listItemId: listItemId)
}
}
......@@ -14,11 +14,12 @@ class YHAIRobotChatViewController: YHBaseViewController {
var myTitle: String = ""
var robotId: String = ""
var listItemId: Int = 0
var conversationId: String = ""
var messages:[YHAIChatMessage] = []
var historyLastMessageId: String = ""
var isNeedShowBannerHeader: Bool = false
var robotType: Int = 0
var robotType: String = ""
let manager = YHAIRequestManager()
let viewModel = YHAIViewModel()
......@@ -178,17 +179,7 @@ class YHAIRobotChatViewController: YHBaseViewController {
var results = self.viewModel.historyMessages.map {
return $0.convertToChatMessage()
}
if !isPull {
if results.count <= 0 { // 无聊天记录时隐藏下拉组件
tableView.header = nil
} else {
tableView.es.addYHPullToRefresh {
self.getHistoryMessages(true)
}
}
}
let uuids = messages.map {
return $0.messageId
}
......@@ -215,11 +206,11 @@ class YHAIRobotChatViewController: YHBaseViewController {
YHCommonAlertView.show("删除历史记录", "删除后记录无法恢复", "取消", "删除", fullGuestureEnable: false) {
} callBack: {
self.manager.clearLobalSubRobotConversationIdForRobotId(self.robotId)
self.manager.clearLobalSubRobotConversationIdForListItemId("\(self.listItemId)")
self.viewModel.requestConversationId { sessionId in
if !sessionId.isEmpty {
self.conversationId = sessionId
self.manager.saveLobalSubRobotConversationId(sessionId, robotId: self.robotId)
self.manager.saveLobalSubRobotConversationId(sessionId, listItemId: "\(self.listItemId)")
self.messages.removeAll()
self.tableView.reloadData()
YHHUD.flash(message: "清除成功")
......@@ -230,15 +221,38 @@ class YHAIRobotChatViewController: YHBaseViewController {
func getFlowMessages() -> [String] {
if robotType == YHAYRobotType.education.rawValue {
if robotType == YHAIRobotType.education.rawValue {
return ["香港教育有哪些优势?", "去香港读书有哪些条件?", "申请香港学校费用是多少?", "了解银河教育插班服务流程", "了解银河教育插班录取率"]
} else if robotType == YHAYRobotType.sale.rawValue {
} else if robotType == YHAIRobotType.sale.rawValue {
return ["优才学历加分要求是什么?", "优才现在要怎么申请?", "墨尔本大学是优才合资格大学吗?", "推荐一些优才产品"]
}
return []
}
func getHeaderTitle() -> String {
if robotType == YHAIRobotType.education.rawValue {
return "Hello,我是香港教育宝"
} else if robotType == YHAIRobotType.sale.rawValue {
return "Hello,我是新港生活规划师"
}
return ""
}
func getHeaderDesc() -> String {
if robotType == YHAIRobotType.education.rawValue {
return "有香港教育的问题尽管问我"
} else if robotType == YHAIRobotType.sale.rawValue {
return "香港身份办理问题可以找我"
}
return ""
}
}
extension YHAIRobotChatViewController: UITableViewDelegate, UITableViewDataSource {
......@@ -344,6 +358,8 @@ extension YHAIRobotChatViewController: UITableViewDelegate, UITableViewDataSourc
}
let view = YHAIChatBannerView()
view.titleLabel.text = getHeaderTitle()
view.descLabel.text = getHeaderDesc()
view.bannerArr = self.getBannerForRobotType(robotType)
view.messages = getFlowMessages()
view.selectFlowMsgBlock = {
......@@ -367,14 +383,15 @@ extension YHAIRobotChatViewController: UITableViewDelegate, UITableViewDataSourc
return view
}
func getBannerForRobotType(_ robotType: Int) -> [YHAIChatBannerItem] {
if robotType == YHAYRobotType.sale.rawValue {
func getBannerForRobotType(_ robotType: String) -> [YHAIChatBannerItem] {
if robotType == YHAIRobotType.sale.rawValue {
return [YHAIChatBannerItem(id: 0, title: "了解银河集团", desc: "香港身份生活一站式服务平台", msg: "银河集团,能够为我提供什么?"),
YHAIChatBannerItem(id: 1, title: "香港身份智能评估", desc: "60s快速评估,了解自身条件是否符合", msg: "开始身份办理评估"),
YHAIChatBannerItem(id: 2, title: "银河产品矩阵", desc: "香港身份、生活多样产品", msg: "介绍一下银河的产品"),]
}
if robotType == YHAYRobotType.education.rawValue {
if robotType == YHAIRobotType.education.rawValue {
return [YHAIChatBannerItem(id: 0, title: "幼中小学升学", desc: "去香港插班需要考核哪些"),
YHAIChatBannerItem(id: 1, title: "大学升学", desc: "DSE分数和Alevel的换算关系"),
YHAIChatBannerItem(id: 2, title: "银河教育服务", desc: "银河教育插班成功率如何?"),]
......
......@@ -150,7 +150,7 @@ extension YHAIServiceListViewController: UICollectionViewDelegate, UICollectionV
}
} else if model.redirectMode == 2 {
// customerVoice -> APP客户心声 productList -> APP-首页银河甄选
// customerVoice -> APP客户心声 productList -> APP-首页银河甄选 AppServiceTab -> 服务页
if model.redirectPath == YHAIJumpPageType.customerHeart.rawValue {
//客户心声
let vc = YHOtherServiceViewController()
......@@ -162,19 +162,32 @@ extension YHAIServiceListViewController: UICollectionViewDelegate, UICollectionV
let vc = YHSelectViewController()
vc.hideFlag = false
UIViewController.current?.navigationController?.pushViewController(vc, animated: true)
} else if model.redirectPath == YHAIJumpPageType.appServiceTab.rawValue {
// 服务页
UIViewController.current?.navigationController?.popToRootViewController(animated: true)
goTabBarBy(tabType: .service)
}
} else if model.redirectMode == 3 { // agent
self.manager.getSubRobotChatConversationId(robotId: model.redirectPath) {
sesseionId in
let vc = YHAIRobotChatViewController()
vc.isNeedShowBannerHeader = model.isNeedShowBannerHeader()
vc.myTitle = model.title
vc.robotId = model.redirectPath
vc.conversationId = sesseionId
vc.robotType = model.botType
self.navigationController?.pushViewController(vc, animated: true)
if model.businessType == YHAIRobotType.main.rawValue {
// 切到主Robot
NotificationCenter.default.post(name: YhConstant.YhNotification.didSwitchToAIChatNotification, object: nil)
} else {
self.manager.getSubRobotChatConversationId(listItemId: "\(model.id)") {
sesseionId in
let vc = YHAIRobotChatViewController()
vc.isNeedShowBannerHeader = model.isNeedShowBannerHeader()
vc.myTitle = model.title
vc.robotId = model.redirectPath
vc.listItemId = model.id
vc.conversationId = sesseionId
vc.robotType = model.businessType
self.navigationController?.pushViewController(vc, animated: true)
}
}
}
}
......
......@@ -19,10 +19,10 @@ class YHAIListModel: SmartCodable {
}
}
enum YHAYRobotType: Int {
case house = 1
case education = 2
case sale = 3
enum YHAIRobotType: String {
case main = "mainBot"
case education = "educationBot"
case sale = "saleBot"
}
class YHEntranceconfigModel: SmartCodable {
......@@ -34,11 +34,11 @@ class YHEntranceconfigModel: SmartCodable {
var description: String = ""
var btnText: String = ""
var redirectMode: Int = 0
var botType: Int = 0 // 1:房产 2:教育 3:销售
var businessType: String = ""
var redirectPath: String = ""
func isNeedShowBannerHeader() -> Bool {
if botType == YHAYRobotType.education.rawValue || botType == YHAYRobotType.sale.rawValue {
if businessType == YHAIRobotType.education.rawValue || businessType == YHAIRobotType.sale.rawValue {
return true
}
return false
......
......@@ -229,8 +229,10 @@ class YHAIMessageBody: SmartCodable {
}
enum YHAIJumpPageType: String {
// customerVoice -> APP客户心声 productList -> APP-首页银河甄选 AppServiceTab -> 服务页
case customerHeart = "customerVoice" // APP客户心声
case galaxySelect = "productList" // APP-首页银河甄选
case appServiceTab = "AppServiceTab" // 服务页
}
class YHAIListInfoModel: SmartCodable {
......
......@@ -26,6 +26,7 @@ class YHAIChatBannerItemCell: FSPagerViewCell {
visualEffectView.colorTint = UIColor(hex: 0xAFAFAF).withAlphaComponent(0.15)
visualEffectView.blurRadius = 16
visualEffectView.scale = 1
visualEffectView.isHidden = true
return visualEffectView
}()
......
......@@ -37,27 +37,28 @@ class YHAIChatBannerView: UIView {
}
}
lazy var bgImgV: UIImageView = {
let imagV : UIImageView = UIImageView()
imagV.contentMode = .scaleAspectFill
imagV.clipsToBounds = true
imagV.image = UIImage(named: "ai_chat_header_bg")
return imagV
lazy var titleLabel: UILabel = {
let lable = UILabel()
lable.font = UIFont.PFSC_R(ofSize: 12)
lable.textColor = UIColor.init(hex: 0x6D788A)
lable.text = "Hello,我是新港生活规划师"
return lable
}()
lazy var rolerImgV: UIImageView = {
let imagV : UIImageView = UIImageView()
imagV.contentMode = .scaleAspectFill
imagV.clipsToBounds = true
imagV.image = UIImage(named: "ai_chat_header_role")
return imagV
lazy var descLabel: UILabel = {
let lable = UILabel()
lable.font = UIFont.PFSC_B(ofSize: 15)
lable.textColor = UIColor.mainTextColor
lable.text = "需要香港身份办理找我~"
return lable
}()
lazy var arrowImgV: UIImageView = {
lazy var bgImgV: UIImageView = {
let imagV : UIImageView = UIImageView()
imagV.contentMode = .scaleAspectFill
imagV.clipsToBounds = true
imagV.image = UIImage(named: "ai_chat_heaer_banner_arrow")
imagV.image = UIImage(named: "ai_chat_header_bg")
imagV.isUserInteractionEnabled = true
return imagV
}()
......@@ -130,10 +131,10 @@ class YHAIChatBannerView: UIView {
func createUI() {
addSubview(bgImgV)
addSubview(rolerImgV)
addSubview(bannerView)
bgImgV.addSubview(titleLabel)
bgImgV.addSubview(descLabel)
bgImgV.addSubview(bannerView)
bannerView.addSubview(indicatorView)
bannerView.addSubview(arrowImgV)
bgImgV.snp.makeConstraints { make in
make.top.equalTo(0)
......@@ -142,34 +143,32 @@ class YHAIChatBannerView: UIView {
make.height.equalTo(242)
}
rolerImgV.snp.makeConstraints { make in
make.top.equalTo(0)
make.right.equalTo(-10)
make.width.equalTo(200)
make.height.equalTo(180)
titleLabel.snp.makeConstraints { make in
make.top.equalTo(57)
make.left.equalTo(20)
make.height.equalTo(20)
}
descLabel.snp.makeConstraints { make in
make.top.equalTo(titleLabel.snp.bottom)
make.left.equalTo(20)
make.height.equalTo(24)
}
bannerView.snp.makeConstraints { make in
make.bottom.equalTo(bgImgV)
make.left.equalTo(22)
make.right.equalTo(-22)
make.left.equalTo(0)
make.right.equalTo(0)
make.height.equalTo(YHAIChatBannerView.bannersHeight)
}
indicatorView.snp.makeConstraints { make in
make.left.right.equalToSuperview()
make.height.equalTo(2)
make.bottom.equalTo(-14)
make.bottom.equalTo(-16)
}
bannerView.reloadData()
arrowImgV.snp.makeConstraints { make in
make.right.equalTo(-20)
make.width.equalTo(12)
make.height.equalTo(4)
make.bottom.equalTo(-40)
}
addSubview(collectionView)
collectionView.snp.makeConstraints { make in
make.left.equalTo(20)
......
......@@ -17,9 +17,9 @@ class YHAIProductCell: UICollectionViewCell {
titleLabel.text = model.title
subtitleLabel.text = model.description
if !model.btnText.isEmpty {
blackButton.setTitle(model.btnText, for: .normal)
blackTitleLabel.text = model.btnText
} else {
blackButton.setTitle("去了解", for: .normal)
blackTitleLabel.text = "去了解"
}
bgImgView.sd_setImage(with: URL(string: model.cover), placeholderImage: UIImage(named: "ai_product_bg_default"))
}
......@@ -48,22 +48,31 @@ class YHAIProductCell: UICollectionViewCell {
return lable
}()
lazy var blackButton: UIButton = {
let btn = UIButton(type: .custom)
btn.setTitle("去了解", for: .normal)
btn.setTitleColor(.white, for: .normal)
btn.titleLabel?.font = .PFSC_M(ofSize: 11)
btn.backgroundColor = .black
btn.addTarget(self, action: #selector(didSendButtonClicked), for: .touchUpInside)
btn.YH_clickEdgeInsets = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
btn.layer.cornerRadius = 13.0
btn.clipsToBounds = true
return btn
lazy var blackView: UIView = {
let v = UIView()
v.backgroundColor = .black
v.layer.cornerRadius = 13.0
v.clipsToBounds = true
v.layer.allowsEdgeAntialiasing = true
v.addSubview(blackTitleLabel)
blackTitleLabel.snp.makeConstraints { make in
make.left.equalTo(10)
make.right.equalTo(-10)
make.top.bottom.equalToSuperview()
}
return v
}()
@objc func didSendButtonClicked() {
}
lazy var blackTitleLabel: UILabel = {
let lable = UILabel()
lable.textColor = UIColor.white
lable.textAlignment = .left
lable.font = UIFont.PFSC_M(ofSize: 11)
lable.text = "去了解"
return lable
}()
required init?(coder: NSCoder) {
super.init(coder: coder)
......@@ -82,7 +91,7 @@ class YHAIProductCell: UICollectionViewCell {
contentView.addSubview(bgImgView)
bgImgView.addSubview(titleLabel)
bgImgView.addSubview(subtitleLabel)
bgImgView.addSubview(blackButton)
bgImgView.addSubview(blackView)
bgImgView.snp.makeConstraints { make in
make.left.equalTo(0)
......@@ -101,14 +110,14 @@ class YHAIProductCell: UICollectionViewCell {
subtitleLabel.snp.makeConstraints { make in
make.left.equalTo(22)
make.right.equalTo(-22)
make.bottom.equalTo(blackButton.snp.top).offset(-12)
make.bottom.equalTo(blackView.snp.top).offset(-12)
}
blackButton.snp.makeConstraints { make in
blackView.snp.makeConstraints { make in
make.left.equalTo(22)
make.bottom.equalTo(-24)
make.height.equalTo(26)
make.width.equalTo(54)
make.right.lessThanOrEqualTo(-22)
}
}
......
......@@ -48,7 +48,13 @@ class YHAIJumpPageTool {
let vc = YHSelectViewController()
vc.hideFlag = false
UIViewController.current?.navigationController?.pushViewController(vc, animated: true)
} else if path == YHAIJumpPageType.appServiceTab.rawValue {
// 服务页
UIViewController.current?.navigationController?.popToRootViewController(animated: true)
goTabBarBy(tabType: .service)
}
} else if mode == 3 {
}
......
......@@ -28,10 +28,15 @@ class YHHomePageViewController: YHBaseViewController {
var homeHeaderViewHeight : CGFloat = 0.0
private var isGoYHManagerFlag : Bool = false
private var didShowFloating : Bool = false
var configModel: YHHomeInfoModel? {
didSet {
homeHeaderView.kingModel = configModel?.king_kong_list ?? []
if let live_info = configModel?.live_info {
setupLiveFloating(liveInfo: live_info)
}
}
}
......@@ -112,6 +117,16 @@ class YHHomePageViewController: YHBaseViewController {
//MARK: - 私有方法
private extension YHHomePageViewController {
private func setupLiveFloating(liveInfo: YHHomeLiveInfoModel) {
printLog("#####setupLiveFloating(liveInfo: YHHomeLiveInfoModel) ")
guard !didShowFloating else {
return
}
didShowFloating = true
let playbackInfo = YHPlayerManager.PlaybackInfo(id: liveInfo.id, token: liveInfo.token, channelId: liveInfo.rtmp_channel, uid: UInt(liveInfo.id), isLive: true, scene: .floating, playerType: .main)
YHPlayerManager.shared.enterFloating(from: nil, playbackInfo: playbackInfo)
}
func gotoMgrVC() {
if self.isGoYHManagerFlag {
return
......
......@@ -288,7 +288,7 @@ extension YHLifeViewController: UICollectionViewDelegate, UICollectionViewDataSo
return
}
let item = self.viewModel.liveArr[indexPath.row]
let playbackInfo = YHPlayerManager.PlaybackInfo(id: item.id, url: item.pull_url, title: item.live_title, roomId: item.room_id, uid: UInt(item.id), isLive: true, scene: .fullscreen)
let playbackInfo = YHPlayerManager.PlaybackInfo(id: item.id, url: nil, title: item.live_title, roomId: item.room_id, uid: UInt(item.id), isLive: true, scene: .fullscreen)
YHPlayerManager.shared.enterLive(from: nil, playbackInfo: playbackInfo)
}
}
......
......@@ -24,7 +24,7 @@ class YHBannerModel: SmartCodable {
var live_type: Int = 0 // 播放类型:1 展示最新直播,2指定直播,3 指定录播
var live_pull_url: String = "" //直播拉流链接
var video_url: String = "" //视频链接
var recorded_cate_id: Int = 0 //录播分类ID
var recorded_video_id: Int = 0 //录播分类ID
var app_id: String = "" //声网直播
var token: String = "" //声网直播
var rtmp_channel: String = "" //声网直播
......
......@@ -57,7 +57,10 @@ class YHHomeTabInfoModel : SmartCodable {
class YHHomeLiveInfoModel : SmartCodable {
var id: Int = 0
var status: Int = 0
var pull_url: Int = 0
var app_id: String = ""
var token: String = ""
var rtmp_channel: String = ""
var img_url: String = ""
required init() {
}
}
......@@ -25,11 +25,8 @@ class YHHomeBannerView: UIView {
// 指定显示图片为第一个
bannerView.selectItem(at: 0, animated: false)
let noNeedAutoScroll = dataArr.contains(where: {
$0.skip_type == 100 || $0.skip_type == 102
$0.skip_type == 100
})
// // TODO: - alex测试
// noNeedAutoScroll = true
// // TODO: - alex测试
// 开启定时器开始滚动
bannerView.automaticSlidingInterval = noNeedAutoScroll ? 0 : bannerSildingInterval
bannerView.removesInfiniteLoopForSingleItem = true
......@@ -146,14 +143,6 @@ extension YHHomeBannerView: FSPagerViewDataSource, FSPagerViewDelegate {
if model.isLocalItemFlag {
return
}
// // TODO: - alex测试
// if index == 1 {
// let cell: YHHomeBannerCollectionViewCell? = pagerView.cellForItem(at: index) as? YHHomeBannerCollectionViewCell
// let playbackInfo = YHPlayerManager.PlaybackInfo(id: 40, url: "https://pull-flv-f1-admin.douyincdn.com/thirdgame/stream-7443723341506054922_md.flv?keeptime=00093a80&wsSecret=cf2c048a5bceb7669e37b229e807c0e2&wsTime=674d82e7&major_anchor_level=common&abr_pts=-800&select_mode=score&_session_id=037-2024120217503167B9DF9F03DF6401DE50.1733133032147.26047&rsi=1", title: nil, roomId: nil, isLive: true, scene: .fullscreen)
// YHPlayerManager.shared.enterLive(from: cell?.bannerImagV, playbackInfo: playbackInfo)
// return
// }
// // TODO: - alex测试
switch model.skip_type {
case 1: //跳转H5
if model.skip_url.isEmpty == false {
......@@ -244,11 +233,15 @@ extension YHHomeBannerView: FSPagerViewDataSource, FSPagerViewDelegate {
// live_type 播放类型:1 展示最新直播,2指定直播,3 指定录播
// live_pull_url 直播拉流链接
// video_url 视频链接
// recorded_cate_id 录播分类id token: String? = nil, channelId
// recorded_video_id 录播id token: String? = nil, channelId
if !checkLogin() {
return
}
let cell: YHHomeBannerCollectionViewCell? = pagerView.cellForItem(at: index) as? YHHomeBannerCollectionViewCell
if let player = YHPlayerManager.shared.getPlayer(.secondary) {
YHPlayerManager.shared.leaveChannel(for: player)
player.clearPlayerView()
}
let playbackInfo = YHPlayerManager.PlaybackInfo(id: model.live_id, url: model.live_pull_url, title: nil, roomId: nil, token: model.token, channelId: model.rtmp_channel, uid: UInt(model.live_id), isLive: true, scene: .fullscreen)
YHPlayerManager.shared.enterLive(from: cell?.bannerImagV, playbackInfo: playbackInfo)
printLog("跳转直播")
......@@ -257,14 +250,22 @@ extension YHHomeBannerView: FSPagerViewDataSource, FSPagerViewDelegate {
if !checkLogin() {
return
}
if let player = YHPlayerManager.shared.getPlayer(.secondary) {
player.stop()
player.clearPlayerView()
}
let cell: YHHomeBannerCollectionViewCell? = pagerView.cellForItem(at: index) as? YHHomeBannerCollectionViewCell
let playbackInfo = YHPlayerManager.PlaybackInfo(id: model.live_id, url: model.video_url, title: nil, roomId: nil, uid: nil, isLive: false, scene: .fullscreen)
let playbackInfo = YHPlayerManager.PlaybackInfo(id: model.recorded_video_id, url: model.video_url, title: nil, roomId: nil, uid: nil, isLive: false, scene: .fullscreen)
YHPlayerManager.shared.enterVOD(from: cell?.bannerImagV, playbackInfo: playbackInfo)
case 102://图片直播
printLog("跳转录播")
if !checkLogin() {
return
}
if let player = YHPlayerManager.shared.getPlayer(.secondary) {
YHPlayerManager.shared.leaveChannel(for: player)
player.clearPlayerView()
}
let cell: YHHomeBannerCollectionViewCell? = pagerView.cellForItem(at: index) as? YHHomeBannerCollectionViewCell
let playbackInfo = YHPlayerManager.PlaybackInfo(id: model.live_id, url: model.live_pull_url, title: nil, roomId: nil, token: model.token, channelId: model.rtmp_channel, uid: UInt(model.live_id), isLive: true, scene: .fullscreen)
YHPlayerManager.shared.enterLive(from: cell?.bannerImagV, playbackInfo: playbackInfo)
......@@ -294,32 +295,17 @@ extension YHHomeBannerView: FSPagerViewDataSource, FSPagerViewDelegate {
if model.isLocalItemFlag {
return
}
// // TODO: - alex测试
// if let cell = cell as? YHHomeBannerCollectionViewCell {
// if index == 1 {
//
// let playbackInfo = YHPlayerManager.PlaybackInfo(id: 40, url: "https://pull-flv-f1-admin.douyincdn.com/thirdgame/stream-7443723341506054922_md.flv?keeptime=00093a80&wsSecret=cf2c048a5bceb7669e37b229e807c0e2&wsTime=674d82e7&major_anchor_level=common&abr_pts=-800&select_mode=score&_session_id=037-2024120217503167B9DF9F03DF6401DE50.1733133032147.26047&rsi=1", title: nil, roomId: nil, isLive: true, scene: .banner)
// YHPlayerManager.shared.enterBanner(playbackInfo: playbackInfo, inView: cell.bannerImagV)
//
// } else {
// let player = YHPlayerManager.shared.getPlayer(.secondary)
// player?.setPlayView(nil)
// }
// return
// }
// // TODO: - alex测试
if model.skip_url.isEmpty == false {
if let cell = cell as? YHHomeBannerCollectionViewCell {
if model.skip_type == 100 || model.skip_type == 102 {
YHPlayerManager.shared.play(url: model.live_pull_url, inView: cell.bannerImagV, title: nil, type: .secondary)
let playbackInfo = YHPlayerManager.PlaybackInfo(id: model.live_id, url: model.live_pull_url, title: nil, roomId: nil, isLive: true, scene: .banner)
YHPlayerManager.shared.enterBanner(playbackInfo: playbackInfo, inView: cell.bannerImagV)
} else {
let player = YHPlayerManager.shared.getPlayer(.secondary)
player?.setPlayView(nil)
if let cell = cell as? YHHomeBannerCollectionViewCell {
if model.skip_type == 100 {
let playbackInfo = YHPlayerManager.PlaybackInfo(id: model.live_id, token: model.token, channelId: model.rtmp_channel, uid: UInt(model.live_id), isLive: true, scene: .banner, playerType: .secondary)
YHPlayerManager.shared.enterBanner(playbackInfo: playbackInfo, inView: cell.bannerImagV)
} else {
if let player = YHPlayerManager.shared.getPlayer(.secondary) {
YHPlayerManager.shared.leaveChannel(for: player)
player.clearPlayerView()
}
}
}
}
......@@ -331,15 +317,13 @@ extension YHHomeBannerView: FSPagerViewDataSource, FSPagerViewDelegate {
if model.isLocalItemFlag {
return
}
// // TODO: - alex测试
// if index == 1 {
// YHPlayerManager.shared.stop(type: .secondary)
// return
// }
// // TODO: - alex测试
if model.skip_url.isEmpty == false {
if model.skip_type == 100 || model.skip_type == 102 {
YHPlayerManager.shared.stop(type: .secondary)
if let player = YHPlayerManager.shared.getPlayer(.secondary) {
YHPlayerManager.shared.leaveChannel(for: player)
player.clearPlayerView()
}
}
}
}
......
......@@ -118,7 +118,7 @@ extension YHSelectLookView: UICollectionViewDelegate, UICollectionViewDataSource
return
}
let item = items[indexPath.row]
let playbackInfo = YHPlayerManager.PlaybackInfo(id: item.id, url: item.pull_url, title: item.live_title, roomId: item.room_id, uid: UInt(item.id), isLive: true, scene: .fullscreen)
let playbackInfo = YHPlayerManager.PlaybackInfo(id: item.id, url: nil, title: item.live_title, roomId: item.room_id, uid: UInt(item.id), isLive: true, scene: .fullscreen)
YHPlayerManager.shared.enterLive(from: nil, playbackInfo: playbackInfo)
}
}
......
......@@ -626,7 +626,7 @@ extension YHJsApi {
let playbackInfo = YHPlayerManager.PlaybackInfo(id: id.intValue(), isLive: true)
YHPlayerManager.shared.enterLive(from: nil, playbackInfo: playbackInfo)
} else if type == 2 {
let playbackInfo = YHPlayerManager.PlaybackInfo(id: id.intValue(), isLive: false)
let playbackInfo = YHPlayerManager.PlaybackInfo(id: id.intValue(), isLive: false, needHideZoomButton: true)
YHPlayerManager.shared.enterVOD(from: nil, playbackInfo: playbackInfo)
}
......
......@@ -184,10 +184,10 @@ class YHLivePlayerViewController: YHBasePlayerViewController {
playbackInfo?.channelId = liveDetail.rtmp_channel
playbackInfo?.token = liveDetail.token
playbackInfo?.title = liveDetail.live_title
messageListView.anchorName = liveDetail.hxNickname
if needJoinLiveChannel {
if !liveDetail.rtmp_channel.isEmpty, !liveDetail.token.isEmpty, let uid = playbackInfo?.uid, let player = player {
player.setPlayView(playerView)
YHPlayerManager.shared.joinChannel(for: player, token: liveDetail.token, channelId: liveDetail.rtmp_channel, uid: uid)
YHPlayerManager.shared.joinChannel(for: player, token: liveDetail.token, channelId: liveDetail.rtmp_channel, uid: uid, view: playerView)
} else if currentPlayingURL == nil, !liveDetail.pullUrl.isEmpty {
play(url: liveDetail.pullUrl) // 如果没有预设URL,使用接口返回的URL播放
}
......@@ -245,7 +245,6 @@ class YHLivePlayerViewController: YHBasePlayerViewController {
func play(url: String, title: String? = nil) {
currentPlayingURL = url
currentVideoTitle = title
// controlView.setTitle(title ?? "")
YHPlayerManager.shared.play(url: url, inView: playerView, title: title)
}
......
......@@ -16,7 +16,7 @@ class YHMainChannelDelegate: NSObject, AgoraRtcEngineDelegate {
weak var player: YHPlayer?
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) {
printLog("main channel: local user join room \(channelId ?? ""): \(uid) \(elapsed)ms")
printLog("$$$$###main channel: local user join room \(channelId ?? ""): \(uid) \(elapsed)ms")
}
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) {
......@@ -24,7 +24,7 @@ class YHMainChannelDelegate: NSObject, AgoraRtcEngineDelegate {
let player = player,
let view = player.currentPlayView else { return }
printLog("main channel: remote user join room \(channelId): \(uid) \(elapsed)ms")
printLog("$$$$###main channel: remote user join room \(channelId): \(uid) \(elapsed)ms")
let videoCanvas = AgoraRtcVideoCanvas()
videoCanvas.uid = uid
......@@ -34,7 +34,7 @@ class YHMainChannelDelegate: NSObject, AgoraRtcEngineDelegate {
}
func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) {
printLog("main channel: remote user left: \(uid) reason \(reason)")
printLog("$$$$###main channel: remote user left: \(uid) reason \(reason)")
let videoCanvas = AgoraRtcVideoCanvas()
videoCanvas.uid = uid
......@@ -42,6 +42,17 @@ class YHMainChannelDelegate: NSObject, AgoraRtcEngineDelegate {
videoCanvas.renderMode = .hidden
engine.setupRemoteVideo(videoCanvas)
}
func rtcEngine(_ engine: AgoraRtcEngineKit, videoSizeChangedOf sourceType: AgoraVideoSourceType, uid: UInt, size: CGSize, rotation: Int) {
printLog("$$$$###videoSizeChangedOf: \(size)")
if let player = player {
player.delegate?.player(player, didReceiveVideoSize: size)
}
}
func rtcEngine(_ engine: AgoraRtcEngineKit, firstRemoteVideoFrameOfUid uid: UInt, size: CGSize, elapsed: Int) {
printLog("$$$$###firstRemoteVideoFrameOfUid: \(size)")
}
}
class YHSecondaryChannelDelegate: NSObject, AgoraRtcEngineDelegate {
......@@ -86,4 +97,15 @@ class YHSecondaryChannelDelegate: NSObject, AgoraRtcEngineDelegate {
connection.localUid = player.currentUid ?? 0
engine.setupRemoteVideoEx(videoCanvas, connection: connection)
}
func rtcEngine(_ engine: AgoraRtcEngineKit, videoSizeChangedOf sourceType: AgoraVideoSourceType, uid: UInt, size: CGSize, rotation: Int) {
printLog("$$$$###videoSizeChangedOf: \(size)")
if let player = player {
player.delegate?.player(player, didReceiveVideoSize: size)
}
}
func rtcEngine(_ engine: AgoraRtcEngineKit, firstRemoteVideoFrameOfUid uid: UInt, size: CGSize, elapsed: Int) {
printLog("###firstRemoteVideoFrameOfUid: \(size)")
}
}
......@@ -42,7 +42,7 @@ class YHVODPlayerViewController: YHBasePlayerViewController {
func play(url: String, title: String? = nil) {
currentPlayingURL = url
currentVideoTitle = title
YHPlayerManager.shared.play(url: url, inView: playerView, title: title)
YHPlayerManager.shared.play(url: url, inView: playerView, title: title, isLive: false)
}
// MARK: - Lifecycle
......@@ -73,6 +73,7 @@ class YHVODPlayerViewController: YHBasePlayerViewController {
topBarView.shareButtonClickEvent = { [weak self] in
self?.shareLive()
}
topBarView.hideZoomButton(playbackInfo?.needHideZoomButton == true)
}
func enterFloating() {
......@@ -142,7 +143,7 @@ class YHVODPlayerViewController: YHBasePlayerViewController {
return
}
let item = detail.recordedVideoSlice[index]
self?.player?.seek(to: item.start_second * 1000)
self?.player?.seek(to: item.start_second * 1000 + 1)
}
// 时间改变回调
progressControl.onTimeChanged = { [weak self] time in
......
......@@ -14,7 +14,7 @@ class YHLiveDetailModel: SmartCodable {
var avatar: String = ""
var hxNickname: String = ""
var hxUid: String = ""
var access_num: Int = 0
var access_num: String = ""
var tips: String = ""
// 1:直播中 2:未直播 0:未知状态 3:结束直播
var status: Int = 0
......
......@@ -12,7 +12,7 @@ import SmartCodable
class YHRecordedDetailModel: SmartCodable {
var account: String = ""
var avatar: String = ""
var access_num: Int = 0
var access_num: String = ""
var tips: String = ""
var recorded_url: String = ""
var recorded_image: String = ""
......
......@@ -6,6 +6,7 @@
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import AgoraRtcKit
import UIKit
// MARK: - 浮窗管理
......@@ -187,15 +188,66 @@ class YHFloatingWindow: NSObject {
// MARK: - Private Methods
private func updateLayoutForOrientation() {
let currentWidth = containerView.bounds.width
let newHeight = currentWidth / videoOrientation.aspectRatio
UIView.animate(withDuration: 0.3) {
var frame = self.containerView.frame
frame.size.height = newHeight
self.containerView.frame = frame
self.delegate?.floatingWindow(self, didChangeSize: frame.size)
}
// let currentWidth = containerView.bounds.width
// let newHeight = currentWidth / videoOrientation.aspectRatio
//
// UIView.animate(withDuration: 0.3) {
// var frame = self.containerView.frame
// frame.size.height = newHeight
// self.containerView.frame = frame
// self.delegate?.floatingWindow(self, didChangeSize: frame.size)
// }
guard let window = UIApplication.shared.yhKeyWindow() else { return }
let currentWidth = containerView.bounds.width
let newHeight = currentWidth / videoOrientation.aspectRatio
// 计算安全区域
let safeAreaInsets = window.safeAreaInsets
let maxHeight = window.bounds.height - safeAreaInsets.top - safeAreaInsets.bottom
// 如果新高度超过最大高度,则反过来调整宽度
let finalWidth: CGFloat
let finalHeight: CGFloat
if newHeight > maxHeight {
finalHeight = maxHeight
finalWidth = maxHeight * videoOrientation.aspectRatio
} else {
finalWidth = currentWidth
finalHeight = newHeight
}
// 确保浮窗位置在屏幕范围内
var newFrame = containerView.frame
newFrame.size.width = finalWidth
newFrame.size.height = finalHeight
// 检查右边界
if newFrame.maxX > window.bounds.width - 16 {
newFrame.origin.x = window.bounds.width - newFrame.width - 16
}
// 检查左边界
if newFrame.minX < 16 {
newFrame.origin.x = 16
}
// 检查底部边界
if newFrame.maxY > window.bounds.height - 44 {
newFrame.origin.y = window.bounds.height - newFrame.height - 44
}
// 检查顶部边界
if newFrame.minY < safeAreaInsets.top + 16 {
newFrame.origin.y = safeAreaInsets.top + 16
}
UIView.animate(withDuration: 0.3) {
self.containerView.frame = newFrame
self.delegate?.floatingWindow(self, didChangeSize: newFrame.size)
}
}
// MARK: - Gesture Handlers
......@@ -439,3 +491,22 @@ extension YHFloatingWindow: UIGestureRecognizerDelegate {
return true
}
}
// MARK: - YHPlayerDelegate
extension YHFloatingWindow: YHPlayerDelegate {
func player(_ player: YHPlayer, didChangedToState state: AgoraMediaPlayerState, reason: AgoraMediaPlayerReason) {
//
}
func player(_ player: YHPlayer, didChangedToPosition position: Int) {
//
}
func player(_ player: YHPlayer, didReceiveVideoSize size: CGSize) {
DispatchQueue.main.async {
self.setVideoSize(size)
}
}
func player(_ player: YHPlayer, didChangedTo positionMs: Int, atTimestamp timestampMs: TimeInterval) {
//
}
}
......@@ -62,8 +62,8 @@ class YHLiveMessageCell: UITableViewCell {
}
}
func configureNormalMessage(_ nickname: String, _ content: String) {
let nickAtt = ASAttributedString(string: nickname + ":", .foreground(UIColor.white.withAlphaComponent(0.65)), .font(UIFont.PFSC_R(ofSize: 13)))
func configureNormalMessage(_ nickname: String, _ content: String, isAnchor: Bool) {
let nickAtt = isAnchor ? ASAttributedString(string: nickname + ":", .foreground(UIColor(hexString: "#FFE3BB") ?? UIColor.white), .font(UIFont.PFSC_R(ofSize: 13))) : ASAttributedString(string: nickname + ":", .foreground(UIColor.white.withAlphaComponent(0.65)), .font(UIFont.PFSC_R(ofSize: 13)))
let contentAtt = ASAttributedString(string: content, .foreground(UIColor.white), .font(UIFont.PFSC_R(ofSize: 13)))
contentLabel.attributed.text = nickAtt + contentAtt
}
......
......@@ -11,6 +11,7 @@ import UIKit
class YHLiveMessageListView: UIView {
private var messages: [EMChatMessage] = []
var anchorName: String?
// MARK: - UI Components
......@@ -107,7 +108,8 @@ extension YHLiveMessageListView: UITableViewDelegate, UITableViewDataSource {
printLog(body.text)
printLog("\(nickName) : \(body.text)")
content = body.text
cell.configureNormalMessage(nickName, content)
let isAnchor = nickName == anchorName
cell.configureNormalMessage(nickName, content, isAnchor: isAnchor)
} else if let body = message.body as? EMCustomMessageBody, body.event == YHChatRoomCustomLocal.tipsEvent, let customExt = body.customExt, let tips = customExt[YHChatRoomCustomLocal.tipsKey] {
cell.configureTipsMessage(tips)
}
......
......@@ -80,7 +80,7 @@ class YHPlayerTopBarView: UIView {
fatalError("init(coder:) has not been implemented")
}
func setupTopBarView(headUrl: String, nickname: String, count: Int) {
func setupTopBarView(headUrl: String, nickname: String, count: String) {
if let url = URL(string: headUrl) {
headPortrait.kf.setImage(with: url, placeholder: UIImage(named: "global_default_image"))
} else {
......@@ -90,9 +90,13 @@ class YHPlayerTopBarView: UIView {
updateCountLabel(count)
}
func updateCountLabel(_ count: Int) {
func updateCountLabel(_ count: String) {
infoCountLabel.text = "\(count)人来过"
}
func hideZoomButton(_ hide: Bool) {
zoomButton.isHidden = hide
}
}
extension YHPlayerTopBarView {
......
......@@ -187,6 +187,11 @@ func configTabBarController() -> YHTabBarViewController {
tabBarController.didHijackHandler = {
tabBarController, viewController, index in
if index == ai_tabIndex {
if !YHLoginManager.shared.isLogin() {
YHOneKeyLoginManager.shared.oneKeyLogin()
return
}
let vc = YHAITabViewController()
UIViewController.current?.navigationController?.pushViewController(vc)
}
......
......@@ -5,12 +5,12 @@
"scale" : "1x"
},
{
"filename" : "Mask group@2x.png",
"filename" : "卡片切图@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Mask group@3x.png",
"filename" : "卡片切图@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
......
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Rectangle 346242466@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Rectangle 346242466@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment