wangliang_wd

Merge branch 'main' of http://192.168.1.42/developOne/harmonyPool into main

* 'main' of http://192.168.1.42/developOne/harmonyPool:
  对齐正在直播卡片
  fix: 回退app foreground background png
  fix: 替换app foreground background png
  fix |> 修复横屏直播点击暂停后,进入后台后,再进入前台,暂停播放按钮与播放器状态不一致问题
  fix: 修复已读的卡片内容置灰后杀进程再次返回频道页此时已读的内容变成未读状态
  title和summary总行数为4
  fix |> 修复人民号tab页头背景换肤与安卓和iOS不一致问题
  视频全屏时,支持横向滑动手势调整进度,功能未实现
  fix: WDPlayController play()增加prepare逻辑
  fix |> 修复tabbar来回多长切换出现多个选中的场景
  fix: 沉浸式视频网络差提示toast逻辑优化
  ref |> 华为分享增加标题和描述部分
  卡片来源显示规则调整未实现,单图卡,小视频卡,来源需要控制16个字,大图卡,三图卡,来源可以展示一行的就不需要控制16个字
Showing 21 changed files with 155 additions and 44 deletions
... ... @@ -39,6 +39,7 @@ export interface ShareContentLink {
desc?: string
link: string
icon?: string
posterImg?: Resource
deeplink: string // 根据内容详情,生成的深度链接 如:rmrbapp://rmrb.app/openwith?type=article&subType=h5_template_article&contentId=30000762651&relId=500000038702&skipType=1&relType=1
}
... ...
... ... @@ -7,19 +7,20 @@ import { common } from '@kit.AbilityKit';
import { systemShare } from '@kit.ShareKit';
import { uniformTypeDescriptor as utd } from '@kit.ArkData';
import { JSON } from '@kit.ArkTS';
import { image } from '@kit.ImageKit';
import { WDShareBase } from '../WDShareBase';
const TAG = "WDSystemShare"
export class WDSystemShare implements WDShareInterface {
shareContent(scene: ShareScene, content: ShareContent, contentType: ShareContentType): Promise<string> {
shareContent(scene: ShareScene, content: ShareContent, contentType: ShareContentType, context?: common.UIAbilityContext): Promise<string> {
return new Promise((resolve, fail) => {
return new Promise(async (resolve, fail) => {
try {
let data = this.getShareData(content, contentType)
let data = await this.getShareData(content, contentType, context)
let controller: systemShare.ShareController = new systemShare.ShareController(data);
let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext
controller.on('dismiss', () => {
... ... @@ -31,26 +32,30 @@ export class WDSystemShare implements WDShareInterface {
selectionMode: systemShare.SelectionMode.SINGLE
});
console.log("分享控制器调用完成")
console.log(TAG, "分享控制器调用完成")
} catch (e) {
console.log(TAG, "异常1" + JSON.stringify(e))
fail(e)
}
})
}
getShareData(content: ShareContent, contentType: ShareContentType) : systemShare.SharedData {
getShareData(content: ShareContent, contentType: ShareContentType, context?: common.UIAbilityContext) : Promise<systemShare.SharedData> {
return new Promise((resolve, fail) => {
if (contentType === ShareContentType.PrueText) {
let prueText = content as ShareContentText
console.log("分享纯文本")
return new systemShare.SharedData({
console.log(TAG, "分享纯文本")
resolve(new systemShare.SharedData({
utd: utd.UniformDataType.PLAIN_TEXT,
content: prueText.text
});
}))
return;
}
if (contentType === ShareContentType.ImageAndText) {
let imageAndText = content as ShareContentImageAndText
console.log("分享图片和文本")
console.log(TAG, "分享图片和文本")
let data: systemShare.SharedData = new systemShare.SharedData({
utd: utd.UniformDataType.PLAIN_TEXT,
content: imageAndText.title
... ... @@ -59,23 +64,46 @@ export class WDSystemShare implements WDShareInterface {
utd: utd.UniformDataType.PNG,
uri: imageAndText.imgURI // 这里必须为本地连接
});
return data
resolve(data)
return
}
console.log("分享链接和文本")
console.log(TAG, "分享链接和文本")
let link = content as ShareContentLink
let posterImg: Uint8Array | undefined = undefined
let shareLink = this.generateShareLink(link)
console.log("TAG, 分享 shareLink ==> " + shareLink)
if (!context || !link.posterImg) {
let data: systemShare.SharedData = new systemShare.SharedData({
utd: utd.UniformDataType.PLAIN_TEXT,
content: link.title
utd: utd.UniformDataType.HYPERLINK,
// uri: link.link // SDK 设计 不能传这里
content: link.link,
title: link.title,
description: link.desc,
thumbnail: posterImg
});
let shareLink = this.generateShareLink(link)
console.log("分享 shareLink ==> " + shareLink)
data.addRecord({
resolve(data)
return
}
context.resourceManager.getMediaContent(link.posterImg)
.then((posterImg) => {
let data: systemShare.SharedData = new systemShare.SharedData({
utd: utd.UniformDataType.HYPERLINK,
// uri: link.link // SDK 设计 不能传这里
content: link.link
content: link.link,
title: link.title,
description: link.desc,
thumbnail: posterImg
});
return data
resolve(data)
})
.catch((e: Error) => {
console.log(TAG, "异常" + JSON.stringify(e))
fail(e)
})
})
}
generateShareLink(shareContent: ShareContentLink) {
... ...
... ... @@ -2,6 +2,7 @@ import { ShareContent, ShareContentType, ShareScene, ShareType } from './Constan
import { HashMap } from '@kit.ArkTS'
import { WDShareInterface } from './WDShareInterface'
import { WDSystemShare } from './System/WDSystemShare'
import { common } from '@kit.AbilityKit'
export interface WDShareObject {
to: ShareType,
... ... @@ -12,6 +13,8 @@ export interface WDShareObject {
export class WDShareBase {
public gotContextFunc?: () => common.UIAbilityContext
private static instance?: WDShareBase
static getInstance() : WDShareBase {
if (!WDShareBase.instance) {
... ... @@ -30,7 +33,8 @@ export class WDShareBase {
share(obj: WDShareObject) : null | Promise<string> {
let shareHandler: WDShareInterface = this.handles.get(obj.to)
if (shareHandler) {
return shareHandler.shareContent(obj.scene, obj.obj, obj.type)
let context = this.gotContextFunc && this.gotContextFunc()
return shareHandler.shareContent(obj.scene, obj.obj, obj.type, context)
}
return null
}
... ...
import { ShareContent, ShareContentType, ShareScene } from './Constant'
import { AsyncCallback } from '@kit.BasicServicesKit'
import { common } from '@kit.AbilityKit'
export interface WDShareInterface {
// shareContent(scene:ShareScene, content: ShareContent, callback: AsyncCallback<void>): void
shareContent(scene:ShareScene, content: ShareContent, contentType: ShareContentType): Promise<string>
shareContent(scene:ShareScene, content: ShareContent, contentType: ShareContentType, context?: common.UIAbilityContext): Promise<string>
... ...
... ... @@ -147,6 +147,7 @@ export struct CardSourceInfo {
}
// 评论数
if (!this.contentDTO.cornerMark && !this.contentDTO.corner) {
if (this.contentDTO.objectType !=='2' && !this.isCompInnerSource && Number(this.getContentDtoBean()?.interactData?.commentNum) > 0 &&
this.showCommentNum()) {
Text(`${this.handlerNum(this.getContentDtoBean()?.interactData?.commentNum.toString())}评`)
... ... @@ -163,6 +164,7 @@ export struct CardSourceInfo {
}
}
}
}
.width(CommonConstants.FULL_WIDTH)
... ...
... ... @@ -92,6 +92,7 @@ export struct TopNavigationComponentNew {
channelId: navItem?.channelId + '',
autoRefresh: this.autoRefresh2Page
})
.backgroundColor(Color.White)
} else {
if (!this.isBroadcast(navItem) && !this.isLayout(navItem)) {
if (CompUtils.isNews(this.navItem)) {
... ... @@ -172,7 +173,8 @@ export struct TopNavigationComponentNew {
channelId: navItem?.channelId + '',
autoRefresh: this.autoRefresh2Page,
isMourning: mourningCheckFn(`${navItem.channelId}`),
});
})
.backgroundColor(CompUtils.isRMH(this.navItem)?Color.White:Color.Transparent)
}
/**
... ... @@ -259,10 +261,11 @@ export struct TopNavigationComponentNew {
@Builder
tabBar() {
if (CompUtils.isNews(this.navItem)) {
// 顶部背景图
Image(this.navItem.backgroundUrl).width('100%')
Image(this.navItem.backgroundUrl).width('100%').height('100%')
.grayscale(this.GrayManage.get().isMourning() ? 1 : 0)
if (CompUtils.isNews(this.navItem)) {
// 顶部搜索、日报logo、早晚报
this.topBar()
... ... @@ -306,10 +309,10 @@ export struct TopNavigationComponentNew {
})
} else {
// 顶部背景图
Image(this.navItem.backgroundUrl)
.width('100%')
.height(this.backgroundImageH)
.grayscale(this.GrayManage.get().isMourning() ? 1 : 0)
// Image(this.navItem.backgroundUrl)
// .width('100%')
// .height(this.backgroundImageH)
// .grayscale(this.GrayManage.get().isMourning() ? 1 : 0)
Row() {
Image($r('app.media.icon_search'))
... ...
... ... @@ -261,8 +261,8 @@ export struct LiveHorizontalCardComponent {
}
// .width(CommonConstants.FULL_WIDTH)
.padding({
left: $r('app.float.card_comp_pagePadding_lf'),
right: $r('app.float.card_comp_pagePadding_lf'),
left: 10,
right: 10,
top: $r('app.float.card_comp_pagePadding_tb'),
bottom: 6
})
... ...
PersistentStorage.persistProp('clickedIds', []);
function persistentStorage(id: string | number, type: 'add' | 'remove' | undefined = 'add') {
let _clickedIds = AppStorage.get<string[]>('clickedIds');
... ...
... ... @@ -31,6 +31,7 @@ export struct PlayUIComponent {
@Consume playSourceState: number
onChangeMenuVisible() {
this.isPlayStatus = !this.isPlayStatus
if (!this.contentDetailData || !this.contentDetailData.liveInfo ||
this.contentDetailData?.liveInfo?.liveState === 'wait') {
return
... ...
... ... @@ -40,7 +40,6 @@ export struct TopPlayComponent {
@Consume @Watch('pageHideChange') pageHide: number
init: boolean = false
@Prop @Watch("liveIMControlMessageChange") lastLiveControl: LiveRoomItemBean = {} as LiveRoomItemBean // IM 控制消息
pageShowChange() {
this.playerController?.play()
}
... ...
... ... @@ -304,10 +304,11 @@ export struct DetailPlayShortVideoPage {
}
})
this.playerViewBuilder()
if(this.index === this.currentIndex) {
PlayerBottomView({
playerController: this.playerController
})
}
PlayerRightView({
playerController: this.playerController
... ...
... ... @@ -2,7 +2,7 @@ import { ContentDetailDTO } from 'wdBean/Index'
import { WDShare } from 'wdShare/Index'
import { PlayerProgressFullScreenView } from './PlayerProgressFullScreenView'
import { PlayerConstants, WDPlayerController } from 'wdPlayer/Index'
import { DateTimeUtils, WindowModel } from 'wdKit/Index'
import { DateTimeUtils, Logger, WindowModel } from 'wdKit/Index'
import { DisplayDirection } from 'wdConstant/Index'
import { window } from '@kit.ArkUI'
... ... @@ -64,7 +64,7 @@ export struct PlayerFullScreenView {
})
this.headerBuilder()
this.middleSlideBuilder()
this.bottomBuilder()
}
.zIndex(99999)
... ... @@ -187,4 +187,45 @@ export struct PlayerFullScreenView {
})
}
@Builder
middleSlideBuilder() {
Column() {
Slider({
value: this.progressVal,
step: 0.01,
style: SliderStyle.OutSet
})
.trackColor(Color.Transparent)// 设置轨道为透明
.selectedColor(Color.Transparent)// 设置已选择部分为透明
.blockColor(Color.Transparent)// 设置滑块为透明
.trackThickness(4)
.showSteps(false)// 不显示步进刻度
.showTips(false)// 不显示提示
.width('100%')
.height('100%')
.onChange((value: number, mode: SliderChangeMode) => {
this.progressVal = value
if (mode === SliderChangeMode.Moving) {
this.isDragging = true
}
if (mode === SliderChangeMode.End) {
this.isDragging = false
}
console.log('Transparent slider value:', value)
})
}.margin({ top: 73, bottom: 73 })
.onTouch((event?: TouchEvent) => {
if (event) {
if (event.type === TouchType.Down) {
clearInterval(this.timer)
}
if (event.type === TouchType.Up) {
this.restartTimer();
this.playerController?.setSeekTime(this.progressVal, SliderChangeMode.End);
}
}
})
}
}
\ No newline at end of file
... ...
... ... @@ -30,13 +30,10 @@ export struct PlayerProgressView {
if (this.onlyWifiLoadVideo) {
this.showLoading = true
}
// console.log("PlayerProgressView11", this.timer)
if(this.timer) {
clearTimeout(this.timer)
}
this.timer = setTimeout(() => {
ToastUtils.shortToast('网络出小差了,请检查下网络')
}, 10000)
// console.log("PlayerProgressView11", this.timer)
} else {
// console.log("PlayerProgressView22", this.timer)
clearTimeout(this.timer)
... ...
... ... @@ -16,6 +16,11 @@ export struct PlayerTitleView {
@State rmhPlatform: number = 0 // 1是人民号
@State isOverLines: boolean = false
@State summary: string = ''
@State private titleLines: number = 0
@State private summaryLines: number = 0
dialogController: CustomDialogController = new CustomDialogController({
builder: DetailDialog({
name: this.getName(),
... ... @@ -104,6 +109,13 @@ export struct PlayerTitleView {
this.summary = this.getSummary()
}
private updateSummaryLines() {
this.summaryLines = Math.max(1, 4 - this.titleLines)
this.isOverLines = this.summary.length > this.clipText(this.summary, 14, this.summaryLines, this.windowWidth - 150 - vp2px(50)).length
}
build() {
Column() {
if (this.getName()) {
... ... @@ -133,7 +145,10 @@ export struct PlayerTitleView {
.fontFamily('PingFang SC-Regular')
.textOverflow({ overflow: TextOverflow.Ellipsis })
.margin({ bottom: 2 }) //8
.onAreaChange((oldArea: Area, newArea: Area) => {
this.titleLines = Math.ceil((newArea.height as number) / 20) // 20是行高
this.updateSummaryLines()
})
/**
* 标题大于三行或存在简介显示查看详情按钮
*/
... ... @@ -161,7 +176,7 @@ export struct PlayerTitleView {
// } else {
if(this.summary) {
Text() {
Span(this.clipText(this.summary, 14, 3, this.windowWidth - 150 - vp2px(50)))
Span(this.clipText(this.summary, 14, this.summaryLines, this.windowWidth - 150 - vp2px(50)))
.fontSize(14)
.fontColor(Color.White)
.lineHeight(21)
... ...
... ... @@ -250,7 +250,11 @@ export class WDPlayerController {
// if (this.avPlayer == null) {
// return
// }
this.avPlayer?.play();
this.avPlayer?.prepare().then(() => {
this.avPlayer?.play()
}, (err: BusinessError) => {
console.error('Failed to prepare,error message is :' + err.message)
})
}
async startRenderFrame(cb: Function) {
... ...
... ... @@ -22,6 +22,7 @@ export class WDShare {
desc: content.shareInfo.shareSummary,
link: content.shareInfo.shareUrl,
deeplink:AppInnerLinkGenerator.generateDeepLinkWithConent(content),
// posterImg:$r("app.media.test_share_poster"),
}
})
}
... ...
... ... @@ -21,6 +21,7 @@
"wdTracking": "file:../../features/wdTracking",
"wdPlayer": "file:../../features/wdPlayer",
"wdShare": "file:../../features/wdShare",
"wdShareBase": "file:../../commons/wdShareBase",
"wdDetailPlayLive": "file:../../features/wdDetailPlayLive"
}
}
... ...
... ... @@ -17,6 +17,7 @@ import { LaunchPageModel } from './viewModel/LaunchPageModel';
const TAG = 'MainPage';
PersistentStorage.persistProp('GestureLoadStrategy', 0); // 点播视频手势动画0为用户首次进入视频点播,1为用户已进入视频点播
PersistentStorage.persistProp('clickedIds', []); // 频道稿件已读存放稿件ID结合用户频道列表已读置灰回显
@Entry
@Component
... ...
... ... @@ -96,7 +96,7 @@ export struct BottomNavigationComponent {
navItem: navItem
})
} else {
// 其它带顶的页面,如 新闻、人民号、服务
// 其它带顶的页面,如 新闻、人民号、服务
TopNavigationComponentNew({
topNavList: navItem.topNavChannelList.filter(item => item.channelId != 2073),
_currentNavIndex: $currentNavIndex,
... ... @@ -193,14 +193,17 @@ export struct BottomNavigationComponent {
}
getBottomImageKnifeOption(navItem: BottomNavDTO, isSelect: boolean): ImageKnifeOption {
let defaultIcon = this.getBottomLocalIcon(navItem, isSelect)
let url = this.getBottomIcon(navItem, isSelect)
// Logger.info(TAG, `onChange111, 本地的地址: ${defaultIcon}`);
let imageKnifeOption: ImageKnifeOption = {
loadSrc: url,
// 占位图使用本地资源
placeholderSrc: defaultIcon,
// 失败占位图使用本地资源
errorholderSrc: defaultIcon,
// errorholderSrc: defaultIcon,
// 是否开启一级内存缓存
isCacheable: true,
// 磁盘缓存
... ...
... ... @@ -24,6 +24,7 @@ import { LiveRoomManager } from 'wdDetailPlayLive/Index'
import { initGlobalPlayerSettings } from 'wdPlayer/src/main/ets/utils/GlobalSetting'
import { BackgroundAudioController } from 'wdPlayer/Index'
import { SpConstants } from 'wdConstant'
import { WDShareBase } from 'wdShareBase/Index';
const TAG = "[StartupManager]"
... ... @@ -126,6 +127,8 @@ export class StartupManager {
this.initLiveChatRoom()
this.initBackgroundAudioTask()
this.initShare()
Logger.debug(TAG, "App 必要初始化完成")
}
... ... @@ -233,6 +236,12 @@ export class StartupManager {
}
}
private initShare() {
WDShareBase.getInstance().gotContextFunc = () => {
return StartupManager.sharedInstance().context!
}
}
private initThirdPlatformSDK() {
}
... ...