• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import router from '@ohos.router';
17import { TrendsItem } from '../commonComponent/TrendsItem';
18import { CommentData } from '../model/TrendsDataSource';
19import { makeCommentDataLocal, promptActionFn } from '../model/DataFactory';
20import { Trends, UserInfo, ContentsType } from '../model/BaseMsg';
21import { PasteControl } from '../authorizedControl/PasteControl';
22import Constants from '../utils/Constants';
23
24@Component
25export struct CommentDetailView {
26  // 初始化输入框value值
27  @State textInputValue: string = '';
28  @State isSelectionMenuHidden: boolean = false;
29  // 初始化是否显示复制粘贴文本选择器
30  @State isTextInputShow: boolean = false;
31  // 初始化键盘高度
32  @StorageLink('keyboardHeight') keyboardHeight: number = 0;
33  // 评论数据属性
34  @Provide commentDataSource: CommentData = new CommentData();
35  // 获取动态信息
36  private trendsItemData: Trends = (router.getParams() as Record<string, Object>)['trendsData'] as Trends;
37  // Scroll控制器
38  private scroller: Scroller = new Scroller();
39  // 输入框控制器
40  private controller: TextInputController = new TextInputController();
41
42  /**
43   * 自定义组件 评论 点赞
44   * @param image 图片路径 text 文本内容 featureIndex 下标
45   */
46  @Builder
47  FeatureBuilder(image: Resource, text: Resource, featureIndex: number) {
48    Column() {
49      Image(image)
50        .width($r('app.integer.layout_size_28'))
51        .height($r('app.integer.layout_size_28'))
52        .objectFit(ImageFit.Contain)
53      Text(text)
54        .fontSize($r('app.integer.layout_size_12'))
55        .id('commentButton')
56    }
57    .justifyContent(FlexAlign.Center)
58    .height(56)
59    .onClick(() => {
60      if (featureIndex !== 1) {
61        promptActionFn($r('app.string.feature_development'));
62        return;
63      }
64      this.isTextInputShow = true;
65    })
66  }
67
68  build() {
69    Stack({ alignContent: Alignment.Bottom }) {
70      Flex({ direction: FlexDirection.Column }) {
71        // 标题
72        TitleBar()
73        Scroll(this.scroller) {
74          Column() {
75            // 动态详情信息
76            TrendsItem({ trendsItemData: this.trendsItemData, isDetailPage: true, isVisible: false })
77              .width('90%')
78            // 评论区
79            CommentArea()
80          }
81        }
82      }.width('100%')
83      .height('100%')
84
85      // 输入框
86      if (this.isTextInputShow) {
87        Row() {
88          if (this.isSelectionMenuHidden) {
89            PasteControl({ isSelectionMenuHidden: $isSelectionMenuHidden, textInputValue: $textInputValue })
90          }
91
92          Image(this.trendsItemData.user.userImage)
93            .width($r('app.integer.layout_size_40'))
94            .height($r('app.integer.layout_size_40'))
95            .borderRadius($r('app.integer.layout_size_20'))
96          TextInput({
97            text: this.textInputValue,
98            placeholder: $r('app.string.add_comment'),
99            controller: this.controller
100          })
101            .id('comment_add')
102            .placeholderFont({ size: 14, weight: 400 })
103            .backgroundColor(Color.White)
104            .selectionMenuHidden(true)
105            .enterKeyType(EnterKeyType.Send)
106            .width($r('app.integer.layout_size_400'))
107            .height($r('app.integer.layout_size_40'))
108            .fontSize($r('app.integer.layout_size_14'))
109            .fontColor(Color.Black)
110            .onChange((value: string) => {
111              this.textInputValue = value;
112            })
113            .onSubmit(async () => {
114              this.trendsItemData.contents.text = this.textInputValue;
115              this.trendsItemData.likeCount = 0;
116              this.commentDataSource.pushData(this.trendsItemData);
117              this.textInputValue = '';
118              this.isTextInputShow = false;
119            })
120            .gesture(LongPressGesture({ repeat: true, duration: 300 })
121              .onAction((event?: GestureEvent) => {
122                this.isSelectionMenuHidden = true;
123              }))
124
125        }.width('100%')
126        .backgroundColor(Color.White)
127        .padding($r('app.integer.layout_size_10'))
128        .border({
129          width: { top: Constants.BORDERWIDTH },
130          color: '#fffffbfb',
131        })
132      } else {
133        Column() {
134          Divider()
135            .vertical(false)
136            .strokeWidth('1')
137            .color($r('app.color.font_color_182431'))
138            .opacity(0.15)
139          Row() {
140            this.FeatureBuilder($r('app.media.ic_share'), $r('app.string.share'), Constants.TAB_INDEX_0)
141            this.FeatureBuilder($r('app.media.ic_message'), $r('app.string.comment'), Constants.TAB_INDEX_1)
142            this.FeatureBuilder($r('app.media.ic_thumbsup'), $r('app.string.like'), Constants.TAB_INDEX_2)
143          }
144          .width('100%')
145          .justifyContent(FlexAlign.SpaceAround)
146          .alignItems(VerticalAlign.Center)
147          .backgroundColor('#F1F3F5')
148        }
149
150      }
151    }.padding({ bottom: px2vp((this.keyboardHeight)) })
152    .expandSafeArea([SafeAreaType.KEYBOARD])
153  }
154}
155
156@Component
157struct TitleBar {
158  build() {
159    Row(){
160      Row() {
161        Image($r('app.media.ic_public_back'))
162          .id('backBtn')
163          .width($r('app.integer.layout_size_24'))
164          .height($r('app.integer.layout_size_24'))
165          .onClick(() => {
166            router.back();
167          })
168        Row() {
169          Image($r('app.media.ic_collect'))
170            .width($r('app.integer.layout_size_24'))
171            .height($r('app.integer.layout_size_24'))
172            .onClick(() => {
173              promptActionFn($r('app.string.feature_development'))
174            })
175          Image($r('app.media.ic_public_more'))
176            .width($r('app.integer.layout_size_24'))
177            .height($r('app.integer.layout_size_24'))
178            .margin({ left: $r('app.integer.layout_size_24') })
179            .onClick(() => {
180              promptActionFn($r('app.string.feature_development'))
181            })
182        }
183        .padding({ right: $r('app.integer.layout_size_12') })
184      }
185      .width('90%')
186      .padding({ left: $r('app.integer.layout_size_12') })
187      .margin({ top: $r('app.integer.layout_size_12'), bottom: $r('app.integer.layout_size_11') })
188      .height($r('app.integer.layout_size_33'))
189      .justifyContent(FlexAlign.SpaceBetween)
190    }
191    .justifyContent(FlexAlign.Center)
192    .width('100%')
193
194
195  }
196}
197
198@Component
199struct CommentArea {
200  @State currentTabIndex: number = 1;
201  @Consume commentDataSource: CommentData;
202
203  async aboutToAppear() {
204    await makeCommentDataLocal(this.commentDataSource);
205  }
206
207  // 设置tabBar样式的位置、未选中图片、选中图片及文字显示的参数
208  @Builder
209  TabBuilder(text: Resource, index: number) {
210    Column() {
211      Text(text)
212        .fontSize($r('app.integer.layout_size_21'))
213        .fontColor(this.currentTabIndex === index ? $r('app.color.font_color_blue') : $r('app.color.font_color_datetime'))
214        .padding({ top: $r('app.integer.layout_size_10'), bottom: $r('app.integer.layout_size_10') })
215        .border({
216          width: { bottom: this.currentTabIndex === index ? $r('app.integer.layout_size_4') : 0 },
217          color: { bottom: $r('app.color.font_color_blue') },
218          radius: { bottomLeft: $r('app.integer.layout_size_2'), bottomRight: $r('app.integer.layout_size_2') }
219        })
220    }.margin({ right: $r('app.integer.layout_size_20') })
221  }
222
223  build() {
224    Column() {
225      Row() {
226        Row() {
227          this.TabBuilder($r('app.string.share_count'), Constants.TAB_INDEX_0)
228          this.TabBuilder($r('app.string.comment_count'), Constants.TAB_INDEX_1)
229        }
230
231        Row() {
232          Text($r('app.string.like_count'))
233            .fontSize($r('app.integer.layout_size_21'))
234            .fontColor($r('app.color.font_color_datetime'))
235        }
236      }
237      .height(56)
238      .width('100%')
239      .justifyContent(FlexAlign.SpaceBetween)
240
241      Row() {
242        Row() {
243          Image($r('app.media.sequence'))
244            .width($r('app.integer.layout_size_21'))
245            .height($r('app.integer.layout_size_21'))
246            .margin({ right: $r('app.integer.layout_size_12') })
247          Text($r('app.string.hot'))
248            .fontFamily('HarmonyHeiTi-Medium')
249            .fontSize($r('app.integer.layout_size_16'))
250            .fontColor($r('app.color.font_color_blue'))
251        }
252      }.width('100%')
253      .margin({ top: $r('app.integer.layout_size_10'), bottom: $r('app.integer.layout_size_10') })
254      .justifyContent(FlexAlign.End)
255      .onClick(() => {
256        promptActionFn($r('app.string.feature_development'));
257      })
258
259      List() {
260        LazyForEach(this.commentDataSource, (item: Trends, index: number) => {
261          ListItem() {
262            CommentItem({ commentsData: item, itemIndex: index })
263          }
264        }, (item: Trends) => JSON.stringify(item))
265      }.cachedCount(4)
266      .width('100%')
267    }.padding({ left: $r('app.integer.layout_size_20'), right: $r('app.integer.layout_size_20') })
268
269  }
270}
271
272@Component
273struct CommentItem {
274  // 初始化断点
275  @StorageLink('currentBreakpoint') currentBreakpoint: string = 'sm';
276  // 初始化评论数据
277  private commentsData: Trends = new Trends(new UserInfo(0, $r('app.media.photo115'), '', '', ''), new ContentsType('', [], []), '', 0, 0, 0) as Trends;
278  private itemIndex: number = 0;
279
280  /**
281   * 加载聊天列表数据,到参数传入的懒加载数据列表中
282   * @param count 数值
283   */
284  handleCount(count: number) {
285    if (count > Constants.UNIT_10000) {
286      return `${(count / Constants.UNIT_10000).toFixed(1)}w`;
287    } else if (count > Constants.UNIT_1000 && count < Constants.UNIT_10000) {
288      return `${(count / Constants.UNIT_1000).toFixed(1)}k`;
289    } else {
290      return count.toString()
291    }
292  }
293
294  build() {
295    Row() {
296      Row() {
297        Image(this.commentsData.user.userImage)
298          .width($r('app.integer.layout_size_42'))
299          .height($r('app.integer.layout_size_42'))
300          .borderRadius($r('app.integer.layout_size_21'))
301        Column() {
302          Row() {
303            Text(this.commentsData.user.userName)
304              .fontSize($r('app.integer.layout_size_18'))
305              .fontFamily('HarmonyHeiTi-Medium')
306              .width(this.currentBreakpoint === 'sm' ? $r('app.integer.layout_size_236') : $r('app.integer.layout_size_260'))
307            Row() {
308              Image($r('app.media.ic_thumbsup'))
309                .opacity($r('app.float.icon'))
310                .width($r('app.integer.layout_size_28'))
311                .height($r('app.integer.layout_size_26'))
312                .margin({ left: $r('app.integer.layout_size_10') })
313                .onClick(() => {
314                  promptActionFn($r('app.string.feature_development'))
315                })
316              Text(this.handleCount(this.commentsData.likeCount))
317                .margin({ right: $r('app.integer.layout_size_24') })
318                .width($r('app.integer.layout_size_38'))
319                .textAlign(TextAlign.Center)
320                .opacity($r('app.float.opacity'))
321              Image($r('app.media.ic_share'))
322                .opacity($r('app.float.icon'))
323                .width($r('app.integer.layout_size_24'))
324                .height($r('app.integer.layout_size_24'))
325                .margin({ right: $r('app.integer.layout_size_2') })
326                .onClick(() => {
327                  promptActionFn($r('app.string.feature_development'))
328                })
329            }.width($r('app.integer.layout_size_122')).alignItems(VerticalAlign.Center)
330          }
331
332          Row() {
333            Text(this.commentsData.dateTime)
334              .fontSize($r('app.integer.layout_size_16'))
335              .fontColor($r('app.color.font_color_datetime'))
336
337            Text(this.commentsData.user.userType)
338              .fontSize($r('app.integer.layout_size_16'))
339              .fontColor($r('app.color.font_color_datetime'))
340              .margin({ left: $r('app.integer.layout_size_6') })
341          }
342          .margin({ top: $r('app.integer.layout_size_6') })
343
344          Text(this.commentsData.contents.text)
345            .fontSize($r('app.integer.layout_size_21'))
346            .fontFamily('HarmonyHeiTi')
347            .margin({ top: $r('app.integer.layout_size_6') })
348          if (this.itemIndex === 1) {
349            Text($r('app.string.comments'))
350              .opacity($r('app.float.opacity'))
351              .width('100%')
352              .height($r('app.integer.layout_size_42'))
353              .fontFamily('HarmonyHeiTi')
354              .backgroundColor('#fff5f5f5')
355              .borderRadius($r('app.integer.layout_size_6'))
356              .padding({ left: $r('app.integer.layout_size_16') })
357              .margin({ top: $r('app.integer.layout_size_12') })
358          }
359        }
360        .alignItems(HorizontalAlign.Start)
361        .justifyContent(FlexAlign.Start)
362        .margin({ left: $r('app.integer.layout_size_10') })
363        .padding({ bottom: $r('app.integer.layout_size_16') })
364        .border({
365          width: { bottom: Constants.BORDERWIDTH },
366          color: { bottom: $r('app.color.border_color') },
367        })
368      }.alignItems(VerticalAlign.Top)
369    }.width('100%')
370    .justifyContent(FlexAlign.SpaceBetween)
371    .margin({ top: $r('app.integer.layout_size_10'), bottom: $r('app.integer.layout_size_10') })
372  }
373}
374