王士厅
1 import { CompDTO, ContentDTO } from 'wdBean' 1 import { CompDTO, ContentDTO } from 'wdBean'
2 -import { CommonConstants } from 'wdConstant/Index'; 2 +import { CommonConstants, CompStyle } from 'wdConstant/Index';
3 import { DateTimeUtils, Logger } from 'wdKit/Index'; 3 import { DateTimeUtils, Logger } from 'wdKit/Index';
4 import router from '@ohos.router' 4 import router from '@ohos.router'
5 5
@@ -20,9 +20,16 @@ export struct CardSourceInfo { @@ -20,9 +20,16 @@ export struct CardSourceInfo {
20 this.processText(); 20 this.processText();
21 } 21 }
22 22
  23 + private isLimited(): boolean {
  24 + return this.compDTO.compStyle === CompStyle.Card_13
  25 + || this.compDTO.compStyle === CompStyle.Card_14
  26 + || this.compDTO.compStyle === CompStyle.Card_06
  27 + || this.compDTO.compStyle === CompStyle.Card_21;
  28 + }
  29 +
23 processText() { 30 processText() {
24 const sourceText = this.contentDTO.rmhPlatform === 1 ? this.contentDTO.rmhInfo?.rmhName : this.contentDTO.source; 31 const sourceText = this.contentDTO.rmhPlatform === 1 ? this.contentDTO.rmhInfo?.rmhName : this.contentDTO.source;
25 - if (sourceText.length > this.maxLength) { 32 + if (this.isLimited() && sourceText.length > this.maxLength) {
26 this.displayText = sourceText.substring(0, this.maxLength) + '...'; 33 this.displayText = sourceText.substring(0, this.maxLength) + '...';
27 this.isEllipsisActive = true; 34 this.isEllipsisActive = true;
28 } else { 35 } else {
@@ -132,6 +132,9 @@ struct CommentListDialog { @@ -132,6 +132,9 @@ struct CommentListDialog {
132 inDialog: true, 132 inDialog: true,
133 dialogBeforeJumpOtherPageAction: () => { 133 dialogBeforeJumpOtherPageAction: () => {
134 // PublicDialogManager.shareInstance().closeLastDialog() 134 // PublicDialogManager.shareInstance().closeLastDialog()
  135 + if (this.onClose) {
  136 + this.onClose()
  137 + }
135 } 138 }
136 }) 139 })
137 } 140 }
@@ -35,6 +35,7 @@ export struct LikeComponent { @@ -35,6 +35,7 @@ export struct LikeComponent {
35 pageParam: ParamType = {} 35 pageParam: ParamType = {}
36 @Consume pageName: string 36 @Consume pageName: string
37 @Consume pageId: string 37 @Consume pageId: string
  38 + private dialogBeforeJumpOtherPageAction: () => void = () => {}
38 39
39 //上层传值 样例 40 //上层传值 样例
40 // this.data['contentId'] = '30035444649' //必须 41 // this.data['contentId'] = '30035444649' //必须
@@ -403,6 +404,7 @@ export struct LikeComponent { @@ -403,6 +404,7 @@ export struct LikeComponent {
403 const user_id = await SPHelper.default.get(SpConstants.USER_ID, '') 404 const user_id = await SPHelper.default.get(SpConstants.USER_ID, '')
404 if (!user_id) { 405 if (!user_id) {
405 console.log(TAG, '点赞点击,未登录') 406 console.log(TAG, '点赞点击,未登录')
  407 + if (this.dialogBeforeJumpOtherPageAction) { this.dialogBeforeJumpOtherPageAction() }
406 WDRouterRule.jumpWithPage(WDRouterPage.loginPage) 408 WDRouterRule.jumpWithPage(WDRouterPage.loginPage)
407 return 409 return
408 } 410 }
@@ -326,7 +326,8 @@ export struct OperRowListView { @@ -326,7 +326,8 @@ export struct OperRowListView {
326 data: this.likeBean, 326 data: this.likeBean,
327 styleType: this.styleType, 327 styleType: this.styleType,
328 componentType: 6, 328 componentType: 6,
329 - pageComponentType: this.pageComponentType 329 + pageComponentType: this.pageComponentType,
  330 + dialogBeforeJumpOtherPageAction: this.dialogBeforeJumpOtherPageAction
330 }) 331 })
331 } 332 }
332 .width(48) 333 .width(48)
@@ -491,6 +492,7 @@ export struct OperRowListView { @@ -491,6 +492,7 @@ export struct OperRowListView {
491 console.log(TAG, '收藏点击,登录', user_id) 492 console.log(TAG, '收藏点击,登录', user_id)
492 if (!user_id) { 493 if (!user_id) {
493 console.log(TAG, '收藏点击,用户未登录') 494 console.log(TAG, '收藏点击,用户未登录')
  495 + if (this.dialogBeforeJumpOtherPageAction) { this.dialogBeforeJumpOtherPageAction() }
494 WDRouterRule.jumpWithPage(WDRouterPage.loginPage) 496 WDRouterRule.jumpWithPage(WDRouterPage.loginPage)
495 return 497 return
496 } 498 }
@@ -19,6 +19,10 @@ export struct PlayerFullScreenView { @@ -19,6 +19,10 @@ export struct PlayerFullScreenView {
19 private timer: number = -1 19 private timer: number = -1
20 @State upProVal: string = '' 20 @State upProVal: string = ''
21 @State duration: string = DateTimeUtils.secondToTime(this.videoDuration) 21 @State duration: string = DateTimeUtils.secondToTime(this.videoDuration)
  22 + @State startX:number = 0
  23 + @State endX:number = 0
  24 + @State panDirection:number = 1 //1左滑 2右滑
  25 + private panDistance:number = 0
22 26
23 getTitle() { 27 getTitle() {
24 return this.contentDetailData?.newsTitle 28 return this.contentDetailData?.newsTitle
@@ -65,6 +69,7 @@ export struct PlayerFullScreenView { @@ -65,6 +69,7 @@ export struct PlayerFullScreenView {
65 69
66 this.headerBuilder() 70 this.headerBuilder()
67 this.middleSlideBuilder() 71 this.middleSlideBuilder()
  72 + // this.middleContainerBuilder()
68 this.bottomBuilder() 73 this.bottomBuilder()
69 } 74 }
70 .zIndex(99999) 75 .zIndex(99999)
@@ -116,7 +121,6 @@ export struct PlayerFullScreenView { @@ -116,7 +121,6 @@ export struct PlayerFullScreenView {
116 }) 121 })
117 } 122 }
118 123
119 -  
120 @Builder 124 @Builder
121 bottomBuilder() { 125 bottomBuilder() {
122 126
@@ -189,12 +193,88 @@ export struct PlayerFullScreenView { @@ -189,12 +193,88 @@ export struct PlayerFullScreenView {
189 } 193 }
190 194
191 @Builder 195 @Builder
  196 + middleContainerBuilder() {
  197 + Row() {
  198 +
  199 + }
  200 + .width('100%')
  201 + .height('100%')
  202 + .margin({ top: 73, bottom: 73 })
  203 + // .backgroundColor('#FF0000')
  204 + .onClick(() => {
  205 + Logger.warn(`cj2024 onClick showOperator=${this.showOperator}`)
  206 + if (!this.isDragging) {
  207 + if (this.showOperator == false) {
  208 + this.restartTimer();
  209 + } else {
  210 + this.showOperator = false
  211 + }
  212 + }
  213 +
  214 + })
  215 + .gesture(
  216 + // 以下组合手势为顺序识别,当长按手势事件未正常触发时则不会触发拖动手势事件
  217 + GestureGroup(GestureMode.Sequence,
  218 + // TapGesture()
  219 + // .onAction((event?:GestureEvent) => {
  220 + // Logger.warn(`cj2024 TapGesture showOperator=${this.showOperator}`)
  221 + // if (this.showOperator == false) {
  222 + // this.restartTimer();
  223 + // } else {
  224 + // this.showOperator = false
  225 + // }
  226 + // }),
  227 + PanGesture()
  228 + .onActionStart((event?: GestureEvent) => {
  229 + if (event) {
  230 + this.startX = event.offsetX
  231 + }
  232 + Logger.warn(`cj2024 pan start`)
  233 + })
  234 + .onActionUpdate((event?: GestureEvent) => {
  235 + if (event) {
  236 + }
  237 + Logger.warn(`cj2024 pan update`)
  238 + })
  239 + .onActionEnd((event?: GestureEvent) => {
  240 + if (event) {
  241 + this.endX = event.offsetX
  242 + }
  243 + this.panDirection = this.endX - this.startX > 0 ? 2 : 1
  244 + Logger.warn(`cj2024 pan end panDirection = ${this.panDirection} this.progressVal = ${this.progressVal} dir=${this.endX - this.startX}`)
  245 + if (Math.abs(this.endX - this.startX) < 100) {
  246 + this.panDistance = 1
  247 + } else {
  248 + this.panDistance = Math.abs(this.endX - this.startX) / 100
  249 + }
  250 + if (this.panDirection == 1) { //左滑
  251 + if (this.progressVal > 5) {
  252 + this.progressVal -= this.panDistance
  253 + } else {
  254 + this.progressVal = 0
  255 + }
  256 + } else {
  257 + if (this.progressVal <100) {
  258 + this.progressVal += this.panDistance
  259 + } else {
  260 + this.progressVal = 100
  261 + }
  262 +
  263 + }
  264 + Logger.warn(`cj2024 pan end panDistance = ${this.panDistance} this.progressVal = ${this.progressVal}`)
  265 + this.playerController?.setSeekTime(this.progressVal, SliderChangeMode.End);
  266 + })
  267 + )
  268 + )
  269 + }
  270 +
  271 + @Builder
192 middleSlideBuilder() { 272 middleSlideBuilder() {
193 Column() { 273 Column() {
194 Slider({ 274 Slider({
195 value: this.progressVal, 275 value: this.progressVal,
196 step: 0.01, 276 step: 0.01,
197 - style: SliderStyle.OutSet 277 + style: SliderStyle.NONE
198 }) 278 })
199 .trackColor(Color.Transparent)// 设置轨道为透明 279 .trackColor(Color.Transparent)// 设置轨道为透明
200 .selectedColor(Color.Transparent)// 设置已选择部分为透明 280 .selectedColor(Color.Transparent)// 设置已选择部分为透明
@@ -211,6 +291,7 @@ export struct PlayerFullScreenView { @@ -211,6 +291,7 @@ export struct PlayerFullScreenView {
211 } 291 }
212 if (mode === SliderChangeMode.End) { 292 if (mode === SliderChangeMode.End) {
213 this.isDragging = false 293 this.isDragging = false
  294 + this.playerController?.setSeekTime(this.progressVal, SliderChangeMode.End);
214 } 295 }
215 296
216 console.log('Transparent slider value:', value) 297 console.log('Transparent slider value:', value)
@@ -222,8 +303,11 @@ export struct PlayerFullScreenView { @@ -222,8 +303,11 @@ export struct PlayerFullScreenView {
222 clearInterval(this.timer) 303 clearInterval(this.timer)
223 } 304 }
224 if (event.type === TouchType.Up) { 305 if (event.type === TouchType.Up) {
  306 + if (this.showOperator == false) {
225 this.restartTimer(); 307 this.restartTimer();
226 - this.playerController?.setSeekTime(this.progressVal, SliderChangeMode.End); 308 + } else {
  309 + this.showOperator = false
  310 + }
227 } 311 }
228 } 312 }
229 }) 313 })
@@ -15,6 +15,7 @@ export struct PlayerTitleView { @@ -15,6 +15,7 @@ export struct PlayerTitleView {
15 @State titleHeight: number = 0 15 @State titleHeight: number = 0
16 @State rmhPlatform: number = 0 // 1是人民号 16 @State rmhPlatform: number = 0 // 1是人民号
17 @State isOverLines: boolean = false 17 @State isOverLines: boolean = false
  18 + @State isTitleOverLines: boolean = false
18 @State summary: string = '' 19 @State summary: string = ''
19 20
20 @State private titleLines: number = 0 21 @State private titleLines: number = 0
@@ -92,6 +93,41 @@ export struct PlayerTitleView { @@ -92,6 +93,41 @@ export struct PlayerTitleView {
92 console.log(TAG, 'clipStr:', clipStr) 93 console.log(TAG, 'clipStr:', clipStr)
93 return clipStr 94 return clipStr
94 } 95 }
  96 + /**
  97 + * 截断文本
  98 + * @param {string} str 要截断的文本 '啊啊啊啊啊'
  99 + * @param {number} fontSize 字体大小(px)
  100 + * @param {number} maxLines 最大行数 3
  101 + * @param {number} textWidth 文本宽度(px) vp 需要转换vp2px()
  102 + * @returns {string} clipStr 截断后的文本 '啊啊'
  103 + */
  104 + clipTitleText(str: string, fontSize: number, maxLines: number, textWidth: number): string {
  105 + let strArr: string[] = str.split("")
  106 + let truncateContent: string = '啊啊啊啊啊啊' // ...比正常文字宽度更小,这里使用啊啊啊(任意三个文字)代替计算
  107 + let measureTruncateWidth: number = measure.measureText({
  108 + textContent: truncateContent,
  109 + fontSize: fontSize,
  110 + fontWeight: 600,
  111 + lineHeight: 20,
  112 + wordBreak:WordBreak.BREAK_ALL
  113 + })
  114 + let clipStr: string = ''
  115 + for (let i = 0; i < strArr.length; i++) {
  116 + if (measure.measureText({
  117 + textContent: clipStr,
  118 + fontSize: fontSize,
  119 + fontWeight: 600,
  120 + lineHeight: 20,
  121 + wordBreak:WordBreak.BREAK_ALL
  122 + }) >= textWidth * maxLines - measureTruncateWidth) {
  123 + this.isTitleOverLines = true
  124 + break;
  125 + }
  126 + clipStr += strArr[i]
  127 + }
  128 + console.log(TAG, 'clipTitleText clipStr:', clipStr)
  129 + return clipStr
  130 + }
95 131
96 aboutToAppear(): void { 132 aboutToAppear(): void {
97 this.rmhPlatform = this.contentDetailData?.rmhPlatform || 0 133 this.rmhPlatform = this.contentDetailData?.rmhPlatform || 0
@@ -136,19 +172,20 @@ export struct PlayerTitleView { @@ -136,19 +172,20 @@ export struct PlayerTitleView {
136 172
137 } 173 }
138 174
139 - Text(this.getTitle())  
140 - .fontColor(Color.White)  
141 - .fontSize(15)  
142 - .maxLines(3)  
143 - .lineHeight(20)  
144 - .fontWeight(600)  
145 - .fontFamily('PingFang SC-Regular')  
146 - .textOverflow({ overflow: TextOverflow.Ellipsis })  
147 - .margin({ bottom: 2 }) //8  
148 - .onAreaChange((oldArea: Area, newArea: Area) => {  
149 - this.titleLines = Math.ceil((newArea.height as number) / 20) // 20是行高  
150 - this.updateSummaryLines()  
151 - }) 175 + // Text(this.getTitle())
  176 + // .fontColor(Color.White)
  177 + // .fontSize(15)
  178 + // .maxLines(4)
  179 + // .lineHeight(20)
  180 + // .fontWeight(600)
  181 + // .fontFamily('PingFang SC-Regular')
  182 + // .textOverflow({ overflow: TextOverflow.Ellipsis })
  183 + // .margin({ bottom: 2 }) //8
  184 + // .onAreaChange((oldArea: Area, newArea: Area) => {
  185 + // this.titleLines = Math.ceil((newArea.height as number) / 20) // 20是行高
  186 + // this.updateSummaryLines()
  187 + // })
  188 + this.titleBuilder()
152 /** 189 /**
153 * 标题大于三行或存在简介显示查看详情按钮 190 * 标题大于三行或存在简介显示查看详情按钮
154 */ 191 */
@@ -174,7 +211,7 @@ export struct PlayerTitleView { @@ -174,7 +211,7 @@ export struct PlayerTitleView {
174 // }) 211 // })
175 // } 212 // }
176 // } else { 213 // } else {
177 - if(this.summary) { 214 + if(this.summary && this.titleLines < 4) {
178 Text() { 215 Text() {
179 Span(this.clipText(this.summary, 14, this.summaryLines, this.windowWidth - 150 - vp2px(50))) 216 Span(this.clipText(this.summary, 14, this.summaryLines, this.windowWidth - 150 - vp2px(50)))
180 .fontSize(14) 217 .fontSize(14)
@@ -232,4 +269,51 @@ export struct PlayerTitleView { @@ -232,4 +269,51 @@ export struct PlayerTitleView {
232 .alignItems(HorizontalAlign.Start) 269 .alignItems(HorizontalAlign.Start)
233 .visibility(this.isOpenDetail || this.isDragging ? Visibility.None : Visibility.Visible) 270 .visibility(this.isOpenDetail || this.isDragging ? Visibility.None : Visibility.Visible)
234 } 271 }
  272 +
  273 + @Builder
  274 + titleBuilder() {
  275 + Text() {
  276 + Span(this.clipTitleText(this.getTitle(), 14, 4, this.windowWidth - 230 - vp2px(50)))
  277 + .fontSize(15)
  278 + .fontColor(Color.White)
  279 + .lineHeight(20)
  280 + .fontWeight(600)
  281 + .fontFamily('PingFang SC-Regular')
  282 + if (this.isTitleOverLines) {
  283 + Span('... 全文')
  284 + .fontColor('#888888')
  285 + .fontWeight(600)
  286 + .fontFamily('PingFang SC-Regular')
  287 + .fontSize(12)
  288 + .onClick(() => {
  289 + this.isOpenDetail = true
  290 + this.dialogController?.open()
  291 + })
  292 + ImageSpan($r('app.media.comment_unfold_svg'))
  293 + .width(14)
  294 + .height(14)
  295 + .objectFit(ImageFit.Fill)
  296 + .verticalAlign(ImageSpanAlignment.BOTTOM)
  297 + .margin({bottom:1})
  298 + // .padding({
  299 + // bottom: 4
  300 + // })
  301 + .onClick(() => {
  302 + this.isOpenDetail = true
  303 + this.dialogController?.open()
  304 + })
  305 +
  306 + }
  307 + }
  308 + .onAreaChange((oldArea: Area, newArea: Area) => {
  309 + this.titleLines = Math.ceil((newArea.height as number) / 20) // 20是行高
  310 + this.updateSummaryLines()
  311 + })
  312 + .padding({
  313 + left: 0,//6
  314 + right: 6,
  315 + top: 0,//4
  316 + bottom: 4
  317 + })
  318 + }
235 } 319 }