张善主

Merge remote-tracking branch 'origin/main'

Showing 80 changed files with 2292 additions and 600 deletions
{
"app": {
"bundleName": "com.wondertek.sight",
"bundleName": "com.peopledailychina.hosactivity",
"vendor": "$string:app_vendor",
"versionCode": 1000000,
"versionName": "1.0.0",
... ...
{
"app": {
// "signingConfigs": [
// {
// "name": "default",
// "type": "HarmonyOS",
// "material": {
// "certpath": "C:\\Users\\pc\\.ohos\\config\\default_sight_harmony_l75MehGV9G3TUayEtL68-EIWqyYDqfVXfu9D-DPJ7I0=.cer",
// "storePassword": "0000001AB256FAF47AA4D68E4841C95D357490DE9FBB26A3A9161AD3069E31B3623E25CB49409CCA9CF7",
// "keyAlias": "debugKey",
// "keyPassword": "0000001AFB06818C2BC8DC275326668AAC62B91EBF7D3F84E8BE0F156D02623AA0F4F8C6B73F362CB371",
// "profile": "C:\\Users\\pc\\.ohos\\config\\default_sight_harmony_l75MehGV9G3TUayEtL68-EIWqyYDqfVXfu9D-DPJ7I0=.p7b",
// "signAlg": "SHA256withECDSA",
// "storeFile": "C:\\Users\\pc\\.ohos\\config\\default_sight_harmony_l75MehGV9G3TUayEtL68-EIWqyYDqfVXfu9D-DPJ7I0=.p12"
// }
// }
// ],
"signingConfigs": [
{
"name": "default",
"type": "HarmonyOS",
"material": {
"certpath": "C:\\Users\\pc\\.ohos\\config\\default_sight_harmony_l75MehGV9G3TUayEtL68-EIWqyYDqfVXfu9D-DPJ7I0=.cer",
"storePassword": "0000001AB256FAF47AA4D68E4841C95D357490DE9FBB26A3A9161AD3069E31B3623E25CB49409CCA9CF7",
"keyAlias": "debugKey",
"keyPassword": "0000001AFB06818C2BC8DC275326668AAC62B91EBF7D3F84E8BE0F156D02623AA0F4F8C6B73F362CB371",
"profile": "C:\\Users\\pc\\.ohos\\config\\default_sight_harmony_l75MehGV9G3TUayEtL68-EIWqyYDqfVXfu9D-DPJ7I0=.p7b",
"storePassword": "0000001EF28F8A628911F4F52B75E452C814EE4370854DD8DFCE186496B6AD88F8DE5AD3E10F24C1079F2EDD1FFF",
"certpath": "./singing_config/manual_com.peopledailychina.hosactivity_sign/鸿蒙中文版客户端证书.cer",
"keyAlias": "peopledailyhosalias",
"keyPassword": "0000001E2E8A50EFF2E6D2023242B432388B2748F8299D8BB319C0B06CFF7DCEA7482C5E3CDF1398CCE095BDC68B",
"profile": "./singing_config/manual_com.peopledailychina.hosactivity_sign/peopledaiychina-hos-profile-debugDebug.p7b",
"signAlg": "SHA256withECDSA",
"storeFile": "C:\\Users\\pc\\.ohos\\config\\default_sight_harmony_l75MehGV9G3TUayEtL68-EIWqyYDqfVXfu9D-DPJ7I0=.p12"
"storeFile": "./singing_config/manual_com.peopledailychina.hosactivity_sign/keystorefile.p12"
}
}
],
... ...
... ... @@ -45,5 +45,9 @@ export class ContentConstants {
*/
static readonly TYPE_FIFTEEN: string = "15";
/**
* 30:金刚位聚合页
*/
static readonly TYPE_THIRTY: string = "30";
}
\ No newline at end of file
... ...
... ... @@ -36,4 +36,16 @@ export class NetworkUtil {
return NetworkUtil.TYPE_NONE;
}
}
/**
* 判断网络是否已连接
* @returns
*/
static isNetConnected(): boolean {
let type = NetworkManager.getInstance().getNetType()
if (type == NetworkType.TYPE_NONE) {
return false
}
return true
}
}
\ No newline at end of file
... ...
... ... @@ -26,7 +26,7 @@ export class ResourcesUtils {
try {
let text = buffer.from(content).toString("utf8");
if (text) {
Logger.info(TAG, "getResourcesText then text:" + text);
// Logger.info(TAG, "getResourcesText then text:" + text);
success(text);
} else {
Logger.warn(TAG, "getResourcesText then text is empty");
... ...
... ... @@ -225,6 +225,10 @@ export class HttpUrlUtils {
*/
static readonly LIVE_APPOINTMENT_PATH: string = "/api/live-center-message/zh/c/live/subscribe";
/**
* 预约状态
*/
static readonly LIVE_APPOINTMENT_BATCH_PATH: string = "api/live-center-message/zh/c/live/subscribe/user/batch";
/**
* 搜索结果 显示tab 数
*/
... ... @@ -285,7 +289,6 @@ export class HttpUrlUtils {
* 获取启动页相关数据
*/
static readonly LAUNCH_PAGE_PATH: string = "/api/rmrb-bff-display-zh/display/zh/c/launchPage";
private static _hostUrl: string = HttpUrlUtils.HOST_PRODUCT;
/**
* 推荐列表
... ... @@ -772,6 +775,11 @@ export class HttpUrlUtils {
return url
}
static getAppointmentStatusUrl() {
let url = HttpUrlUtils._hostUrl + HttpUrlUtils.LIVE_APPOINTMENT_BATCH_PATH
return url
}
static getSearchResultCountDataUrl() {
let url = HttpUrlUtils._hostUrl + HttpUrlUtils.SEARCH_RESULT_COUNT_DATA_PATH
return url
... ... @@ -818,6 +826,12 @@ export class HttpUrlUtils {
return url
}
//金刚位聚合页
static getThemeListUrl() {
let url = HttpUrlUtils._hostUrl + "/api/rmrb-bff-display-zh/display/zh/c/themeList";
return url;
}
// static getYcgCommonHeaders(): HashMap<string, string> {
// let headers: HashMap<string, string> = new HashMap<string, string>()
//
... ...
... ... @@ -65,6 +65,10 @@ export function registerRouter() {
return WDRouterPage.audioDetail
} else if (action.params?.detailPageType == 18) {
return WDRouterPage.multiPictureListPage
} else if (action.params?.detailPageType == 19) {
return WDRouterPage.videoPlayPage
}else if (action.params?.detailPageType == 30) {
return WDRouterPage.themeListPage
}
return WDRouterPage.detailPlayVodPage
})
... ...
... ... @@ -59,6 +59,8 @@ export class WDRouterPage {
static multiPictureDetailPage = new WDRouterPage("phone", "ets/pages/detail/MultiPictureDetailPage");
//大图列表页
static multiPictureListPage = new WDRouterPage("wdComponent", "ets/pages/MultiPictureListPage");
//单个视频播放页
static videoPlayPage = new WDRouterPage("wdComponent", "ets/pages/VideoPlayPage");
// 音乐详情页
static audioDetail = new WDRouterPage("phone", "ets/pages/detail/AudioDetail");
// 动态详情页
... ... @@ -118,4 +120,6 @@ export class WDRouterPage {
static liveMorePage = new WDRouterPage("wdComponent", "ets/components/page/LiveMorePage");
//预约更多页
static reserveMorePage = new WDRouterPage("wdComponent", "ets/components/page/ReserveMorePage");
//金刚位聚合页
static themeListPage = new WDRouterPage("wdComponent", "ets/components/page/ThemeListPage");
}
... ...
... ... @@ -4,6 +4,8 @@ import { Logger } from 'wdKit';
import { StringUtils } from 'wdKit/src/main/ets/utils/StringUtils';
import { WDRouterRule } from '../router/WDRouterRule';
import { ContentConstants } from 'wdConstant';
import { common, Want } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
// import { LiveModel } from '../viewmodel/LiveModel';
... ... @@ -58,10 +60,14 @@ export class ProcessUtils {
break;
//动态详情页(动态图文)
case ContentConstants.TYPE_FOURTEEN:
ProcessUtils.gotoDynamicDetailPage(content);
//动态详情页(动态视频)
case ContentConstants.TYPE_FIFTEEN:
ProcessUtils.gotoDynamicDetailPage(content);
break;
case ContentConstants.TYPE_THIRTY:
ProcessUtils.gotoThemeListPage(content)
break;
default:
break;
}
... ... @@ -194,6 +200,26 @@ export class ProcessUtils {
}
/**
* 金刚位聚合页
* @param content
* */
private static gotoThemeListPage(content: ContentDTO) {
let taskAction: Action = {
type: 'JUMP_DETAIL_PAGE',
params: {
detailPageType: 30,
contentID: content?.objectId,
extra: {
relType: content?.relType,
relId: content?.relId,
} as ExtraDTO
} as Params,
};
WDRouterRule.jumpWithAction(taskAction)
Logger.debug(TAG, `gotoAtlasDetailPage, ${content.objectId}`);
}
/**
* 图片预览页
* @param content
* */
... ... @@ -212,4 +238,38 @@ export class ProcessUtils {
WDRouterRule.jumpWithAction(taskAction)
Logger.debug(TAG, `gotoAtlasDetailPage, ${content.objectId}`);
}
}
\ No newline at end of file
/**
* 打开外链
* @param url 外链地址
*/
public static jumpExternalWebPage(url: string) {
let context = getContext() as common.UIAbilityContext;
let wantInfo: Want = {
action: 'ohos.want.action.viewData',
entities: ['entity.system.browsable'],
uri: url
}
context.startAbility(wantInfo).then(() => {
Logger.debug(TAG, 'jumpExternalWebPage success')
}).catch((err: BusinessError) => {
Logger.error(TAG, 'jumpExternalWebPage success, error: ' + JSON.stringify(err))
})
}
/**
* 打开端内web页面
* @param url web地址
*/
public static gotoDefaultWebPage(url: string) {
let taskAction: Action = {
type: 'JUMP_H5_BY_WEB_VIEW',
params: {
url: url,
} as Params,
};
WDRouterRule.jumpWithAction(taskAction)
}
}
... ...
... ... @@ -37,7 +37,6 @@ export {
postExecuteCollectRecordParams,
contentListParams,
postInteractAccentionOperateParams,
postRecommendListParams,
contentListItem
} from './src/main/ets/bean/detail/MultiPictureDetailPageDTO';
... ... @@ -119,12 +118,18 @@ export { ArticleListDTO } from './src/main/ets/bean/component/ArticleListDTO';
export { appStyleImagesDTO } from './src/main/ets/bean/content/appStyleImagesDTO';
export { LiveRoomBean,LiveRoomItemBean } from './src/main/ets/bean/live/LiveRoomBean';
export { LiveRoomBean, LiveRoomItemBean } from './src/main/ets/bean/live/LiveRoomBean';
export { LiveRoomDataBean } from './src/main/ets/bean/live/LiveRoomDataBean';
export { ReserveBean } from './src/main/ets/bean/live/ReserveBean';
export { LiveInfoDTO } from './src/main/ets/bean/detail/LiveInfoDTO';
export { postRecommendListParams } from './src/main/ets/bean/detail/postRecommendListParams';
export { postThemeListParams } from './src/main/ets/bean/detail/postThemeListParams';
export { LiveDTO } from './src/main/ets/bean/peoples/LiveDTO';
export { contentVideosDTO } from './src/main/ets/bean/content/contentVideosDTO';
... ...
... ... @@ -19,49 +19,80 @@ export interface AdvRuleBean {
/**
* 广告展示顺序,0:随机展示;1列表循环
*/
displayMode:number
displayMode: number
/**
* 每间隔刷新n次展示广告
*/
refreshFrequency:number
refreshFrequency: number
/**
* 广告信息集合
*/
advert:AdvertsBean;
advert: AdvertsBean;
}
/**
* 广告组件数据
*/
export interface CompAdvBean{
export interface CompAdvBean {
/**
* 广告订单id
*/
id:string;
id: string;
/**
* 投放开始时间
*/
startTime:number;
startTime: number;
/**
* 投放结束时间
*/
endTime:number;
endTime: number;
/**
* 信息流广告素材
*/
matInfo:CompAdvMatInfoBean
matInfo: CompAdvMatInfoBean
/**
* 信息流广告位
*/
slotInfo:CompAdvSlotInfoBean
slotInfo: CompAdvSlotInfoBean
/**
* 展示优先级
* 广告A,displayPriority=1
* 广告B,displayPriority=2
* 则打开页面时,挂角展示顺序 A->B (优先级升序排列)
*/
displayPriority: number;
/**
* 展示的次数
*/
showCount: number;
/**
* 页面id
*/
pageId: String ;
/**
* 开屏广告-显示时长
*/
displayDuration: String;
/**
* 开屏广告-展示轮数
* 2.launchAdInfo有多个时:
* 广告A,displayRound=10
* 广告B,displayRound=5,
* 每次开机屏展示广告概率
* 广告A=10/(10+5)
* 广告B=5/(10+5)
* 广告A展示10次后,不再展示,
* 广告B展示5此后,不再展示。
* 下一轮展示继续上面逻辑。
*/
displayRound: number;
}
... ...
... ... @@ -19,7 +19,10 @@ export interface Params {
// 13.音频详情页
// 17.多图(图集)详情页
// 18.大图列表页
// 19.单个视频播放页
detailPageType?: number; // 详情页类型
liveStyle?: number; // 直播类型:0横屏,1竖屏
creatorId?: string; //号主id
videoUrl?: string;
videoCoverUrl?: string;
}
... ...
... ... @@ -177,14 +177,4 @@ export interface postInteractAccentionOperateParams {
// userType: number;
// userId: string;
status: number;
}
export interface postRecommendListParams {
imei: string;
userId ?: string;
contentId ?: string;
relId ?: string;
contentType ?: number;
recType: number;
channelId ? : string
}
\ No newline at end of file
... ...
... ... @@ -3,11 +3,14 @@ export interface RmhInfoDTO {
authTitle: string;
authTitle2: string;
banControl: number;
cnIsAttention: number;
cnIsAttention?: number;
cnAttention?: number;
cnlsComment?: number;
cnlsLike?: number;
cnMainControl: number;
cnShareControl: number;
cnIsComment: number;
cnIsLike: number;
cnIsComment?: number;
cnIsLike?: number;
posterShareControl: number;
rmhDesc: string;
rmhHeadUrl: string;
... ...
export interface postRecommendListParams {
imei: string;
userId ?: string;
contentId ?: string;
relId ?: string;
contentType ?: number;
recType: number;
channelId ? : string
}
\ No newline at end of file
... ...
export interface postThemeListParams {
sort: number;
pageNum: number;
pageSize: number;
}
\ No newline at end of file
... ...
... ... @@ -16,4 +16,11 @@ export interface LiveRoomItemBean {
//是否置顶 1置顶0不置顶
isTop: number
role: string
//ZH_TEXT_AND_IMAGE_MSG :图文,ZH_TEXT_MSG:文本,ZH_VIDEO_MSG:视频,ZH_AUDIO_MSG:音频
dataType: string
transcodeImageUrl: string
videoUrl: string
pictureResolutions: string[]
//音视频长度
duration: number
}
\ No newline at end of file
... ...
export interface ReserveBean {
relationId: string,
liveId: string
}
\ No newline at end of file
... ...
... ... @@ -91,6 +91,7 @@ export struct BottomNavigationComponent {
// this.onBottomNavigationIndexChange()
})
.backgroundColor(this.barBackgroundColor)
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
// .padding({ bottom: this.bottomRectHeight + 'px', top: this.topRectHeight + 'px' }) // 此处margin具体数值在实际中应与导航条区域高度保持一致
... ...
... ... @@ -298,47 +298,55 @@ struct ChannelDialog {
.zIndex(this.dragItem == item.num ? 1 : 0)
.translate(this.dragItem == item.num ? { x: this.offsetX, y: this.offsetY } : { x: 0, y: 0 })
.gesture(
GestureGroup(GestureMode.Parallel,
TapGesture()
.onAction((event?: GestureEvent) => {
if (this.isEditIng) {
if (item.delPermitted === 1) {
this.delChannelItem(index)
}
} else {
this.confirm(index)
this.controller?.close()
GestureGroup(GestureMode.Parallel,
TapGesture()
.onAction((event?: GestureEvent) => {
if (this.isEditIng) {
if (item.delPermitted === 1) {
this.delChannelItem(index)
}
}),
PanGesture({ fingers: 1, direction: null, distance: 0 })
.onActionStart((event: GestureEvent) => {
this.dragItem = item.num
} else {
this.confirm(index)
this.controller?.close()
}
}),
LongPressGesture({ repeat: true })
.onAction((event: GestureEvent | undefined) => {
if (event) {
if (event.repeat && this.isEditIng === false) {
this.isEditIng = true;
}
}
}),
PanGesture({ fingers: 1, direction: null, distance: 0 })
.onActionStart((event: GestureEvent) => {
this.dragItem = item.num
this.dragRefOffsetX = 0
this.dragRefOffsetY = 0
})
.onActionUpdate((event: GestureEvent) => {
animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
this.handleAnimationTo(item, event)
})
})
.onActionEnd((event: GestureEvent) => {
animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
this.dragItem = -1
this.offsetX = 0
this.offsetY = 0
this.dragRefOffsetX = 0
this.dragRefOffsetY = 0
})
.onActionUpdate((event: GestureEvent) => {
animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
this.handleAnimationTo(item, event)
})
})
.onActionEnd((event: GestureEvent) => {
animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
this.dragItem = -1
this.offsetX = 0
this.offsetY = 0
this.dragRefOffsetX = 0
this.dragRefOffsetY = 0
})
})
).onCancel(() => {
animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
this.dragItem = -1
this.offsetX = 0
this.offsetY = 0
this.dragRefOffsetX = 0
this.dragRefOffsetY = 0
})
).onCancel(() => {
animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
this.dragItem = -1
this.offsetX = 0
this.offsetY = 0
this.dragRefOffsetX = 0
this.dragRefOffsetY = 0
})
})
)
}, (item: TopNavDTO) => JSON.stringify(item))
}
... ...
... ... @@ -52,48 +52,56 @@ export struct PageComponent {
@Builder
ListLayout() {
List() {
// 下拉刷新
ListItem() {
RefreshLayout({
refreshBean: new RefreshLayoutBean(this.pageModel.isVisiblePullDown, this.pageModel.pullDownRefreshImage,
this.pageModel.pullDownRefreshText, this.pageModel.pullDownRefreshHeight)
})
}
LazyForEach(this.pageModel.compList, (compDTO: CompDTO, compIndex: number) => {
RelativeContainer() {
List() {
// 下拉刷新
ListItem() {
Column() {
CompParser({ compDTO: compDTO, compIndex: compIndex });
}
}
},
(compDTO: CompDTO, compIndex: number) => compDTO.id + compIndex.toString() + this.pageModel.timestamp
)
// 加载更多
ListItem() {
if (this.pageModel.hasMore) {
LoadMoreLayout({
refreshBean: new RefreshLayoutBean(this.pageModel.isVisiblePullUpLoad, this.pageModel.pullUpLoadImage,
this.pageModel.pullUpLoadText, this.pageModel.pullUpLoadHeight)
RefreshLayout({
refreshBean: new RefreshLayoutBean(this.pageModel.isVisiblePullDown, this.pageModel.pullDownRefreshImage,
this.pageModel.pullDownRefreshText, this.pageModel.pullDownRefreshHeight)
})
} else if (!this.pageModel.contentNeedScroll) {
NoMoreLayout()
}
LazyForEach(this.pageModel.compList, (compDTO: CompDTO, compIndex: number) => {
ListItem() {
Column() {
CompParser({ compDTO: compDTO, compIndex: compIndex });
}
}
},
(compDTO: CompDTO, compIndex: number) => compDTO.id + compIndex.toString() + this.pageModel.timestamp
)
// 加载更多
ListItem() {
if (this.pageModel.hasMore) {
LoadMoreLayout({
refreshBean: new RefreshLayoutBean(this.pageModel.isVisiblePullUpLoad, this.pageModel.pullUpLoadImage,
this.pageModel.pullUpLoadText, this.pageModel.pullUpLoadHeight)
})
} else if (!this.pageModel.contentNeedScroll) {
NoMoreLayout()
}
}
}
// comp自己处理分页,这里设置EdgeEffect.None
.edgeEffect(this.pageModel.contentNeedScroll ? EdgeEffect.None : EdgeEffect.Spring)
.scrollBar(BarState.Off)
.cachedCount(8)
.height(CommonConstants.FULL_PARENT)
.onScrollIndex((start: number, end: number) => {
// Listen to the first index of the current list.
this.pageModel.startIndex = start;
// 包含了 头尾item,判断时需要考虑+2
this.pageModel.endIndex = end;
})
.id('page_list')
// 挂角广告
this.pageHornAd()
}
// comp自己处理分页,这里设置EdgeEffect.None
.edgeEffect(this.pageModel.contentNeedScroll ? EdgeEffect.None : EdgeEffect.Spring)
.scrollBar(BarState.Off)
.cachedCount(8)
.height(CommonConstants.FULL_PARENT)
.onScrollIndex((start: number, end: number) => {
// Listen to the first index of the current list.
this.pageModel.startIndex = start;
// 包含了 头尾item,判断时需要考虑+2
this.pageModel.endIndex = end;
})
}
@Builder
... ... @@ -105,6 +113,111 @@ export struct PageComponent {
// })
}
/**
* 页面挂角广告
*/
@Builder
pageHornAd() {
if (this.pageModel.pageLeftCornerAdv.matInfo != null) {
// 页面左挂角
Image(this.pageModel.pageLeftCornerAdv.matInfo.matImageUrl[0])
.width($r('app.float.vp_80'))
.height($r('app.float.vp_80'))
.id("left_iv")
.alignRules({
bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
left: { anchor: '__container__', align: HorizontalAlign.Start },
})
.margin({ bottom: "65vp", left: $r('app.float.card_comp_pagePadding_lf') })
Image($r('app.media.icon_adv_horn_close')).id('left_close').width($r('app.float.vp_16')).alignRules({
top: { anchor: 'left_iv', align: VerticalAlign.Top },
left: { anchor: 'left_iv', align: HorizontalAlign.Start },
}).offset({
x: -10,
y: -10
})
Text($r('app.string.comp_advertisement'))
.width($r('app.float.vp_28'))
.height($r('app.float.vp_16'))
.fontSize($r('app.float.font_size_10'))
.fontColor(Color.White)
.id('left_tag')
.alignRules({
bottom: { anchor: 'left_iv', align: VerticalAlign.Bottom },
left: { anchor: 'left_iv', align: HorizontalAlign.Start },
})
.textAlign(TextAlign.Center)
.backgroundColor($r('app.color.res_color_general_000000_30'))
.borderRadius({
topLeft: $r('app.float.vp_2'),
topRight: $r('app.float.vp_2'),
bottomLeft: $r('app.float.vp_2'),
bottomRight: $r('app.float.vp_2')
})
}
if (this.pageModel.pageRightCornerAdv.matInfo != null && this.pageModel.isShowRightAds) {
// 页面右边挂角
Image(this.pageModel.pageRightCornerAdv.matInfo.matImageUrl[0])
.width($r('app.float.vp_80'))
.height($r('app.float.vp_80'))
.id("right_iv")
.alignRules({
bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
right: { anchor: '__container__', align: HorizontalAlign.End },
})
.margin({ bottom: "65vp", right: $r('app.float.card_comp_pagePadding_lf') })
.onClick(()=>{
// 关闭挂角广告
this.pageModel.isShowLeftAds = false;
})
Image($r('app.media.icon_adv_horn_close'))
.id('right_close')
.width($r('app.float.vp_16'))
.alignRules({
top: { anchor: 'right_iv', align: VerticalAlign.Top },
right: { anchor: 'right_iv', align: HorizontalAlign.End },
})
.offset({
x: 10,
y: -10
})
.onClick(() => {
// 关闭挂角广告
this.pageModel.isShowRightAds = false;
})
Text($r('app.string.comp_advertisement'))
.width($r('app.float.vp_28'))
.height($r('app.float.vp_16'))
.fontSize($r('app.float.font_size_10'))
.fontColor(Color.White)
.id('right_tag')
.alignRules({
bottom: { anchor: 'right_iv', align: VerticalAlign.Bottom },
right: { anchor: 'right_iv', align: HorizontalAlign.End },
})
.textAlign(TextAlign.Center)
.backgroundColor($r('app.color.res_color_general_000000_30'))
.borderRadius({
topLeft: $r('app.float.vp_2'),
topRight: $r('app.float.vp_2'),
bottomLeft: $r('app.float.vp_2'),
bottomRight: $r('app.float.vp_2')
})
}
}
async aboutToAppear() {
// 选中tab,才请求数据。拦截大量接口请求
if (this.navIndex === this.currentTopNavSelectedIndex) {
... ...
import { ContentDTO } from 'wdBean';
import { ContentDTO, ReserveBean } from 'wdBean';
import { ProcessUtils } from 'wdRouter';
import { CommonConstants } from 'wdConstant/Index';
import PageViewModel from '../../viewmodel/PageViewModel';
... ... @@ -24,6 +24,7 @@ const TAG: string = 'ReserveMorePage';
struct ReserveMorePage {
@State private pageModel: PageModel = new PageModel();
@State data: LazyDataSource<ContentDTO> = new LazyDataSource();
reserveBean: ReserveBean[] = []
topSafeHeight: number = AppStorage.get<number>('topSafeHeight') as number;
type: number = 2;
currentPage: number = 1;
... ... @@ -72,12 +73,32 @@ struct ReserveMorePage {
// }
} as ContentDTO;
aboutToAppear(): void {
PageViewModel.getLiveMoreUrl(this.type, this.currentPage, this.pageSize).then((liveReviewDTO) => {
async aboutToAppear(): Promise<void> {
// PageViewModel.get
PageViewModel.getLiveMoreUrl(this.type, this.currentPage, this.pageSize).then(async (liveReviewDTO) => {
// this.operDataList = []
// this.operDataList.push(...liveReviewDTO.list)
this.data.push(...liveReviewDTO.list)
this.reserveBean = this.transformToLiveDetailsBeans(liveReviewDTO.list)
const apointMentStatus = await LiveModel.getAppointmentStatus(this.reserveBean)
console.info(`cj2024 ${apointMentStatus.code}`)
})
}
// 这个函数遍历liveReviewDTO.list并转换为LiveDetailsBean数组
transformToLiveDetailsBeans(list: ContentDTO[]): ReserveBean[] {
const liveDetailsBeans: ReserveBean[] = [];
list.forEach(item => {
liveDetailsBeans.push({
relationId: item.relId,
liveId: item.objectId,
});
});
return liveDetailsBeans
}
build() {
... ... @@ -274,6 +295,7 @@ struct ReserveMorePage {
//
// })
const liveDetail = await LiveModel.liveAppointment(item?.relId || '', item?.objectId || '', this.isAppointmentLive || false)
// const liveDetail = await LiveModel.getAppointmentStatus(item?.relId || '', item?.objectId || '', this.isAppointmentLive || false)
}
/*导航栏*/
... ...
import { ContentDTO } from 'wdBean';
import { CommonConstants ,ViewType} from 'wdConstant';
import PageViewModel from '../../viewmodel/PageViewModel';
import RefreshLayout from '../page/RefreshLayout';
import { RefreshLayoutBean } from '../page/RefreshLayoutBean';
import PageModel from '../../viewmodel/PageModel';
import { DateTimeUtils, LazyDataSource } from 'wdKit/Index';
import router from '@ohos.router';
import { CardParser } from '../CardParser';
import { channelSkeleton } from '../skeleton/channelSkeleton'
import { ErrorComponent } from '../view/ErrorComponent';
import { EmptyComponent } from '../view/EmptyComponent';
const TAG: string = 'ThemeListPage';
@Entry
@Component
struct ThemeListPage {
@State private pageModel: PageModel = new PageModel();
@State data: LazyDataSource<ContentDTO> = new LazyDataSource();
sort: number = 1;
currentPage: number = 1;
pageSize: number = 20;
title: string = '金刚位聚合页'
aboutToAppear(): void {
PageViewModel.postThemeList(this.sort, this.currentPage, this.pageSize).then((liveReviewDTO) => {
console.log(`postThemeList${JSON.stringify(liveReviewDTO)}`)
this.data.push(...liveReviewDTO.list)
if(this.data.getDataArray().length > 0){
this.pageModel.viewType = ViewType.LOADED;
}else{
this.pageModel.viewType = ViewType.EMPTY
}
})
}
build() {
Column() {
this.TabbarNormal()
if (this.pageModel.viewType == ViewType.LOADING) {
this.LoadingLayout()
} else if (this.pageModel.viewType == ViewType.ERROR) {
ErrorComponent()
} else if (this.pageModel.viewType == ViewType.EMPTY) {
EmptyComponent()
} else {
this.ListLayout()
}
}
.padding({
bottom: $r('app.float.card_comp_pagePadding_tb')
})
}
@Builder
LoadingLayout() {
channelSkeleton()
}
/*导航栏*/
@Builder
TabbarNormal() {
RelativeContainer() {
//标题栏目
Image($r('app.media.icon_arrow_left'))
.width(24)
.height(24)
.objectFit(ImageFit.Auto)
.id("back_icon")
.alignRules({
center: { anchor: "__container__", align: VerticalAlign.Center },
left: { anchor: "__container__", align: HorizontalAlign.Start }
})
.onClick(() => {
router.back()
})
Text(this.title)// .height('42lpx')
.maxLines(1)
.id("title")
.fontSize('35lpx')
.fontWeight(400)
.fontColor($r('app.color.color_222222'))
.lineHeight('42lpx')
.alignRules({
center: { anchor: "__container__", align: VerticalAlign.Center },
middle: { anchor: "__container__", align: HorizontalAlign.Center }
})
}
.height(44)
.width('100%')
.padding({
left: $r('app.float.card_comp_pagePadding_lf'),
right: $r('app.float.card_comp_pagePadding_lf'),
})
}
@Builder
ListLayout() {
List() {
// 下拉刷新
ListItem() {
RefreshLayout({
refreshBean: new RefreshLayoutBean(this.pageModel.isVisiblePullDown, this.pageModel.pullDownRefreshImage,
this.pageModel.pullDownRefreshText, this.pageModel.pullDownRefreshHeight)
})
}
LazyForEach(this.data, (contentDTO: ContentDTO, contentIndex: number) => {
ListItem() {
Column() {
CardParser({ contentDTO });
}
}
},
(contentDTO: ContentDTO, contentIndex: number) => contentDTO.pageId + contentIndex.toString()
)
}
.scrollBar(BarState.Off)
.cachedCount(8)
.height(CommonConstants.FULL_PARENT)
.onScrollIndex((start: number, end: number) => {
this.pageModel.startIndex = start;
this.pageModel.endIndex = end;
})
}
}
\ No newline at end of file
... ...
... ... @@ -11,7 +11,7 @@ import { VideoChannelDetail } from 'wdDetailPlayShortVideo/Index';
const TAG = 'TopNavigationComponent';
PersistentStorage.persistProp('channelIds', '');
PersistentStorage.persistProp('indexSettingChannelId', 0);
PersistentStorage.persistProp('indexSettingChannelId', 2002);
const storage = LocalStorage.getShared();
... ... @@ -36,7 +36,7 @@ export struct TopNavigationComponent {
// 顶导数据
@State @Watch('onTopNavigationDataUpdated') topNavList: TopNavDTO[] = []
@State compList: LazyDataSource<CompDTO> = new LazyDataSource();
@StorageProp('indexSettingChannelId') indexSettingChannelId: number = 0
@StorageProp('indexSettingChannelId') indexSettingChannelId: number = 2002
//我的频道id列表
@State channelIds: number[] = []
//本地缓存频道id列表
... ... @@ -106,7 +106,7 @@ export struct TopNavigationComponent {
}
//频道分类
if (item.myChannel === '1') {
if (item.myChannel === '1' && item.name !== '播报') {
_myChannelList.push(item)
_channelIds.push(item.channelId)
} else if (item.moreChannel === '1') {
... ... @@ -121,13 +121,9 @@ export struct TopNavigationComponent {
this.myChannelList = _myChannelList
//缓存首页频道
if (!this.indexSettingChannelId) {
AppStorage.set('indexSettingChannelId', this.homeChannelList[0].channelId)
} else {
let index = this.myChannelList.findIndex(_item => _item.channelId === this.indexSettingChannelId)
if (index > -1) {
this.currentTopNavSelectedIndex = index
}
let index = this.myChannelList.findIndex(_item => _item.channelId === this.indexSettingChannelId)
if (index > -1) {
this.currentTopNavSelectedIndex = index
}
}
... ... @@ -299,12 +295,13 @@ export struct TopNavigationComponent {
.fontColor(this.getFontColor(item, index))
.padding({ top: $r('app.float.top_tab_item_padding_top') })
.maxLines(this.MAX_LINE)
Divider()
.width(16)
.strokeWidth(2)// 分割线粗细度。
.padding({ top: 2 })
.color(Color.Red)
.opacity(this.currentTopNavSelectedIndex === index ? 1 : 0)
if (this.currentTopNavSelectedIndex === index) {
Row()
.width(20)
.height(3)
.backgroundImage($r('app.media.icon_channel_active'), ImageRepeat.NoRepeat)
}
}
.hoverEffect(HoverEffect.Highlight)
.constraintSize({
... ...
... ... @@ -151,7 +151,7 @@ export struct PeopleShipHomeArticleListComponent {
try {
this.isLoading = true
let listData: ArticleListData = await PeopleShipHomePageDataModel.getPeopleShipHomePageArticleListData(this.creatorId, this.currentPage, 20, this.typeModel.type)
Logger.debug(TAG, `获取页面信息, ${listData.list.length}`);
Logger.debug(TAG, `获取页面信息, ${JSON.stringify(listData.list)}`);
Logger.debug(TAG, `已更新值最新, ${this.currentPage}`);
if (resolve ) {
... ... @@ -173,7 +173,7 @@ export struct PeopleShipHomeArticleListComponent {
}
this.isLoading = false
this.queryArticleContentInteractCount(listData)
Logger.debug(TAG, '展示的总数', `${this.arr.length}`)
Logger.debug(TAG, '展示的总数'+`${this.arr.length}`)
}catch (exception) {
if (resolve) {
resolve('')
... ... @@ -236,7 +236,8 @@ export struct PeopleShipHomeArticleListComponent {
// 19.动态图文卡-人民号,20.动态视频卡-人民号,
// 21 小视频卡-人民号
contentDTO.objectType = `${element.type}`;
// 时间显示
contentDTO.isSearch = true
// contentDTO.productNum = element.productCount;
// if (master) {
// contentDTO.customWorkStatus = element.workStatus;
... ... @@ -277,8 +278,10 @@ export struct PeopleShipHomeArticleListComponent {
//图集数量
contentDTO.photoNum = element.mainPicCount;
if (element.mainPicCount) {
contentDTO.photoNum = element.mainPicCount;
}
Logger.debug(TAG, '图集数量:' + `${element.mainPicCount}`)
if (element.contentExt && element.contentExt.length > 0) {
let extModel = element.contentExt[0];
contentDTO.openLikes = extModel.openLikes;
... ...
import { DisplayUtils, Logger } from 'wdKit'
import { DisplayUtils, Logger } from 'wdKit'
import { PeopleShipHomePageDataModel } from '../../viewmodel/PeopleShipHomePageDataModel'
import { PeopleShipHomeArticleListComponent } from './PeopleShipHomeArticleListComponent'
import { ArticleCountData, ArticleTypeData } from 'wdBean'
... ... @@ -8,9 +8,7 @@ import { RefreshLayoutBean } from '../page/RefreshLayoutBean'
@Component
export struct PeopleShipHomeListComponent {
private controller: TabsController = new TabsController()
@State tabArr: ArticleTypeData[] = []
@State creatorId: string = ''
// 发布数量
... ... @@ -19,47 +17,69 @@ export struct PeopleShipHomeListComponent {
@State private isLoading: boolean = false
@Consume topHeight: number
build() {
if (this.isLoading) {
this.LoadingLayout()
}
// 列表
else if(this.publishCount == 0) {
else if (this.publishCount == 0) {
// 无数据展示
EmptyComponent().height(DisplayUtils.getDeviceHeight() - this.topHeight)
} else {
Tabs({ barPosition: BarPosition.Start, controller: this.controller}) {
ForEach(this.tabArr, (item: ArticleTypeData, index: number) => {
TabContent() {
PeopleShipHomeArticleListComponent({
typeModel: item,
creatorId: this.creatorId,
currentTopSelectedIndex: this.currentIndex,
currentIndex: index
})
}.tabBar(this.tabBuilder(index, item.name ?? ''))
} else {
Column() {
Column() {
// 页签
Row() {
Scroll() {
Row() {
ForEach(this.tabArr, (item: ArticleTypeData, index: number) => {
this.Tab(index, item.name ?? '')
})
}
.justifyContent(FlexAlign.Start)
}
.align(Alignment.Start)
.scrollable(ScrollDirection.Horizontal)
.scrollBar(BarState.Off)
.width('100%')
}
.alignItems(VerticalAlign.Bottom)
.width('100%')
}
.alignItems(HorizontalAlign.Start)
.width('100%')
})
Tabs({ barPosition: BarPosition.Start, controller: this.controller }) {
ForEach(this.tabArr, (item: ArticleTypeData, index: number) => {
TabContent() {
PeopleShipHomeArticleListComponent({
typeModel: item,
creatorId: this.creatorId,
currentTopSelectedIndex: this.currentIndex,
currentIndex: index
})
}
// }.tabBar(this.tabBuilder(index, item.name ?? ''))
})
}
.backgroundColor(Color.White)
.barWidth('100%')
.barHeight(0)
.vertical(false)
.height(DisplayUtils.getDeviceHeight() - 144)
.animationDuration(0)
.divider({
strokeWidth: '0.5vp',
color: $r('app.color.color_F5F5F5'),
startMargin: 0,
endMargin: 0
})
.onChange((index: number) => {
this.currentIndex = index
})
}
.backgroundColor(Color.White)
.barWidth('100%')
.barHeight('44vp')
.vertical(false)
.height(DisplayUtils.getDeviceHeight() - 100)
.animationDuration(0)
.divider({
strokeWidth: '0.5vp',
color: $r('app.color.color_F5F5F5'),
startMargin: 0,
endMargin: 0
})
.onChange((index: number) => {
this.currentIndex = index
})
}
}
@Builder
... ... @@ -70,21 +90,33 @@ export struct PeopleShipHomeListComponent {
}).height(DisplayUtils.getDeviceHeight() - this.topHeight)
}
@Builder tabBuilder(index: number, name: string) {
// 单独的页签
@Builder
Tab(index: number, name: string) {
Column() {
Text(name)
.fontColor(this.currentIndex === index ? $r('app.color.color_222222') : $r('app.color.color_666666') )
.fontColor(this.currentIndex === index ? $r('app.color.color_222222') : $r('app.color.color_666666'))
.fontSize(18)
.fontWeight(this.currentIndex === index ? 500 : 400)
.lineHeight(22)
.height(22)
.margin({ top: 11, bottom: 1 })
Divider()
.width('15vp')
.strokeWidth(2)
.color('#CB0000')
.opacity(this.currentIndex === index ? 1 : 0)
}.width('100%')
}
.justifyContent(FlexAlign.Center)
.constraintSize({ minWidth: 35 })
.margin({
left: '16vp',
right: '16vp'
})
.height('44vp')
.onClick(() => {
this.controller.changeIndex(index)
this.currentIndex = index
})
}
async aboutToAppear() {
... ...
... ... @@ -13,6 +13,7 @@ import MineSettingDatasModel from '../../model/MineSettingDatasModel';
import { MineMainSettingFunctionItem } from '../../viewmodel/MineMainSettingFunctionItem';
import common from '@ohos.app.ability.common';
import dataPreferences from '@ohos.data.preferences';
import { TitleBackComponent } from './TitleBackComponent';
@Component
export struct MineSettingComponent {
... ... @@ -67,11 +68,15 @@ export struct MineSettingComponent {
}
build() {
Navigation() {
//滑动区域
// Navigation() {
// //滑动区域
// this.settingList()
// }.titleMode(NavigationTitleMode.Mini)
// .title('设置')
Column(){
TitleBackComponent({title:"设置"})
this.settingList()
}.titleMode(NavigationTitleMode.Mini)
.title('设置')
}
}
// // 页面布局
... ... @@ -159,7 +164,7 @@ export struct MineSettingComponent {
})
}.onScrollFrameBegin((offset, state) => {
return { offsetRemain: 0 }
})
}).divider({strokeWidth:1,color:"#f0f0f0",startMargin: 15,endMargin: 10})
}
.backgroundColor(Color.White)
.borderRadius(8)
... ... @@ -203,7 +208,7 @@ export struct MineSettingComponent {
Toggle({ type: ToggleType.Switch, isOn: item.switchState })
.height('50lpx')
.margin({ left: '81lpx', right: '29lpx' })
.selectedColor(Color.Pink)
.selectedColor("#ED2800")
.onChange((isOn: boolean) => {
if(item.itemType=='push_switch'){
//推送
... ... @@ -251,7 +256,7 @@ export struct MineSettingComponent {
// 右侧文案和右箭头
Row() {
Text((item.title=='清除缓存') ? this.cacheSize.toFixed(2) + 'MB' : '')
Text((item.itemType=='clear_cache') ? this.cacheSize.toFixed(2) + 'MB' : '')
.fontColor('#999999')
.maxLines(1)
Image($r('app.media.mine_user_arrow'))
... ... @@ -270,14 +275,14 @@ export struct MineSettingComponent {
}
.height('54lpx')
.onClick(() => {
if (item.title == '账户与安全') {
if (item.itemType == 'account') {
let params: Params = {
pageID: 'AccountAndSecurityLayout'
}
WDRouterRule.jumpWithPage(WDRouterPage.settingPage, params)
} else if (item.title == '隐私设罝') {
} else if (item.itemType == 'private_setting') {
WDRouterRule.jumpWithPage(WDRouterPage.privacySettingPage)
} else if (item.title == '清除缓存') {
} else if (item.itemType == 'clear_cache') {
this.dialogController.open()
}
})
... ...
import { router } from '@kit.ArkUI'
@Component
export struct TitleBackComponent {
@State title: string = ''
build() {
RelativeContainer() {
Text(this.title)
.fontColor('#FF333333')
.fontSize(18)
.textAlign(TextAlign.Center)
.height(44)
.alignRules({
top: { anchor: "__container__", align: VerticalAlign.Top },
left: { anchor: "__container__", align: HorizontalAlign.Start },
right: { anchor: "__container__", align: HorizontalAlign.End },
})
.id('titleContent')
Image($r('app.media.back_icon'))
.objectFit(ImageFit.Auto)
.height(24)
.width(24)
.margin({
left: 16, top: 8
})
.alignRules({
top: { anchor: "__container__", align: VerticalAlign.Top },
left: { anchor: "__container__", align: HorizontalAlign.Start },
})
.onClick(() => {
router.back()
})
.id('backImage')
}.height(44)
}
}
\ No newline at end of file
... ...
... ... @@ -119,10 +119,12 @@ export struct EmptyComponent {
noProgrammeData() {
Column() {
Image(this.buildNoDataTipImage())
.width('this.EMPTY_IMAGE_WIDTH')
.height(this.EMPTY_IMAGE_HEIGHT)
.width(160)
.height(112)
.objectFit(ImageFit.Contain)
// .border({ width: 1, color: Color.Red, radius: 6 })
// .width('this.EMPTY_IMAGE_WIDTH')
// .height(this.EMPTY_IMAGE_HEIGHT)
Text(this.emptyType !== 8 ? this.buildNoDataTip() : `${this.buildNoDataTip()}(${this.timeNum}s)`)
.fontSize($r('app.float.normal_text_size'))
... ... @@ -185,6 +187,8 @@ export struct EmptyComponent {
contentString = '获取内容失败请重试' // 前方拥堵,请耐心等待
} else if (this.emptyType === WDViewDefaultType.WDViewDefaultType_NoContent1) {
contentString = '暂无内容'
} else if (this.emptyType === WDViewDefaultType.WDViewDefaultType_NoFollow) {
contentString = '暂无关注'
}
return contentString
... ... @@ -215,7 +219,7 @@ export struct EmptyComponent {
imageString = $r('app.media.icon_no_master1')
} else if (this.emptyType === WDViewDefaultType.WDViewDefaultType_NoVideo) {
imageString = $r('app.media.icon_no_content')
} else if (this.emptyType === WDViewDefaultType.WDViewDefaultType_NoContent1) {
} else if (this.emptyType === WDViewDefaultType.WDViewDefaultType_NoContent1 || this.emptyType === WDViewDefaultType.WDViewDefaultType_NoFollow) {
imageString = $r('app.media.icon_no_appointmentMade1')
}
return imageString
... ...
... ... @@ -52,7 +52,7 @@ class MineSettingDatasModel{
let suspensionState=SPHelper.default.getSync(SpConstants.SETTING_SUSPENSION_SWITCH,false) as boolean
this.mainSettingData.push(new MineMainSettingFunctionItem(null, '开启播放器悬浮窗', null, 1, suspensionState,"suspensionState_switch"))
this.mainSettingData.push(new MineMainSettingFunctionItem(null, null, null, 2, null,""))
this.mainSettingData.push(new MineMainSettingFunctionItem(null, '清除缓存', '32MB', 0, false,""))
this.mainSettingData.push(new MineMainSettingFunctionItem(null, '清除缓存', '32MB', 0, false,"clear_cache"))
this.mainSettingData.push(new MineMainSettingFunctionItem(null, '评价我们', null, 0, false,""))
return this.mainSettingData
... ...
import { DateFormatUtil, WDPlayerController, WDPlayerRenderLiveView } from 'wdPlayer/Index';
import router from '@ohos.router';
import { StringUtils } from 'wdKit/Index';
import { Action } from 'wdBean';
const TAG = 'VideoPlayPage';
@Entry
@Component
export struct VideoPlayPage {
//是否处于播放状态中
@State isPlayStatus: boolean = true
playerController: WDPlayerController = new WDPlayerController();
//视频地址
@State videoUrl: string = ''
//封面图
@State videoCoverUrl: string = ''
@State currentTime: string = ''
@State totalTime: string = ''
@State progressVal: number = 0;
aboutToAppear(): void {
let par: Action = router.getParams() as Action
let params = par?.params
this.videoUrl = params?.videoUrl ? params?.videoUrl : ''
this.videoCoverUrl = params?.videoCoverUrl ? params?.videoCoverUrl : ''
//播放进度监听
this.playerController.onTimeUpdate = (position: number, duration: number) => {
this.currentTime = DateFormatUtil.secondToTime(Math.floor(position / 1000));
this.totalTime = DateFormatUtil.secondToTime(Math.floor(duration / 1000));
this.progressVal = Math.floor(position * 100 / duration);
}
this.playerController.onCanplay = () => {
this.playerController.play()
}
}
build() {
Stack() {
WDPlayerRenderLiveView({
playerController: this.playerController,
onLoad: async () => {
this.playerController.firstPlay(this.videoUrl)
}
})
.height('100%')
.width('100%')
.visibility(StringUtils.isEmpty(this.videoUrl) ? Visibility.None : Visibility.Visible)
Image(this.videoCoverUrl)
.objectFit(ImageFit.Contain)
.visibility(StringUtils.isEmpty(this.videoUrl) ? Visibility.Visible : Visibility.None)
Column() {
this.getTopUIComponent()
Stack()
.layoutWeight(1)
this.getBottomUIComponent()
}
}
.width('100%')
}
@Builder
getTopUIComponent() {
Column() {
Row() {
Image($r('app.media.icon_arrow_left_white'))
.width(24)
.aspectRatio(1)
.margin({
right: 10
})
.onClick(() => {
router.back()
})
}
.width('100%')
.alignItems(VerticalAlign.Center)
.margin({
bottom: 10
})
}.width('100%')
.padding({
top: 20,
bottom: 6,
left: 10,
right: 10
})
.alignItems(HorizontalAlign.Start)
}
@Builder
getBottomUIComponent() {
Row() {
this.playOrPauseBtn()
Text(this.currentTime)
.fontColor(Color.White)
.fontWeight(600)
.fontSize('12fp')
.margin({
left: 16
})
this.playProgressView()
Text(this.totalTime)
.fontColor(Color.White)
.fontWeight(600)
.fontSize('12fp')
.margin({
right: 16
})
}
.alignItems(VerticalAlign.Center)
.width('100%')
.padding({
left: 10,
right: 10,
top: 15,
bottom: 15
})
}
@Builder
playOrPauseBtn() {
//暂停、播放
Image(this.isPlayStatus ? $r('app.media.icon_live_player_pause') : $r('app.media.player_play_ic'))
.width(24)
.height(24)
.onClick(() => {
if (this.isPlayStatus) {
this.isPlayStatus = false
this.playerController.pause()
} else {
this.isPlayStatus = true
this.playerController.play()
}
})
}
@Builder
playProgressView() {
Slider({
value: this.progressVal,
step: 1,
style: SliderStyle.OutSet
})
.blockSize({
width: 18,
height: 12
})
.blockStyle({
type: SliderBlockType.IMAGE,
image: $r('app.media.ic_player_block')
})
.blockColor(Color.White)
.trackColor('#4DFFFFFF')
.selectedColor('#FFED2800')
.height(14)
.trackThickness(1)
.layoutWeight(1)
.margin({
left: 8,
right: 8
})
.onChange((value: number, mode: SliderChangeMode) => {
this.playerController?.setSeekTime(value, mode);
})
}
onPageHide(): void {
this.playerController?.pause()
this.playerController?.stop()
}
}
\ No newline at end of file
... ...
... ... @@ -21,7 +21,8 @@ import {
postExecuteCollectRecordParams,
postExecuteLikeParams,
postInteractAccentionOperateParams,
postRecommendListParams
postRecommendListParams,
postThemeListParams
} from 'wdBean';
import { PageUIReqBean } from '../components/page/bean/PageUIReqBean';
... ... @@ -422,4 +423,17 @@ export class PageRepository {
Logger.info(TAG, "getPageUrl url = " + url)
return url;
}
/**
* 获取金刚位聚合页列表
* https://pdapis.pdnews.cn/api/display/zh/c/themeList
* @param params
* @returns
* */
static postThemeList(params: postThemeListParams) {
let url = HttpUrlUtils.getThemeListUrl()
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
Logger.info(TAG, "postThemeList url = " + url + JSON.stringify(params))
return WDHttp.post<ResponseDTO<LiveReviewDTO>>(url, params, headers)
};
}
... ...
... ... @@ -2,7 +2,7 @@ import HashMap from '@ohos.util.HashMap';
import { HttpUrlUtils, ResponseDTO } from 'wdNetwork';
import { HttpRequest } from 'wdNetwork/src/main/ets/http/HttpRequest';
import { Logger, ToastUtils } from 'wdKit';
import { LiveDetailsBean } from 'wdBean/Index';
import { LiveDetailsBean, ReserveBean } from 'wdBean/Index';
const TAG = 'LiveModel'
... ... @@ -66,5 +66,34 @@ export class LiveModel {
})
})
}
/**
* 查询预约状态
*
[{"relationId":"500002824823","liveId":"20000120522"},{"relationId":"500002845517","liveId":"20000120782"}]
* @returns
* @returns
*/
static getAppointmentStatus(reserveBean: ReserveBean[]) {
// let params: Record<string, ArrayList<ReserveBean>> = {};
// params = reserveBean
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
return new Promise<ResponseDTO<string>>((success, fail) => {
HttpRequest.post<ResponseDTO<string>>(
HttpUrlUtils.getAppointmentStatusUrl(),
reserveBean,
headers).then((data: ResponseDTO<string>) => {
if (data.code != 0) {
fail(data.message)
ToastUtils.shortToast(data.message)
return
}
success(data)
}, (error: Error) => {
fail(error.message)
Logger.debug(TAG + ":error ", error.toString())
})
})
}
}
... ...
... ... @@ -5,6 +5,7 @@ import { closeRefresh } from '../utils/PullDownRefresh';
import PageModel from './PageModel';
import PageViewModel from './PageViewModel';
import { promptAction } from '@kit.ArkUI';
import { AdvRuleBean } from 'wdBean/src/main/ets/bean/adv/AdvsRuleBean';
const TAG = 'PageHelper';
... ... @@ -45,9 +46,50 @@ export class PageHelper {
return;
}
pageModel.pageInfo = pageInfo;
//解析广告资源
this.analysisAdvSource(pageModel);
this.parseGroup(pageModel)
}
/**
* 解析广告资源
* @param pageInfo
*/
analysisAdvSource(pageModel: PageModel) {
let pageInfo = pageModel.pageInfo
if (pageInfo.hasAdInfo === 1 && pageInfo.cornersAdv != null) {
// 优先展示展现中心广告
let cornersAdv = pageInfo.cornersAdv
} else if (pageInfo.cornersAdv2 != null && pageInfo.cornersAdv2.length > 0) {
// 广告中心-挂角广告信息
let cornersAdv2 = pageInfo.cornersAdv2
// 获取
let showCompAdvBean = cornersAdv2[0]
//
let slotInfo = showCompAdvBean.slotInfo;
let postion = slotInfo.position
if (postion == 0) {
//左边挂角
pageModel.pageLeftCornerAdv = showCompAdvBean
pageModel.isShowLeftAds = true
} else {
// 右边挂角
pageModel.pageRightCornerAdv = showCompAdvBean
pageModel.isShowRightAds = true
}
Logger.error("XXX", JSON.stringify(pageInfo.cornersAdv2))
}
}
async parseGroup(pageModel: PageModel) {
let pageInfo: PageInfoDTO = pageModel.pageInfo
pageModel.groupList = []
... ...
... ... @@ -4,6 +4,7 @@ import { ViewType } from 'wdConstant/src/main/ets/enum/ViewType';
import { RefreshConstants as Const } from '../utils/RefreshConstants';
import { PageUIReqBean } from '../components/page/bean/PageUIReqBean';
import { GroupInfoDTO, PageInfoDTO } from 'wdBean/src/main/ets/bean/navigation/PageInfoDTO';
import { CompAdvBean } from 'wdBean/src/main/ets/bean/adv/AdvsRuleBean';
/**
* 页面下拉刷新、上拉加载数据bean。
... ... @@ -50,6 +51,15 @@ export default class PageModel {
// keyGenerator相关字符串,用于刷新list布局
timestamp: String = '1';
//左右挂角广告对象
pageLeftCornerAdv:CompAdvBean = {} as CompAdvBean
isShowLeftAds : boolean = true;
pageRightCornerAdv:CompAdvBean = {} as CompAdvBean
isShowRightAds : boolean = true;
/**
* 简单复制业务数据
*/
... ...
... ... @@ -358,7 +358,7 @@ export class PageViewModel extends BaseViewModel {
async getLiveMoreUrl(type: number, pageNum: number, pageSize: number): Promise<LiveReviewDTO> {
return new Promise<LiveReviewDTO>((success, error) => {
Logger.info(TAG, `getLiveMoreUrl pageInfo start`);
PageRepository.fetchLiveMoreUrl(type,pageNum, pageSize).then((resDTO: ResponseDTO<LiveReviewDTO>) => {
PageRepository.fetchLiveMoreUrl(type, pageNum, pageSize).then((resDTO: ResponseDTO<LiveReviewDTO>) => {
if (!resDTO || !resDTO.data) {
Logger.error(TAG, 'getLiveMoreUrl then navResDTO is empty');
error('resDTO is empty');
... ... @@ -378,6 +378,30 @@ export class PageViewModel extends BaseViewModel {
})
})
}
async postThemeList(sort: number, pageNum: number, pageSize: number) : Promise<LiveReviewDTO> {
return new Promise<LiveReviewDTO>((success, error) => {
Logger.info(TAG, `postThemeList pageInfo start`);
PageRepository.postThemeList({ sort, pageNum, pageSize }).then((resDTO) => {
if (!resDTO || !resDTO.data) {
Logger.error(TAG, 'postThemeList then navResDTO is empty');
error('resDTO is empty');
return
}
if (resDTO.code != 0) {
Logger.error(TAG, `postThemeList then code:${resDTO.code}, message:${resDTO.message}`);
error('resDTO Response Code is failure');
return
}
// let navResStr = JSON.stringify(navResDTO);
Logger.info(TAG, "postThemeList then,navResDTO.timestamp:" + resDTO.timestamp, `${JSON.stringify(resDTO)}}`);
success(resDTO.data);
}).catch((err: Error) => {
Logger.error(TAG, `postThemeList catch, error.name : ${err.name}, error.message:${err.message}`);
error(err);
})
})
}
}
... ...
... ... @@ -121,11 +121,11 @@
"value": "#99636363"
},
{
"name":"color_648DF2",
"name": "color_648DF2",
"value": "#648DF2"
},
{
"name":"color_EEEEEE",
"name": "color_EEEEEE",
"value": "#EEEEEE"
},
{
... ... @@ -151,6 +151,10 @@
{
"name": "color_0D000000",
"value": "#0D000000"
},
{
"name": "res_color_general_000000_30",
"value": "#4D000000"
}
]
}
\ No newline at end of file
... ...
... ... @@ -209,6 +209,10 @@
"value": "3vp"
},
{
"name": "vp_2",
"value": "2vp"
},
{
"name": "vp_55",
"value": "55vp"
},
... ... @@ -225,6 +229,14 @@
"value": "16vp"
},
{
"name": "vp_28",
"value": "28vp"
},
{
"name": "vp_80",
"value": "80vp"
},
{
"name": "card_comp_pagePadding_lf",
"value": "16fp"
},
... ...
... ... @@ -48,5 +48,10 @@
"name": "reason_read_write_media",
"value": "user_grant"
}
,
{
"name": "comp_advertisement",
"value": "广告"
}
]
}
\ No newline at end of file
... ...
... ... @@ -19,6 +19,8 @@
"components/page/PeopleShipHomePage",
"pages/MultiPictureListPage",
"components/page/LiveMorePage",
"components/page/ReserveMorePage"
"components/page/ReserveMorePage",
"pages/VideoPlayPage",
"components/page/ThemeListPage"
]
}
\ No newline at end of file
... ...
import { LiveDetailsBean, LiveRoomItemBean } from 'wdBean/Index'
import { EmptyComponent, ErrorComponent, ListHasNoMoreDataUI, WDViewDefaultType } from 'wdComponent/Index'
import { EmptyComponent, ErrorComponent, WDViewDefaultType } from 'wdComponent/Index'
import CustomRefreshLoadLayout from 'wdComponent/src/main/ets/components/page/CustomRefreshLoadLayout'
import LoadMoreLayout from 'wdComponent/src/main/ets/components/page/LoadMoreLayout'
import RefreshLayout from 'wdComponent/src/main/ets/components/page/RefreshLayout'
import { RefreshLayoutBean } from 'wdComponent/src/main/ets/components/page/RefreshLayoutBean'
import PageModel from 'wdComponent/src/main/ets/viewmodel/PageModel'
import { ViewType } from 'wdConstant/Index'
import { Logger } from 'wdKit/Index'
import { LiveViewModel } from '../../viewModel/LiveViewModel'
import { TabChatItemComponent } from './TabChatItemComponent'
... ...
import { LiveDetailsBean, LiveRoomItemBean } from 'wdBean/Index'
import { EmptyComponent, ErrorComponent, ListHasNoMoreDataUI, WDViewDefaultType } from 'wdComponent/Index'
import { LiveViewModel } from '../../viewModel/LiveViewModel'
import { EmptyComponent, ErrorComponent, ListHasNoMoreDataUI,
WDViewDefaultType } from 'wdComponent/Index'
import { TabLiveItemComponent } from './TabLiveItemComponent'
import CustomRefreshLoadLayout from 'wdComponent/src/main/ets/components/page/CustomRefreshLoadLayout'
import { RefreshLayoutBean } from 'wdComponent/src/main/ets/components/page/RefreshLayoutBean'
... ... @@ -9,6 +9,7 @@ import { ViewType } from 'wdConstant/Index'
import LoadMoreLayout from 'wdComponent/src/main/ets/components/page/LoadMoreLayout'
import RefreshLayout from 'wdComponent/src/main/ets/components/page/RefreshLayout'
import { StringUtils } from 'wdKit/Index'
import { LiveViewModel } from '../../viewModel/LiveViewModel'
@Component
export struct TabLiveComponent {
... ... @@ -110,6 +111,7 @@ export struct TabLiveComponent {
liveRoomItemBeanTemp.senderUserName = '人民日报主持人'
liveRoomItemBeanTemp.pictureUrls=[]
liveRoomItemBeanTemp.pictureUrls.push(this.liveDetailsBean?.fullColumnImgUrls[0]?.url)
liveRoomItemBeanTemp.dataType='ZH_TEXT_AND_IMAGE_MSG'
this.liveList.push(liveRoomItemBeanTemp)
}
}
... ...
import { LiveRoomItemBean, PhotoListBean, } from 'wdBean/Index';
import { DateTimeUtils, StringUtils } from 'wdKit/Index';
import { Action, Params } from 'wdBean';
import { ExtraDTO } from 'wdBean/src/main/ets/bean/component/extra/ExtraDTO';
import { WDRouterRule } from 'wdRouter/Index';
import { Action, LiveRoomItemBean, Params, PhotoListBean } from 'wdBean/Index'
import { ExtraDTO } from 'wdBean/src/main/ets/bean/component/extra/ExtraDTO'
import { DateTimeUtils, StringUtils } from 'wdKit/Index'
import { WDRouterRule } from 'wdRouter/Index'
@Component
export struct TabLiveItemComponent {
... ... @@ -14,108 +13,190 @@ export struct TabLiveItemComponent {
}
build() {
Column() {
Row() {
Image(StringUtils.isEmpty(this.item.senderUserAvatarUrl) ? $r('app.media.default_head') : this.item.senderUserAvatarUrl)
.borderRadius(90)
.width(24)
.height(24)
Text(this.item.senderUserName)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
Row() {
Image(StringUtils.isEmpty(this.item.senderUserAvatarUrl) ? $r('app.media.default_head') : this.item.senderUserAvatarUrl)
.borderRadius(90)
.width(24)
.height(24)
Column() {
Row() {
Text(this.item.senderUserName)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize('14fp')
.fontWeight(400)
.fontColor('#222222')
Text('主持人')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize('11fp')
.fontWeight(400)
.fontColor('#968562')
.backgroundColor('#F1EFEB')
.padding({
left: 4,
top: 1,
right: 4,
bottom: 1
})
.borderRadius(2)
.margin({ left: 8 })
.visibility('host' == this.item.role ? Visibility.Visible : Visibility.None)
Text(DateTimeUtils.getCommentTime(new Date(this.item.time).getTime()))
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize('12fp')
.fontWeight(400)
.fontColor('#999999')
.margin({ left: 8 })
.visibility(StringUtils.isNotEmpty(this.item.time) ? Visibility.Visible : Visibility.None)
Text('置顶')
.fontSize('11fp')
.fontWeight(400)
.fontColor('#ED2800')
.backgroundColor('#F1EFEB')
.padding({
left: 4,
top: 1,
right: 4,
bottom: 1
})
.borderRadius(2)
.margin({ left: 8 })
.width(100)
.visibility(1 == this.item.isTop ? Visibility.Visible : Visibility.None)
}
Text(this.item.text)
.fontSize('14fp')
.fontWeight(400)
.fontColor('#222222')
.margin({ left: 8 })
Text('主持人')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize('11fp')
.fontWeight(400)
.fontColor('#968562')
.backgroundColor('#F1EFEB')
.padding({
left: 4,
top: 1,
right: 4,
bottom: 1
.margin({
top: 6
})
.borderRadius(2)
.margin({ left: 8 })
.visibility('host' == this.item.role ? Visibility.Visible : Visibility.None)
Text(DateTimeUtils.getCommentTime(new Date(this.item.time).getTime()))
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize('12fp')
.fontWeight(400)
.fontColor('#999999')
.margin({ left: 8 })
.visibility(StringUtils.isNotEmpty(this.item.time) ? Visibility.Visible : Visibility.None)
Blank()
Text('置顶')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize('11fp')
.fontWeight(400)
.fontColor('#ED2800')
.backgroundColor('#F1EFEB')
.padding({
left: 4,
top: 1,
right: 4,
bottom: 1
.width('100%')
.textAlign(TextAlign.Start)
//ZH_TEXT_AND_IMAGE_MSG :图文,ZH_TEXT_MSG:文本,ZH_VIDEO_MSG:视频,ZH_AUDIO_MSG:音频
//图文
if (this.item.dataType === 'ZH_TEXT_AND_IMAGE_MSG') {
List({ space: this.item.pictureUrls.length == 1 ? 0 : 5 }) {
ForEach(this.item.pictureUrls, (item: string, index: number) => {
ListItem() {
Image(item)
.width(`${100 / this.item.pictureUrls.length}%`)
.height(this.item.pictureUrls.length > 1 ? 70 : 174)
.objectFit(ImageFit.Auto)
.borderRadius(4)
}.onClick(() => {
this.photoList = []
for (let item of this.item.pictureUrls) {
this.photoList.push({
width: 0,
height: 0,
picPath: item,
picDesc: ''
})
}
this.gotoMultipleListImagePage()
})
})
}
.listDirection(Axis.Horizontal)
.margin({
top: 8,
right: 16
})
.borderRadius(2)
.margin({ left: 8 })
.visibility(1 == this.item.isTop ? Visibility.Visible : Visibility.None)
}
.width('100%')
Text(this.item.text)
.fontSize('14fp')
.fontWeight(400)
.fontColor('#222222')
.margin({
left: 32,
top: 6
})
.width('100%')
.textAlign(TextAlign.Start)
List() {
ForEach(this.item.pictureUrls, (item: string, index: number) => {
ListItem() {
Image(item)
.height(174)
.width(310)
.aspectRatio(310 / 174)
.objectFit(ImageFit.Auto)
.borderRadius(4)
}.onClick(() => {
this.photoList=[]
for (let item of this.item.pictureUrls) {
this.photoList.push({
width: 0,
height: 0,
picPath: item,
picDesc: ''
}
//音频
else if (this.item.dataType === 'ZH_AUDIO_MSG') {
Row() {
Image($r('app.media.icon_voice'))
.width(20)
.aspectRatio(1)
.margin({
left: 8,
right: 6
})
Text(DateTimeUtils.getFormattedDuration(this.item.duration))
.fontColor('#666666')
.fontWeight(400)
.fontSize('14fp')
}
.backgroundColor(Color.White)
.height(36)
.borderRadius(4)
.margin({ top: 8, right: 16 })
.width('100%')
}
//视频
else if (this.item.dataType === 'ZH_VIDEO_MSG') {
RelativeContainer() {
Image(this.item.transcodeImageUrl)
.width('100%')
.objectFit(ImageFit.Cover)
.borderRadius(4)
.id('iv_id')
Stack() {
Row()
.borderRadius(90)
.width(32)
.height(32)
.backgroundColor('#000000')
Image($r('app.media.player_play_ic'))
.height(16)
.aspectRatio(1)
}
this.gotoMultipleListImagePage()
.alignRules({
left: { anchor: "iv_id", align: HorizontalAlign.Start },
bottom: { anchor: "iv_id", align: VerticalAlign.Bottom }
})
.margin({
left: 12,
bottom: 12
})
.id('play_id')
}
.margin({
top: 8,
right: 16
})
.aspectRatio(Number.parseFloat(this.item.pictureResolutions[0]?.split('*')[0]) / Number.parseFloat(this.item.pictureResolutions[0]?.split('*')[1]))
.onClick(() => {
this.gotoVideoPlayPage()
})
})
}.margin({
left: 32,
top: 8
}
}
.margin({
left: 8,
right: 16
})
}.margin({
left: 15,
top: 15,
right: 15
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
}
.alignItems(VerticalAlign.Top)
.padding({
left: 17,
top: 8,
bottom: 8,
})
}
aboutToDisappear(): void {
/**
* @param content
* */
gotoVideoPlayPage() {
let taskAction: Action = {
type: 'JUMP_DETAIL_PAGE',
params: {
detailPageType: 19,
videoUrl: this.item.videoUrl,
videoCoverUrl: this.item.transcodeImageUrl
} as Params,
};
WDRouterRule.jumpWithAction(taskAction)
}
/**
... ... @@ -134,4 +215,8 @@ export struct TabLiveItemComponent {
};
WDRouterRule.jumpWithAction(taskAction)
}
aboutToDisappear(): void {
}
}
\ No newline at end of file
... ...
... ... @@ -269,7 +269,8 @@ export struct PlayUIComponent {
.blockSize({
width: 18,
height: 12
})// .blockStyle({
})
// .blockStyle({
// type: SliderBlockType.IMAGE,
// image: $r('app.media.ic_player_block')
// })
... ...
import mediaquery from '@ohos.mediaquery';
import { ContentDetailDTO, InteractDataDTO } from 'wdBean';
import { PlayerConstants, WDPlayerController, WDPlayerRenderView } from 'wdPlayer';
import { ContentDetailRequest, devicePLSensorManager } from 'wdDetailPlayApi';
import { PlayControlViewContainer } from '../view/PlayControlViewContainer';
import { PlayerDetailContainer } from '../view/PlayerDetailContainer';
import { DetailContainer } from '../view/DetailContainer';
import { ContentDetailRequest } from 'wdDetailPlayApi';
import {
batchLikeAndCollectParams,
batchLikeAndCollectResult,
... ... @@ -13,6 +9,8 @@ import {
} from 'wdDetailPlayApi/src/main/ets/request/ContentDetailRequest';
import { HttpUrlUtils } from 'wdNetwork/Index';
import { DateTimeUtils } from 'wdKit/Index';
import { PlayerBottomView } from '../view/PlayerBottomView';
import { PlayerRightView } from '../view/PlayerRightView';
const TAG = 'DetailPlayShortVideoPage';
... ... @@ -32,27 +30,30 @@ export struct DetailPlayShortVideoPage {
@Provide videoLandScape?: number = 1; // 视频朝向, 横屏视频:1;竖屏视频:2
@Provide newsStatusOfUser: batchLikeAndCollectResult | undefined = undefined // 点赞、收藏状态
@Provide followStatus: string = '0' // 关注状态
@Link @Watch('switchVideoStatusChange') switchVideoStatus: boolean
@Provide isOpenDetail: boolean = false // 查看详情按钮点击
@Provide isDragging: boolean = false // 拖动时间进度条
@Consume @Watch('pageShowChange') pageShow: number
@Consume @Watch('pageHideChange') pageHide: number
pageShowChange() {
if (this.currentIndex === this.index && this.playerController.getStatus() === PlayerConstants.STATUS_PAUSE) {
this.playerController.play()
this.queryNewsInfoOfUser()
}
}
/**
* 直播频道从其他频道切换回来需要继续播放视频
*/
switchVideoStatusChange() {
if (this.switchVideoStatus) {
if (this.currentIndex === this.index && this.playerController.getStatus() === PlayerConstants.STATUS_PAUSE) {
this.playerController.play()
}
} else {
if (this.currentIndex === this.index && this.playerController.getStatus() === PlayerConstants.STATUS_START) {
this.playerController.pause()
}
pageHideChange() {
if (this.currentIndex === this.index && this.playerController.getStatus() === PlayerConstants.STATUS_START) {
this.playerController.pause()
}
}
/**
* 监听下标变化手动创建或销毁视频
*/
currentIndexChange() {
if (this.currentIndex != this.index) {
this.playerController.pause()
if (this.index < this.currentIndex - 3 && this.playerController.getPlayer()) {
this.playerController.release()
}
... ... @@ -64,12 +65,11 @@ export struct DetailPlayShortVideoPage {
} else {
this.playerController.play()
}
}
}
/**
* 查询用户点赞、收藏、关注等状态
* 查询用户点赞、收藏、关注状态、记录浏览历史
*/
queryNewsInfoOfUser() {
if (HttpUrlUtils.getUserId()) {
... ... @@ -100,7 +100,7 @@ export struct DetailPlayShortVideoPage {
}
})
// 记录浏览历史
// 记录浏览历史
const params2: postInteractBrowsOperateParams = {
delStatus: 0,
contentList: [{
... ... @@ -118,51 +118,41 @@ export struct DetailPlayShortVideoPage {
}
aboutToAppear() {
// console.log('开始设置setContentDetailData', JSON.stringify(this.contentDetailData))
this.videoLandScape = this.contentDetailData?.videoInfo[0]?.videoLandScape
this.queryNewsInfoOfUser()
this.playerController.onCanplay = () => {
if (this.index == 0 || this.currentIndex === this.index) {
this.playerController.play()
}
}
this.playerController.onTimeUpdate = (position, duration) => {
this.progressVal = Math.floor(position * 100 / duration);
}
// 设置播放地址
let listener = mediaquery.matchMediaSync('(orientation: landscape)');
listener.on("change", (mediaQueryResult) => {
if (mediaQueryResult.matches) {
console.log("横屏 yes")
this.isFullScreen = true
} else {
this.isFullScreen = false
console.log("横屏 no")
}
// WindowModel.shared.setMainWindowFullScreen(this.isFullScreen)
})
}
onPageShow() {
// this.playerController?.play();
// WindowModel.shared.setPreferredOrientation(window.Orientation.AUTO_ROTATION_RESTRICTED);
this.queryNewsInfoOfUser()
}
aboutToDisappear(): void {
console.log('aboutToDisappear', this.index)
console.log(TAG, 'aboutToDisappear', this.index)
this.playerController?.pause()
this.playerController?.release();
}
onPageHide() {
this.playerController?.pause();
build() {
Stack({ alignContent: Alignment.Top }) {
this.playerViewBuilder()
PlayerBottomView({
playerController: this.playerController
})
PlayerRightView({
playerController: this.playerController
})
}
.height('100%')
.width('100%')
}
@Builder
playerViewContainerBuilder() {
playerViewBuilder() {
// 播放窗口
WDPlayerRenderView({
playerController: this.playerController,
... ... @@ -181,36 +171,4 @@ export struct DetailPlayShortVideoPage {
this.playerController?.switchPlayOrPause();
})
}
@Builder
playControlViewContainerBuilder() {
// 播放窗口控制bar
PlayControlViewContainer({
playerController: this.playerController
})
}
@Builder
detailContainerBuilder() {
DetailContainer({
playerController: this.playerController
})
}
build() {
Column() {
PlayerDetailContainer({
playerView: () => {
this.playerViewContainerBuilder()
}, playControlView: () => {
// this.playControlViewContainerBuilder()
}, detailView: () => {
this.detailContainerBuilder()
}
})
}
.height('100%')
.width('100%')
}
}
\ No newline at end of file
... ...
... ... @@ -16,7 +16,12 @@ export struct DetailVideoListPage {
private relId: string = ''
private relType: string = ''
private swiperController: SwiperController = new SwiperController()
@Provide bottomSafeHeight: number = AppStorage.get<number>('bottomSafeHeight') || 0
@Provide topSafeHeight: number = AppStorage.get<number>('topSafeHeight') || 0
@Provide windowWidth: number = AppStorage.get<number>('windowWidth') || 0
@Provide showComment: boolean = true
@Provide pageShow: number = -1
@Provide pageHide: number = -1
@State data: ContentDetailDTO[] = []
@State testData: string[] = ['111', '222', '333']
@State currentIndex: number = 0
... ... @@ -48,17 +53,17 @@ export struct DetailVideoListPage {
this.closeFullScreen()
}
// page show/hide只能在外层组件触发
onPageShow(): void {
console.log(TAG, 'onPageShow')
this.pageShow = Math.random()
this.openFullScreen()
console.log('getWindowProperties', JSON.stringify(WindowModel.shared.getWindowProperties()))
}
onPageHide(): void {
console.log(TAG, 'onPageHide')
this.pageHide = Math.random()
this.closeFullScreen()
}
... ... @@ -68,7 +73,7 @@ export struct DetailVideoListPage {
*/
openFullScreen() {
WindowModel.shared.setWindowSystemBarProperties({ statusBarContentColor: '#ffffff', })
// WindowModel.shared.setWindowLayoutFullScreen(true)
WindowModel.shared.setWindowLayoutFullScreen(true)
// WindowModel.shared.setWindowSystemBarEnable([])
}
... ... @@ -78,7 +83,7 @@ export struct DetailVideoListPage {
*/
closeFullScreen() {
WindowModel.shared.setWindowSystemBarProperties({ statusBarContentColor: '#000000', })
// WindowModel.shared.setWindowLayoutFullScreen(false)
WindowModel.shared.setWindowLayoutFullScreen(false)
// WindowModel.shared.setWindowSystemBarEnable(['status', 'navigation'])
}
... ... @@ -105,6 +110,7 @@ export struct DetailVideoListPage {
}).then(res => {
if (res.data) {
this.data = this.data.concat(res.data)
console.log('视频列表===', JSON.stringify(res.data))
}
})
}
... ... @@ -138,7 +144,6 @@ export struct DetailVideoListPage {
Swiper(this.swiperController) {
ForEach(this.data, (item: ContentDetailDTO, index: number) => {
DetailPlayShortVideoPage({
switchVideoStatus: $switchVideoStatus,
contentDetailData: item,
currentIndex: this.currentIndex,
index: index,
... ... @@ -155,9 +160,8 @@ export struct DetailVideoListPage {
.displayCount(1, true)
.onChange((index: number) => {
this.currentIndex = index
console.info('onChange==', index.toString())
if (this.currentIndex === this.data.length - 1) {
// TODO:下拉刷新“努力加载中”
this.queryVideoList()
}
})
... ... @@ -165,6 +169,9 @@ export struct DetailVideoListPage {
.width('100%')
.height('100%')
.backgroundColor(Color.Black)
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM, SafeAreaEdge.START, SafeAreaEdge.END])
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
.padding({
bottom: this.bottomSafeHeight + 'px'
})
}
}
\ No newline at end of file
... ...
export class PlayerConstants {
static readonly STATUS_IDLE: number = 0;
static readonly STATUS_START: number = 1;
static readonly STATUS_PAUSE: number = 2;
static readonly STATUS_STOP: number = 3;
}
@Preview
@Component
export struct Test {
build() {
Row() {
RelativeContainer() {
Image($r('app.media.ic_like_uncheck'))
.width('100%')
.borderRadius(24)
.aspectRatio(1)
.border({ width: 1, color: Color.White, style: BorderStyle.Solid })
.alignRules({
top: { anchor: "__container__", align: VerticalAlign.Top },
left: { anchor: "__container__", align: HorizontalAlign.Start }
})
.id("row1")
Image($r('app.media.ic_add'))
.width(24)
.borderRadius(12)
.alignRules({
left: { anchor: "__container__", align: HorizontalAlign.Center },
bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
})
.margin({ left: -12 })
.id("row2")
}.height('auto')
@State progressVal: number = 10;
@State status: number = PlayerConstants.STATUS_PAUSE;
padding1(num: string) {
let length = 2;
for (let len = (num.toString()).length; len < length; len = num.length) {
num = `${'0'}${num}`;
}
return num;
}
secondToTime(seconds: number) {
let time = '00:00'
let hourUnit = 60 * 60;
let hour = Math.floor(seconds / hourUnit);
let minute = Math.floor((seconds - hour * hourUnit) / 60);
let second = seconds - hour * hourUnit - minute * 60;
if (hour > 0) {
return `${this.padding1(hour.toString())}${':'}${this.padding1(minute.toString())}${':'}${this.padding1(second.toString())}`;
}
if (minute > 0) {
return `${this.padding1(minute.toString())}${':'}${this.padding1(second.toString())}`;
} else {
return `${'00'}${':'}${this.padding1(second.toString())}`;
}
.height(58)
.width(48)
.backgroundColor(Color.Black)
}
build() {
Column() {
Text() {
Span(this.secondToTime(6))
Span(' / ')
Span('00:06')
}
.fontSize(24)
.fontColor(Color.White)
.fontWeight(600)
.margin({ bottom: 30 })
// .visibility(Visibility.None)
Slider({
value: this.progressVal,
step: 0.01,
// style: SliderStyle.OutSet
})
.blockColor(this.status === PlayerConstants.STATUS_START ? Color.Transparent : $r('app.color.play_block_color'))
.trackColor(this.status === PlayerConstants.STATUS_START ? $r('app.color.play_track_color') : $r('app.color.pause_track_color'))
.selectedColor(this.status === PlayerConstants.STATUS_START ? $r('app.color.play_selected_color') : $r('app.color.pause_selected_color'))
.trackThickness(this.status === PlayerConstants.STATUS_START ? 1 : 4)
.blockStyle({
type: this.status === PlayerConstants.STATUS_START ? SliderBlockType.DEFAULT : SliderBlockType.IMAGE,
image: $r('app.media.ic_player_block')
})
.blockSize({ width: 18, height: 12 })
.width('100%')// .height(19)
.onChange((value: number, mode: SliderChangeMode) => {
// this.playerController?.setSeekTime(Math.floor(value), mode);
})
}
.backgroundColor(Color.Blue)
.height('100%')
}
}
\ No newline at end of file
... ...
... ... @@ -25,7 +25,9 @@ interface loadMoreData {
const TAG = 'VideoChannelDetail'
let timer: number = -1
@Entry
const storage = LocalStorage.getShared();
@Entry(storage)
@Component
export struct VideoChannelDetail {
private groupId: string = '' // 楼层id
... ... @@ -43,6 +45,7 @@ export struct VideoChannelDetail {
@Link barBackgroundColor: Color
private swiperController: SwiperController = new SwiperController()
@Provide showComment: boolean = false
@Provide windowWidth: number = AppStorage.get<number>('windowWidth') || 0
@State data: ContentDetailDTO[] = []
@State currentIndex: number = 0
@State interactDataList: InteractDataDTO[] = []
... ... @@ -216,7 +219,6 @@ export struct VideoChannelDetail {
ForEach(this.data, (item: ContentDetailDTO, index: number) => {
Column() {
DetailPlayShortVideoPage({
switchVideoStatus: $switchVideoStatus,
contentDetailData: item,
currentIndex: this.currentIndex,
index: index,
... ...
@Preview
@CustomDialog
export struct DetailDialog {
controller: CustomDialogController
@Prop name: string
@Prop title: string
@Prop summary: string
@Link isOpen: boolean
@Link isOpenDetail: boolean
build() {
Column() {
if (this.name + '1222222') {
Text(`@${this.name}` + '1222222')
if (this.name) {
Text(`@${this.name}`)
.fontColor(Color.White)
.fontSize(14)
.fontWeight(600)
.lineHeight(17)
.margin({ top: 8 })
}
if (this.title) {
... ... @@ -36,8 +38,8 @@ export struct DetailDialog {
Image($r('app.media.ic_close'))
.height(24).margin({ top: 20 }).onClick(() => {
this.controller.close()
if (this.isOpen) {
this.isOpen = !this.isOpen
if (this.isOpenDetail) {
this.isOpenDetail = !this.isOpenDetail
}
})
}.width('100%').justifyContent(FlexAlign.Center)
... ...
import { WDPlayerController } from 'wdPlayer/Index';
import { PlayerTitleView } from './PlayerTitleView'
import { PlayerProgressView } from './PlayerProgressView'
import { PlayerCommentView } from './PlayerCommentView'
import { PlayerTimeSeekView } from './PlayerTimeSeekView'
@Component
export struct PlayerBottomView {
private playerController?: WDPlayerController;
@Consume showComment?: boolean
@Consume isOpenDetail?: boolean
@Consume isDragging?: boolean
build() {
Column() {
PlayerTitleView()
PlayerProgressView({ playerController: this.playerController })
if (this.showComment) {
PlayerCommentView()
}
}
.alignItems(HorizontalAlign.Start)
.position({ x: 0, y: '100%' })
.markAnchor({ y: '100%' })
}
}
\ No newline at end of file
... ...
import router from '@ohos.router';
@Component
export struct PlayerCommentView {
@Consume showComment?: boolean
@Consume isOpenDetail?: boolean
@State comment: string = '';
build() {
Row() {
Image($r('app.media.ic_back'))
.width(24)
.height(24)
.aspectRatio(1)
.onClick(() => {
router.back();
})
TextInput({ placeholder: '说两句...', text: this.comment })
.placeholderColor(Color.White)
.placeholderFont({ size: 14 })
.fontColor(Color.White)
.fontSize(14)
.maxLines(1)
.layoutWeight(1)
.backgroundColor('#1a1a1a')
.borderRadius(2)
.height(30)
.margin({ left: 12 })
}
.backgroundColor(Color.Black)
.alignItems(VerticalAlign.Center)
.padding({ left: 16, right: 16, top: 11, bottom: 11 })
.visibility(this.isOpenDetail ? Visibility.None : Visibility.Visible)
}
}
\ No newline at end of file
... ...
... ... @@ -14,51 +14,6 @@ export struct PlayerDetailContainer {
console.log(`PlayerDetailContainer aboutToAppear`)
}
buildVideoHeight() {
let videoHeight: string | number = 200
if (this.videoLandScape == 2) {
videoHeight = '100%'
} else {
videoHeight = 200
}
console.log(`PlayerDetailContainer buildVideoHeight:${videoHeight} `)
return videoHeight
}
buildVideoTo() {
let videoTop: number;
if (this.videoLandScape == 2) {
videoTop = 0
} else {
videoTop = 174
}
console.log(`PlayerDetailContainer videoTop:${videoTop} `)
return videoTop
}
buildVideoBottom() {
let videoBottom: number;
if (this.videoLandScape == 2) {
videoBottom = 0
} else {
videoBottom = 320
}
console.log(`PlayerDetailContainer buildVideoBottom:${videoBottom} `)
return videoBottom
}
isShowBottomView() {
console.log(`PlayerDetailContainer videoLandScape:${this.videoLandScape} `)
let isShowBottom: boolean = false
if (this.isFullScreen) {
isShowBottom = false
} else {
isShowBottom = true
}
console.log(`PlayerDetailContainer isShowBottom:${isShowBottom} `)
return isShowBottom
}
build() {
Stack() {
this.playerView()
... ...
import { ContentDetailDTO } from 'wdBean/Index';
import { DateTimeUtils } from 'wdKit/Index';
import { PlayerConstants, WDPlayerController } from 'wdPlayer/Index';
@Component
export struct PlayerProgressView {
private playerController?: WDPlayerController;
@Consume contentDetailData: ContentDetailDTO
@Consume progressVal: number;
@Consume isOpenDetail: boolean
@Consume isDragging: boolean
@State status: number = PlayerConstants.STATUS_START;
aboutToAppear() {
if (this.playerController) {
this.playerController.onStatusChange = (status: number) => {
this.status = status
console.log('=============', this.status)
}
}
}
build() {
Column() {
Text() {
Span(DateTimeUtils.secondToTime(Math.floor(this.progressVal / 100 * this.contentDetailData.videoInfo[0].videoDuration)))
Span(' / ')
Span(DateTimeUtils.secondToTime(this.contentDetailData.videoInfo[0].videoDuration || 0))
}
.fontSize(24)
.fontColor(Color.White)
.fontWeight(600)
.margin({ bottom: 30 })
.visibility(this.isDragging ? Visibility.Visible : Visibility.None)
Slider({
value: this.progressVal,
step: 0.01,
// style: SliderStyle.OutSet
})
.blockColor(this.status === PlayerConstants.STATUS_PAUSE || this.isDragging ? $r('app.color.play_block_color') : Color.Transparent)
.trackColor(this.status === PlayerConstants.STATUS_PAUSE || this.isDragging ? $r('app.color.pause_track_color') : $r('app.color.play_track_color'))
.selectedColor(this.status === PlayerConstants.STATUS_PAUSE || this.isDragging ? $r('app.color.pause_selected_color') : $r('app.color.play_selected_color'))
.trackThickness(this.status === PlayerConstants.STATUS_PAUSE || this.isDragging ? 4 : 1)
.blockStyle({
type: this.status === PlayerConstants.STATUS_PAUSE || this.isDragging ? SliderBlockType.IMAGE : SliderBlockType.DEFAULT,
image: $r('app.media.ic_player_block')
})
.blockSize({ width: 18, height: 12 })
.width('100%')
.height(19)
.onChange((value: number, mode: SliderChangeMode) => {
this.progressVal = value
if (mode === SliderChangeMode.Moving) {
this.isDragging = true
}
if (mode === SliderChangeMode.End) {
this.isDragging = false
}
this.playerController?.setSeekTime(value, mode);
console.log('slider onChange:', value, mode)
})
}.visibility(this.isOpenDetail ? Visibility.None : Visibility.Visible)
}
}
\ No newline at end of file
... ...
import { ContentDetailDTO, InteractDataDTO, Params, RmhInfoDTO, UserInfoDTO } from 'wdBean/Index';
import {
batchLikeAndCollectParams,
batchLikeAndCollectResult,
ContentDetailRequest,
contentListParams,
postExecuteCollectRecordParams,
postExecuteLikeParams,
postInteractAccentionOperateParams
} from 'wdDetailPlayApi/src/main/ets/request/ContentDetailRequest';
import { SPHelper, ToastUtils } from 'wdKit';
import { HttpUrlUtils } from 'wdNetwork/Index';
import { WDPlayerController } from 'wdPlayer/Index';
import { WDRouterPage, WDRouterRule } from 'wdRouter/Index';
import { SpConstants } from 'wdConstant/Index'
export interface OperationItem {
icon: Resource;
icon_check?: Resource;
// icon_selected: Resource;
text: string | Resource;
num?: number; // 个数
}
const TAG = 'PlayerRightView';
@Component
export struct PlayerRightView {
private playerController?: WDPlayerController;
@Consume interactData: InteractDataDTO
@Consume contentDetailData: ContentDetailDTO
@Consume newsStatusOfUser: batchLikeAndCollectResult
@Consume followStatus: string
@Consume isOpenDetail: boolean
@Consume isDragging: boolean
@State operationList: OperationItem[] = [
{
icon: $r('app.media.ic_like_uncheck'),
icon_check: $r('app.media.ic_like_check'),
text: "赞",
// num: 6622
},
{
icon: $r('app.media.ic_collect_uncheck'),
icon_check: $r('app.media.ic_collect_check'),
text: "收藏",
// num: 662,
},
{
icon: $r('app.media.ic_comment'),
text: "抢首评",
// num: 500,
},
{
icon: $r('app.media.ic_share'),
text: "分享"
}
]
aboutToAppear() {
}
/**
* 点赞、取消点赞
*/
async toggleLikeStatus() {
// 未登录,跳转登录
const user_id = await SPHelper.default.get(SpConstants.USER_ID, '')
if (!user_id) {
this.playerController?.pause()
WDRouterRule.jumpWithPage(WDRouterPage.loginPage)
return
}
const params: postExecuteLikeParams = {
status: this.newsStatusOfUser?.likeStatus === '1' ? '0' : '1',
contentId: this.contentDetailData?.newsId + '',
contentType: this.contentDetailData?.newsType + '',
}
ContentDetailRequest.postExecuteLike(params).then(res => {
if (this.newsStatusOfUser) {
this.newsStatusOfUser.likeStatus = this.newsStatusOfUser?.likeStatus === '1' ? '0' : '1'
if (this.newsStatusOfUser.likeStatus === '1') {
this.interactData.likeNum = Number(this.interactData.likeNum) + 1
} else {
this.interactData.likeNum = Number(this.interactData.likeNum) - 1
}
console.log('点赞、取消点赞==', this.newsStatusOfUser?.likeStatus, this.interactData?.likeNum)
// this.queryContentInteractCount()
}
})
}
/**
* 收藏、取消收藏
*/
async toggleCollectStatus() {
// 未登录,跳转登录
const user_id = await SPHelper.default.get(SpConstants.USER_ID, '')
if (!user_id) {
WDRouterRule.jumpWithPage(WDRouterPage.loginPage)
return
}
const params: postExecuteCollectRecordParams = {
status: this.newsStatusOfUser?.collectStatus === 1 ? '0' : '1',
contentList: [{
contentId: this.contentDetailData?.newsId + '',
contentType: this.contentDetailData?.newsType + '',
}],
}
ContentDetailRequest.postExecuteCollectRecord(params).then(res => {
if (this.newsStatusOfUser) {
this.newsStatusOfUser.collectStatus = this.newsStatusOfUser?.collectStatus === 1 ? 0 : 1
// this.queryContentInteractCount()
if (this.newsStatusOfUser.collectStatus === 1) {
this.interactData.collectNum = Number(this.interactData.collectNum) + 1
} else {
this.interactData.collectNum = Number(this.interactData.collectNum) - 1
}
console.log('收藏、取消收藏==', this.newsStatusOfUser?.collectStatus, this.interactData?.collectNum)
}
})
}
/**
* 查询点赞、收藏数量
*/
queryContentInteractCount() {
const params: contentListParams = {
contentList: [{
contentId: this.contentDetailData?.newsId + '',
contentType: this.contentDetailData?.newsType,
}]
}
ContentDetailRequest.getContentInteract(params).then(res => {
if (res.data && this.interactData) {
this.interactData.likeNum = res.data[0]?.likeNum
this.interactData.collectNum = res.data[0]?.collectNum
this.interactData.commentNum = res.data[0]?.commentNum
}
console.log('获取互动点赞等数据===', JSON.stringify(res))
})
}
getImgUrl() {
return this.contentDetailData?.rmhInfo?.rmhHeadUrl || this.contentDetailData?.userInfo?.userHeadUrl
}
/**
* 关注号主
*/
async handleAccention() {
// 未登录,跳转登录
const user_id = await SPHelper.default.get(SpConstants.USER_ID, '')
if (!user_id) {
WDRouterRule.jumpWithPage(WDRouterPage.loginPage)
return
}
const params2: postInteractAccentionOperateParams = {
attentionUserType: this.contentDetailData?.rmhInfo?.userType || '', //被关注用户类型(1 普通用户 2 视频号 3 矩阵号)
attentionUserId: this.contentDetailData?.rmhInfo?.userId || '', // 被关注用户号主id
attentionCreatorId: this.contentDetailData?.rmhInfo?.rmhId || '', // 被关注用户号主id
// userType: 1,
// userId: '1',
status: 1,
}
ContentDetailRequest.postInteractAccentionOperate(params2).then(res => {
console.log('关注号主==', JSON.stringify(res.data))
if (this.followStatus == '1') {
this.followStatus = '0'
} else {
this.followStatus = '1'
}
})
}
@Builder
buildUserComp() {
Column() {
if (this.getImgUrl()) {
RelativeContainer() {
Image(this.getImgUrl())
.width('100%')
.borderRadius(24)
.aspectRatio(1)
.border({ width: 1, color: Color.White, style: BorderStyle.Solid })
.alignRules({
top: { anchor: "__container__", align: VerticalAlign.Top },
left: { anchor: "__container__", align: HorizontalAlign.Start }
})
.id("row1")
.onClick(() => {
if (this.contentDetailData.rmhInfo?.cnMainControl === 1) {
// 号主页
const params: Params = {
creatorId: this.contentDetailData.rmhInfo.rmhId,
pageID: ''
}
WDRouterRule.jumpWithPage(WDRouterPage.peopleShipHomePage, params)
}
})
if (this.followStatus == '0') {
Image($r('app.media.ic_add'))
.width(24)
.borderRadius(12)
.alignRules({
left: { anchor: "__container__", align: HorizontalAlign.Center },
bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
})
.margin({ left: -12 })
.id("row2")
.onClick(() => {
// 关注
this.handleAccention()
})
}
}.height(60)
}
}.margin({ bottom: 18 })
}
@Builder
buildOperationItem(item: OperationItem, index: number) {
Column() {
if (item.text === '赞') {
Image(this.newsStatusOfUser?.likeStatus == '1' ? item.icon_check : item.icon)
.width(32)
.aspectRatio(1)
.onClick(() => {
this.toggleLikeStatus()
})
Text(this.interactData?.likeNum ? (this.interactData.likeNum + '') : item.text)
.width('100%')// .margin({ top: 4, left: 6, right: 6 })// .backgroundColor(Color.Brown)
.fontWeight(500)
.textAlign(TextAlign.Center)
.fontSize(13)
.fontColor('#FFFFFF')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
} else if (item.text === '收藏') {
Image(this.newsStatusOfUser?.collectStatus == 1 ? item.icon_check : item.icon)
.width(32)
.aspectRatio(1)
.onClick(() => {
this.toggleCollectStatus()
})
Text(this.interactData?.collectNum ? (this.interactData.collectNum + '') : item.text)
.width('100%')// .margin({ top: 4, left: 6, right: 6 })// .backgroundColor(Color.Brown)
.fontWeight(500)
.textAlign(TextAlign.Center)
.fontSize(13)
.fontColor('#FFFFFF')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
} else if (item.text === '抢首评') {
Image(item.icon)
.width(32)
.aspectRatio(1)
.onClick((event: ClickEvent) => {
ToastUtils.showToast('评论为公共方法,待开发', 1000);
})
Text(this.interactData?.commentNum ? (this.interactData.commentNum + '') : item.text)
.width('100%')// .margin({ top: 4, left: 6, right: 6 })// .backgroundColor(Color.Brown)
.fontWeight(500)
.textAlign(TextAlign.Center)
.fontSize(13)
.fontColor('#FFFFFF')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
} else {
Image(item.icon)
.width(32)
.aspectRatio(1)
.onClick((event: ClickEvent) => {
ToastUtils.showToast('分享为公共方法,待开发', 1000);
})
Text(item.text)
.width('100%')// .margin({ top: 4, left: 6, right: 6 })// .backgroundColor(Color.Brown)
.fontWeight(500)
.textAlign(TextAlign.Center)
.fontSize(13)
.fontColor('#FFFFFF')
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
}
// .width(48)
.margin({ bottom: 20 })
.alignItems(HorizontalAlign.Center)
.hoverEffect(HoverEffect.Scale)
}
build() {
Column() {
this.buildUserComp()
ForEach(this.operationList, (item: OperationItem, index: number) => {
this.buildOperationItem(item, index)
}, (item: OperationItem, index: number) => JSON.stringify(item))
}
.width(48)
.position({ x: '100%', y: '100%' })
.markAnchor({ x: '100%', y: '100%' })
.padding({ bottom: 72 })
.visibility(this.isOpenDetail || this.isDragging ? Visibility.None : Visibility.Visible)
}
}
\ No newline at end of file
... ...
@Preview
@Component
export struct PlayerTimeSeekView {
build() {
Row() {
Text() {
Span('00:06')
Span('/')
Span('00:06')
}
.fontSize(24)
.fontColor(Color.White)
.fontWeight(600)
}
}
}
\ No newline at end of file
... ...
... ... @@ -49,8 +49,14 @@ export struct PlayerTitleComment {
getName() {
// console.error(this.contentDetailData?.newsSourceName + '===========' + this.contentDetailData?.editorName)
// this.contentDetailData?.newsSourceName || authTitle
return this.contentDetailData?.rmhInfo?.rmhName || ''
}
getIcon() {
// console.error(this.contentDetailData?.newsSourceName + '===========' + this.contentDetailData?.editorName)
// this.contentDetailData?.newsSourceName ||
return this.contentDetailData?.editorName || ''
return this.contentDetailData?.rmhInfo?.authIcon || ''
}
getTitle() {
... ... @@ -99,11 +105,16 @@ export struct PlayerTitleComment {
Row() {
Column() {
if (this.getName()) {
Text("@" + this.getName())
.fontColor(Color.White)
.fontSize(15)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
Row() {
Text("@" + this.getName())
.fontColor(Color.White)
.fontSize(15)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
if (this.getIcon()) {
Image(this.getIcon()).height(10).margin({ left: 4 })
}
}
}
if (this.getTitle()) {
Text(this.getTitle())
... ...
import measure from '@ohos.measure'
import { ContentDetailDTO } from 'wdBean/Index'
import { DetailDialog } from './DetailDialog'
import { componentUtils } from '@kit.ArkUI'
@Preview
@Component
export struct PlayerTitleView {
@Consume contentDetailData: ContentDetailDTO
@Consume windowWidth: number
@Consume isOpenDetail: boolean
@Consume isDragging: boolean
@State titleHeight: number = 0
dialogController: CustomDialogController = new CustomDialogController({
builder: DetailDialog({
name: this.getName(),
title: this.getTitle(),
summary: this.getSummary(),
isOpenDetail: this.isOpenDetail
}),
autoCancel: false,
customStyle: true,
alignment: DialogAlignment.Bottom
})
getName(): string {
// authTitle
return this.contentDetailData?.rmhInfo?.rmhName || ''
}
getIcon(): string {
return this.contentDetailData?.rmhInfo?.authIcon || ''
}
getTitle(): string {
return this.contentDetailData?.newsTitle || ''
}
getSummary(): string {
return this.contentDetailData?.newIntroduction || ''
}
aboutToAppear(): void {
const info = measure.measureTextSize({
textContent: this.getTitle(),
fontSize: 15,
fontWeight: 400,
lineHeight: 20,
constraintWidth: this.windowWidth - 100 - 16 - 22 + 'px',
})
this.titleHeight = info?.height as number || 0
console.log('titleHeight:', this.titleHeight,)
}
build() {
Column() {
if (this.getName()) {
Row() {
Text("@" + this.getName())
.fontColor(Color.White)
.fontSize(17)
.maxLines(1)
.lineHeight(25)
.fontWeight(600)
.textOverflow({ overflow: TextOverflow.Ellipsis })
if (this.getIcon()) {
Image(this.getIcon()).height(10).margin({ left: 4 })
}
}.margin({ bottom: 8 })
}
Text(this.getTitle())
.fontColor(Color.White)
.fontSize(15)
.maxLines(3)
.lineHeight(20)
.fontWeight(400)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.margin({ bottom: 8 })
/**
* 标题大于三行或存在简介显示查看详情按钮
*/
if (this.titleHeight > 200 || this.getSummary()) {
Text('查看详情 > ')
.padding({ left: 6, right: 6, top: 4, bottom: 4 })
.borderRadius(2)
.backgroundColor('#99636363')
.fontColor(Color.White)
.fontSize(12)
.lineHeight(14)
.fontWeight(400)
.margin({ bottom: 8 })
.onClick(() => {
this.isOpenDetail = true
this.dialogController?.open()
})
}
}
.width(this.windowWidth - 100 + 'px')
.padding({ left: 16, right: 22 })
.alignItems(HorizontalAlign.Start)
.visibility(this.isOpenDetail || this.isDragging ? Visibility.None : Visibility.Visible)
}
}
\ No newline at end of file
... ...
... ... @@ -55,6 +55,7 @@ struct LoginPage {
alignment:DialogAlignment.Center
})
loginViewModel = new LoginViewModel()
@State isProtocol:boolean=false
onCodeSend() {
Logger.debug(TAG, "isCodeSend:" + this.isCodeSend + "")
... ... @@ -72,108 +73,119 @@ struct LoginPage {
}
build() {
RelativeContainer() {
//注册内容
Column() {
Image($r("app.media.login_logo"))
.width(120)
.height(66)
.margin({ top: 78 })
.align(Alignment.Center)
if (this.checkCodePage) {
LoginInputComponent({
phoneContent: $phoneContent,
codeContent: $codeContent,
isSubmit: $isSubmit,
isCodeSend: $isCodeSend
})
} else {
this.addPassword()
}
Stack() {
RelativeContainer() {
Row() {
Image(this.protocolState ? $r('app.media.login_checkbox_select') : $r('app.media.login_checkbox_unselected'))
.width(15)
.height(15)
.onClick(() => {
this.protocolState = !this.protocolState
//注册内容
Column() {
Image($r("app.media.login_logo"))
.width(120)
.height(66)
.margin({ top: 78 })
.align(Alignment.Center)
if (this.checkCodePage) {
LoginInputComponent({
phoneContent: $phoneContent,
codeContent: $codeContent,
isSubmit: $isSubmit,
isCodeSend: $isCodeSend
})
} else {
this.addPassword()
}
Text() {
Span("我已阅读并同意").fontColor("#999999").fontSize(12)
Span("《用户协议》").fontColor("#ED2800").fontSize(12).onClick(() => {
let bean={contentID:"1",pageID:""} as Params
WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage,bean)
})
Span("及").fontColor("#999999").fontSize(12)
Span("《隐私政策》").fontColor("#ED2800").fontSize(12).onClick(() => {
let bean={contentID:"2",pageID:""} as Params
WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage,bean)
})
Row() {
Image(this.protocolState ? $r('app.media.login_checkbox_select') : $r('app.media.login_checkbox_unselected'))
.width(15)
.height(15)
.onClick(() => {
this.protocolState = !this.protocolState
})
Text() {
Span("我已阅读并同意").fontColor("#999999").fontSize(12)
Span("《用户协议》").fontColor("#ED2800").fontSize(12).onClick(() => {
let bean = { contentID: "1", pageID: "" } as Params
WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage, bean)
})
Span("及").fontColor("#999999").fontSize(12)
Span("《隐私政策》").fontColor("#ED2800").fontSize(12).onClick(() => {
let bean = { contentID: "2", pageID: "" } as Params
WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage, bean)
})
}
}.margin({ top: 48 }).alignItems(VerticalAlign.Center)
Row() {
Text("登录")
.borderRadius(4)
.fontColor(this.isSubmit ? "#FFFFFFFF" : "#66FFFFFF")
.fontSize(18)
.fontWeight(FontWeight.Medium)
.margin({ top: 20 })
.height(44)
.textAlign(TextAlign.Center)
.width("100%")
.backgroundColor(this.isSubmit ? "#FFED2800" : "#99ED2800")
.onClick(() => {
if (!this.isSubmit) {
return
}
this.loginSubmit()
})
}.padding({ left: 25, right: 25 }).width('100%')
if (!this.checkCodePage) {
Text('忘记密码').fontColor('#666666').fontSize(14).margin({ top: 16 })
.onClick(() => {
// router.pushUrl({ url: 'pages/login/ForgetPasswordPage' })
let pageType = { 'pageType': 0 } as Record<string, number>;
WDRouterRule.jumpWithPage(WDRouterPage.forgetPasswordPage, pageType)
})
}
}.margin({ top: 48 }).alignItems(VerticalAlign.Center)
Row() {
Text("登录")
.borderRadius(4)
.fontColor(this.isSubmit ?"#FFFFFFFF":"#66FFFFFF")
.fontSize(18)
.fontWeight(FontWeight.Medium)
.margin({ top: 20 })
.height(44)
.textAlign(TextAlign.Center)
.width("100%")
.backgroundColor(this.isSubmit?"#FFED2800":"#99ED2800")
.onClick(() => {
if(!this.isSubmit){
return
}
this.loginSubmit()
}.width("100%")
.alignRules({
top: { anchor: "__container__", align: VerticalAlign.Top },
}).id("register")
})
}.padding({ left: 25, right: 25 }).width('100%')
//其他登录方式
Column() {
this.addOtherLogin()
}.width('100%')
.alignRules({
bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
}).id("other")
//关闭按钮
Image($r('app.media.login_closed'))
.width(24)
.height(24)
.margin({ top: 10, right: 15 })
.alignRules({
top: { anchor: "__container__", align: VerticalAlign.Top },
right: { anchor: "__container__", align: HorizontalAlign.End }
})
.onClick(() => {
router.back()
})
.id('id_close')
if (!this.checkCodePage) {
Text('忘记密码').fontColor('#666666').fontSize(14).margin({ top: 16 })
.onClick(() => {
// router.pushUrl({ url: 'pages/login/ForgetPasswordPage' })
let pageType = {'pageType': 0} as Record<string, number>;
WDRouterRule.jumpWithPage(WDRouterPage.forgetPasswordPage, pageType)
})
}
}.width('100%').height('100%')
}.width("100%")
.alignRules({
top: { anchor: "__container__", align: VerticalAlign.Top },
}).id("register")
ProtocolComponent({
cancelMethod: (): void => this.cancelProtocol(),
agreeMethod: (): void => this.agreeProtocol()
})
.visibility(this.isProtocol ? Visibility.Visible : Visibility.None)
//其他登录方式
Column() {
this.addOtherLogin()
}.width('100%')
.alignRules({
bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
}).id("other")
//关闭按钮
Image($r('app.media.login_closed'))
.width(24)
.height(24)
.margin({ top: 10, right: 15 })
.alignRules({
top: { anchor: "__container__", align: VerticalAlign.Top },
right: { anchor: "__container__", align: HorizontalAlign.End }
})
.onClick(() => {
router.back()
})
.id('id_close')
}.width('100%')
.height('100%')
}.width('100%').height('100%')
}
@Builder
... ... @@ -188,15 +200,15 @@ struct LoginPage {
.type(InputType.Normal)
.onChange((content) => {
this.accountContent = content
this.isSubmit = (this.accountContent.length >= 11 && this.passwordContent.length >= 6)
this.isSubmit = (this.accountContent.length >= 1 && this.passwordContent.length >= 6)
})
RelativeContainer() {
if (this.passwordSwitch) {
// if (this.passwordSwitch) {
this.addPasswordInputLayout()
} else {
this.addPasswordInputLayout()
}
// } else {
// this.addPasswordInputLayout()
// }
Image(this.passwordSwitch ? $r('app.media.login_password_off') : $r('app.media.login_password_on'))
.onClick(() => {
... ... @@ -237,7 +249,7 @@ struct LoginPage {
.onChange((value) => {
// Logger.debug(TAG, "onChange" + value + "/" + this.passwordContent)
this.passwordContent = value
this.isSubmit = (this.accountContent.length >= 11 && this.passwordContent.length >= 6)
this.isSubmit = (this.accountContent.length >= 1 && this.passwordContent.length >= 6)
})
.id("password")
}
... ... @@ -366,8 +378,92 @@ struct LoginPage {
if (this.protocolState) {
this.requestLogin()
} else {
this.dialogController.open()
// this.dialogController.open()
this.isProtocol=true
}
}
agreeProtocol(): void {
this.isProtocol = false
this.protocolState = true
this.requestLogin()
}
cancelProtocol(): void {
this.isProtocol = false
}
}
@Component
struct ProtocolComponent {
cancelMethod?: () => void
agreeMethod?: () => void
build() {
Stack() {
Column() {
Text("温馨提示")
.fontColor("#222222")
.fontSize(18)
.width("100%")
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Center)
.margin({ top: 20 })
Text() {
Span("为保障您的合法权益,请阅读并同意").fontSize(14).fontColor("#666666")
Span("《用户协议》").fontSize(14).fontColor("#ED2800").onClick(() => {
let bean = { contentID: "1", pageID: "" } as Params
WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage, bean)
})
Span("及").fontSize(14).fontColor("#666666")
Span("《隐私政策》").fontSize(14).fontColor("#ED2800").onClick(() => {
let bean = { contentID: "2", pageID: "" } as Params
WDRouterRule.jumpWithPage(WDRouterPage.loginProtocolPage, bean)
})
Span("后进行登录").fontSize(14).fontColor("#666666")
}.margin({ top: 12, left: 16, right: 16 })
Divider().color("#999999").width("100%").margin({ top: 14 }).height('1vp')
Row() {
Text('放弃登录')
.fontSize(16)
.fontColor("#999999")
.layoutWeight(1)
.fontWeight(FontWeight.Medium)
.textAlign(TextAlign.Center)
.onClick(() => {
if (this.cancelMethod) {
this.cancelMethod()
}
})
.height('100%')
// Divider().color("#999999").height('100%').width('0.5vp')
Text('同意并登录')
.fontSize(16)
.fontColor("#ED2800")
.layoutWeight(1)
.fontWeight(FontWeight.Medium)
.textAlign(TextAlign.Center)
.border({
width: { left: 1 },
color: "#999999",
style: { left: BorderStyle.Solid }
})
.onClick(() => {
if (this.agreeMethod) {
this.agreeMethod()
}
})
.height('100%')
}.layoutWeight(1).justifyContent(FlexAlign.Center)
}.height(161).backgroundColor(Color.White).borderRadius(6).width('74%')
}.width('100%')
.height('100%')
.backgroundColor('#66000000')
}
}
\ No newline at end of file
... ...
... ... @@ -73,13 +73,12 @@ export struct WDPlayerRenderView {
Row() {
// 设置为“surface“类型时XComponent组件可以和其他组件一起进行布局和渲染。
XComponent({
id: 'xComponentId',
type: 'surface',
id: this.insId,
type: XComponentType.SURFACE,
controller: this.xComponentController
})
.onLoad(async (event) => {
Logger.info(TAG, 'onLoad')
// const surfaceId = this.xComponentController.getXComponentSurfaceId()
this.xComponentController.setXComponentSurfaceSize({
surfaceWidth: 1920,
surfaceHeight: 1080
... ... @@ -89,13 +88,16 @@ export struct WDPlayerRenderView {
this.onLoad(event)
}
})
.width(this.selfSize.width)
.height(this.selfSize.height)
.width('100%')// .width(this.selfSize.width)
// .height(this.selfSize.height)
.aspectRatio(this.videoWidth / this.videoHeight)
.renderFit(RenderFit.RESIZE_COVER)
}
.id(this.insId)
.onAreaChange(() => {
// this.updateLayout()
})
// .onAreaChange(() => {
// this.updateLayout()
// })
.backgroundColor("#000000")
// .height('100%')
... ... @@ -103,15 +105,21 @@ export struct WDPlayerRenderView {
}
updateLayout() {
let info = componentUtils.getRectangleById(this.insId);
if (info.size.width > 0 && info.size.height > 0 && this.videoHeight > 0 && this.videoWidth > 0) {
if (info.size.width / info.size.height > this.videoWidth / this.videoHeight) {
let scale = info.size.height / this.videoHeight;
this.selfSize = new Size((this.videoWidth * scale / info.size.width) * 100 + "%", '100%');
} else {
let scale = info.size.width / this.videoWidth;
this.selfSize = new Size('100%', (this.videoHeight * scale / info.size.height) * 100 + "%");
// let info = componentUtils.getRectangleById(this.insId);
const windowRect = WindowModel.shared.getWindowProperties()?.windowRect
if (windowRect) {
const info = windowRect
if (info.width > 0 && info.height > 0 && this.videoHeight > 0 && this.videoWidth > 0) {
if (info.width / info.height > this.videoWidth / this.videoHeight) {
let scale = info.height / this.videoHeight;
this.selfSize = new Size((this.videoWidth * scale / info.width) * 100 + "%", '100%');
} else {
let scale = info.width / this.videoWidth;
this.selfSize = new Size('100%', (this.videoHeight * scale / info.height) * 100 + "%");
}
}
}
}
}
\ No newline at end of file
... ...
... ... @@ -59,8 +59,12 @@ export default class EntryAbility extends UIAbility {
const SYSTEM_AREA = windowClass.getWindowAvoidArea(TYPE_SYSTEM);
const bottomSafeHeight = NAV_AREA.bottomRect.height; // 获取到导航条区域的高度
const topSafeHeight = SYSTEM_AREA.topRect.height; // 获取到状态栏区域的高度
const width = windowClass.getWindowProperties().windowRect.width
const height = windowClass.getWindowProperties().windowRect.height
AppStorage.setOrCreate('bottomSafeHeight', bottomSafeHeight);
AppStorage.setOrCreate('topSafeHeight', topSafeHeight);
AppStorage.setOrCreate('windowWidth', width);
AppStorage.setOrCreate('windowHeight', height);
// let a = new WindowModel();
... ...
import { BottomNavigationComponent, LogoutViewModel} from 'wdComponent';
import { BottomNavigationComponent, LogoutViewModel } from 'wdComponent';
import { BreakpointConstants } from 'wdConstant';
import { BreakpointSystem, EmitterEventId, EmitterUtils, Logger } from 'wdKit';
import { BreakpointSystem, EmitterEventId, EmitterUtils, Logger } from 'wdKit';
import router from '@ohos.router';
import { promptAction } from '@kit.ArkUI';
import { HWLocationUtils } from 'wdHwAbility/Index';
... ... @@ -12,7 +12,8 @@ const TAG = 'MainPage';
@Entry
@Component
struct MainPage {
@Provide pageShow: number = -1
@Provide pageHide: number = -1
private breakpointSystem: BreakpointSystem = new BreakpointSystem()
@StorageLink('currentBreakpoint') @Watch('watchCurrentBreakpoint') currentBreakpoint: string = BreakpointConstants.BREAKPOINT_XS;
... ... @@ -34,9 +35,14 @@ struct MainPage {
Logger.info(TAG, 'aboutToDisappear');
}
onPageHide() {
Logger.info(TAG, 'onPageHide');
this.pageHide = Math.random()
}
onPageShow() {
Logger.info(TAG, 'onPageShow');
this.pageShow = Math.random()
}
onBackPress() {
... ...
import router from '@ohos.router'
import { WDRouterRule } from 'wdRouter';
import { ProcessUtils, WDRouterRule } from 'wdRouter';
import { WDRouterPage } from 'wdRouter';
import { Logger, SPHelper } from 'wdKit/Index';
import { SpConstants } from 'wdConstant/Index';
... ... @@ -178,23 +178,14 @@ struct LaunchAdvertisingPage {
// openType 端外 端内 打开
if (this.model.launchAdInfo[0].matInfo.openType == '2') {
//端外打开
let context = getContext(this) as common.UIAbilityContext;
let wantInfo: Want = {
// uncomment line below if wish to implicitly query only in the specific bundle.
// bundleName: 'com.example.myapplication',
action: 'ohos.want.action.viewData',
// entities can be omitted.
entities: ['entity.system.browsable'],
uri: 'https://news.bjd.com.cn/2024/03/19/10724331.shtml'
}
context.startAbility(wantInfo).then(() => {
// ...
}).catch((err: BusinessError) => {
// ...
})
ProcessUtils.jumpExternalWebPage(this.model.launchAdInfo[0].matInfo.linkUrl)
clearInterval(this.timer)
}else {
//端内打开
ProcessUtils.gotoDefaultWebPage(this.model.launchAdInfo[0].matInfo.linkUrl)
clearInterval(this.timer)
}
}
... ...
... ... @@ -98,6 +98,12 @@ struct LaunchPage {
//获取本地存储的启动页数据
let dataModelStr : string = SPHelper.default.getSync(SpConstants.APP_LAUNCH_PAGE_DATA_MODEL,'') as string
if (!dataModelStr) {
//直接跳转首页
WDRouterRule.jumpWithReplacePage(WDRouterPage.mainPage)
return
}
let dataModel : LaunchDataModel = JSON.parse(dataModelStr)
console.log(dataModelStr)
... ...
-----BEGIN NEW CERTIFICATE REQUEST-----
MIIBSjCB8gIBADBgMQswCQYDVQQGEwI4NjEOMAwGA1UECBMFQW5odWkxDjAMBgNV
BAcTBUhlZmVpMRIwEAYDVQQKEwlXb25kZXJUZWsxDzANBgNVBAsTBldvbmRlcjEM
MAoGA1UEAxMDWEdZMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcpXWRUmv/W+Q
j25o83pS3Ftb6VtfwUsapOYxIqoxmpauFHTKg1RA7h3QlILy3rhNW7I8wiwNA+kp
jfLqCGzMQqAwMC4GCSqGSIb3DQEJDjEhMB8wHQYDVR0OBBYEFPdvSvMO2yFULBr+
iUFb6ytXskNHMAoGCCqGSM49BAMCA0cAMEQCID4oV66jJ0KJ23jAHFlQ+5xioszZ
dYhhRK7tG9Dsy4VpAiAx3rhNI8RbM7s+t2hqEsbrBXznNK7omEU4hooOkewbaw==
-----END NEW CERTIFICATE REQUEST-----
... ...
-----BEGIN CERTIFICATE-----
MIICGjCCAaGgAwIBAgIIShhpn519jNAwCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC
Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE
AwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDMxNjAzMDQzOVoXDTQ5MDMx
NjAzMDQzOVowUzELMAkGA1UEBhMCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE
CwwKSHVhd2VpIENCRzEeMBwGA1UEAwwVSHVhd2VpIENCRyBSb290IENBIEcyMHYw
EAYHKoZIzj0CAQYFK4EEACIDYgAEWidkGnDSOw3/HE2y2GHl+fpWBIa5S+IlnNrs
GUvwC1I2QWvtqCHWmwFlFK95zKXiM8s9yV3VVXh7ivN8ZJO3SC5N1TCrvB2lpHMB
wcz4DA0kgHCMm/wDec6kOHx1xvCRo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
AQH/BAUwAwEB/zAdBgNVHQ4EFgQUo45a9Vq8cYwqaiVyfkiS4pLcIAAwCgYIKoZI
zj0EAwMDZwAwZAIwMypeB7P0IbY7c6gpWcClhRznOJFj8uavrNu2PIoz9KIqr3jn
BlBHJs0myI7ntYpEAjBbm8eDMZY5zq5iMZUC6H7UzYSix4Uy1YlsLVV738PtKP9h
FTjgDHctXJlC5L7+ZDY=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDATCCAoigAwIBAgIIXmuDXbWpOB8wCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC
Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE
AwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDcwOTAyMDQyNFoXDTMwMDcw
NzAyMDQyNFowYjELMAkGA1UEBgwCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE
CwwKSHVhd2VpIENCRzEtMCsGA1UEAwwkSHVhd2VpIENCRyBEZXZlbG9wZXIgUmVs
YXRpb25zIENBIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE65LdoIZh1hlpZ2gP
bJ6gPhHsvYSRe22KETgdqeVeYnrbRHI9wsPT6RGYS+pU4mPl6wxzgDMqN6SY/BoZ
luhkE1PzaHoPoNIWIq0O33hpyKyyYwAacIUEjYurkw1E9r9no4IBGDCCARQwHwYD
VR0jBBgwFoAUo45a9Vq8cYwqaiVyfkiS4pLcIAAwHQYDVR0OBBYEFNtek7Ij6NDk
/nF6Zumkc0dbf/NeMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEGCCsGAQUFBwIBFiVo
dHRwOi8vY3BraS1jYXdlYi5odWF3ZWkuY29tL2Nwa2kvY3BzMBIGA1UdEwEB/wQI
MAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMGYGA1UdHwRfMF0wW6BZoFeGVWh0dHA6
Ly9jcGtpLWNhd2ViLmh1YXdlaS5jb20vY3BraS9zZXJ2bGV0L2NybEZpbGVEb3du
LmNybD9jZXJ0eXBlPTEwJi9yb290X2cyX2NybC5jcmwwCgYIKoZIzj0EAwMDZwAw
ZAIwWO1X5q2MdfpR1Q237GpUHGbL1C13rGyFg2p3AYo44FpZ2/A9ss0wOHKM4KDl
ZPqdAjBLkf8NPZy7KVog98+iCTLq35DJ2ZVxkCxknA9YhiHVyXf4HPm4JlT7rW7o
Q+FzM3c=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIC0jCCAligAwIBAgIOY8sBbjnB96BZITO8K44wCgYIKoZIzj0EAwMwYjELMAkG
A1UEBgwCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEt
MCsGA1UEAwwkSHVhd2VpIENCRyBEZXZlbG9wZXIgUmVsYXRpb25zIENBIEcyMB4X
DTI0MDQyMzEwNDkxNVoXDTI1MDQyMzEwNDkxNVowgYExCzAJBgNVBAYTAkNOMRgw
FgYDVQQKDA/kurrmsJHml6XmiqXnpL4xHDAaBgNVBAsMEzE0MDU5MDg1MTcwMDg3
Mjk5ODUxOjA4BgNVBAMMMeS6uuawkeaXpeaKpeekvigxNDA1OTA4NTE3MDA4NzI5
OTg1KVwsRGV2ZWxvcG1lbnQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARyldZF
Sa/9b5CPbmjzelLcW1vpW1/BSxqk5jEiqjGalq4UdMqDVEDuHdCUgvLeuE1bsjzC
LA0D6SmN8uoIbMxCo4HRMIHOMAwGA1UdEwEB/wQCMAAwWQYDVR0fBFIwUDBOoEyg
SoZIaHR0cDovL2g1aG9zdGluZy1kcmNuLmRiYW5rY2RuLmNuL2NjaDUvY3JsL2hk
cmNhZzIvSHVhd2VpQ0JHSERSRzJjcmwuY3JsMB8GA1UdIwQYMBaAFNtek7Ij6NDk
/nF6Zumkc0dbf/NeMB0GA1UdDgQWBBT3b0rzDtshVCwa/olBW+srV7JDRzAOBgNV
HQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwCgYIKoZIzj0EAwMDaAAw
ZQIxALQlPju1pWaQmEkj4DRezSJGS2jiPFfpSjxTJDrG2ipXHQ5jkC4QP/3AzlLe
LJ70VAIwBpsn6UOHBmNywFrdw2qpdJNueiHHefZlXFD8043LtpeYfQaHi0/gIdCQ
BclpH6Ga
-----END CERTIFICATE-----
... ...
-----BEGIN CERTIFICATE-----
MIICGjCCAaGgAwIBAgIIShhpn519jNAwCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC
Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE
AwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDMxNjAzMDQzOVoXDTQ5MDMx
NjAzMDQzOVowUzELMAkGA1UEBhMCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE
CwwKSHVhd2VpIENCRzEeMBwGA1UEAwwVSHVhd2VpIENCRyBSb290IENBIEcyMHYw
EAYHKoZIzj0CAQYFK4EEACIDYgAEWidkGnDSOw3/HE2y2GHl+fpWBIa5S+IlnNrs
GUvwC1I2QWvtqCHWmwFlFK95zKXiM8s9yV3VVXh7ivN8ZJO3SC5N1TCrvB2lpHMB
wcz4DA0kgHCMm/wDec6kOHx1xvCRo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
AQH/BAUwAwEB/zAdBgNVHQ4EFgQUo45a9Vq8cYwqaiVyfkiS4pLcIAAwCgYIKoZI
zj0EAwMDZwAwZAIwMypeB7P0IbY7c6gpWcClhRznOJFj8uavrNu2PIoz9KIqr3jn
BlBHJs0myI7ntYpEAjBbm8eDMZY5zq5iMZUC6H7UzYSix4Uy1YlsLVV738PtKP9h
FTjgDHctXJlC5L7+ZDY=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDATCCAoigAwIBAgIIXmuDXbWpOB8wCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC
Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE
AwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDcwOTAyMDQyNFoXDTMwMDcw
NzAyMDQyNFowYjELMAkGA1UEBgwCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE
CwwKSHVhd2VpIENCRzEtMCsGA1UEAwwkSHVhd2VpIENCRyBEZXZlbG9wZXIgUmVs
YXRpb25zIENBIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE65LdoIZh1hlpZ2gP
bJ6gPhHsvYSRe22KETgdqeVeYnrbRHI9wsPT6RGYS+pU4mPl6wxzgDMqN6SY/BoZ
luhkE1PzaHoPoNIWIq0O33hpyKyyYwAacIUEjYurkw1E9r9no4IBGDCCARQwHwYD
VR0jBBgwFoAUo45a9Vq8cYwqaiVyfkiS4pLcIAAwHQYDVR0OBBYEFNtek7Ij6NDk
/nF6Zumkc0dbf/NeMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEGCCsGAQUFBwIBFiVo
dHRwOi8vY3BraS1jYXdlYi5odWF3ZWkuY29tL2Nwa2kvY3BzMBIGA1UdEwEB/wQI
MAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMGYGA1UdHwRfMF0wW6BZoFeGVWh0dHA6
Ly9jcGtpLWNhd2ViLmh1YXdlaS5jb20vY3BraS9zZXJ2bGV0L2NybEZpbGVEb3du
LmNybD9jZXJ0eXBlPTEwJi9yb290X2cyX2NybC5jcmwwCgYIKoZIzj0EAwMDZwAw
ZAIwWO1X5q2MdfpR1Q237GpUHGbL1C13rGyFg2p3AYo44FpZ2/A9ss0wOHKM4KDl
ZPqdAjBLkf8NPZy7KVog98+iCTLq35DJ2ZVxkCxknA9YhiHVyXf4HPm4JlT7rW7o
Q+FzM3c=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICzjCCAlOgAwIBAgIOCfqzV9Lb4emhfwEBhZkwCgYIKoZIzj0EAwMwYjELMAkG
A1UEBgwCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEt
MCsGA1UEAwwkSHVhd2VpIENCRyBEZXZlbG9wZXIgUmVsYXRpb25zIENBIEcyMB4X
DTI0MDQyMzEwNTA0OFoXDTI3MDQyMzEwNTA0OFowfTELMAkGA1UEBhMCQ04xGDAW
BgNVBAoMD+S6uuawkeaXpeaKpeekvjEcMBoGA1UECwwTMTQwNTkwODUxNzAwODcy
OTk4NTE2MDQGA1UEAwwt5Lq65rCR5pel5oql56S+KDE0MDU5MDg1MTcwMDg3Mjk5
ODUpXCxSZWxlYXNlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcpXWRUmv/W+Q
j25o83pS3Ftb6VtfwUsapOYxIqoxmpauFHTKg1RA7h3QlILy3rhNW7I8wiwNA+kp
jfLqCGzMQqOB0TCBzjAMBgNVHRMBAf8EAjAAMFkGA1UdHwRSMFAwTqBMoEqGSGh0
dHA6Ly9oNWhvc3RpbmctZHJjbi5kYmFua2Nkbi5jbi9jY2g1L2NybC9oZHJjYWcy
L0h1YXdlaUNCR0hEUkcyY3JsLmNybDAfBgNVHSMEGDAWgBTbXpOyI+jQ5P5xembp
pHNHW3/zXjAdBgNVHQ4EFgQU929K8w7bIVQsGv6JQVvrK1eyQ0cwDgYDVR0PAQH/
BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMAoGCCqGSM49BAMDA2kAMGYCMQD1
UL0Qj+pCjOirB7hB80Pcd5jrvy1fM1a6MptJdmZtIpUBcMPk8CKO/GeUu4rPrdEC
MQDN7j9hEa4VJWu35BmoSAyZuJw4bmZ5Y56qmtLX1xFwvu9NDQiO4uZyR7q0M3Oj
FgA=
-----END CERTIFICATE-----
... ...