• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 Hunan OpenValley Digital Industry Development 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 Logger from '../../utils/Logger';
18import { ChatSource } from '../data/DataSource';
19import ChatComponent from '../../component/ChatComponent'
20import { ChatBox } from '../data/ChatBox'
21import { getMockTool } from '../../mock/MockData'
22import Tool from '../data/Tool'
23import User from '../data/User'
24import ChatController from '../../controller/ChatController';
25import LoginResult from '../data/LoginResult';
26
27const TAG: string = '[ChatPage]';
28
29@Entry
30@Component
31struct ChatPage {
32  private scroller: Scroller = new Scroller();
33  private scrollerTool: Scroller = new Scroller();
34  @State chats: ChatSource = new ChatSource();
35  private toolArr: Array<Tool> = getMockTool(); // 用户信息模拟数据
36  @State isSend: boolean = true; // 是否为发送消息
37  @State isInput: boolean = false; // 是否正在输入
38  private currentUser: User | null = null; // 当前用户信息
39  private oppositeUser: User | null = null; // 对端用户信息
40  private userInfo: LoginResult | null = null; // 登录返回结果信息
41  private chatController: ChatController = new ChatController();
42  @State inputValue: string = '';
43
44  aboutToAppear() {
45    if (AppStorage.get("currentUser")) {
46      this.currentUser = AppStorage.get("currentUser")!;
47    }
48    if (AppStorage.get("oppositeUser")) {
49      this.oppositeUser = AppStorage.get("oppositeUser")!;
50    }
51    if (AppStorage.get("userInfo")) {
52      this.userInfo = AppStorage.get("userInfo")!;
53    }
54
55    this.chatController.onMessage(this.userInfo?.getId(), (value: string) => {
56      Logger.info(TAG, `ChatPage onMessage begin msg value: ${value}`);
57      if (value) {
58        this.chats.pushData(new ChatBox(false, value, this.oppositeUser?.getUserIcon()));
59      }
60    })
61
62  }
63
64  build() {
65    Column() {
66      Row() {
67        Image($r('app.media.app_icon'))
68          .id('chatBack')
69          .width(20)
70          .height(20)
71          .objectFit(ImageFit.Contain)
72          .margin({ left: 16 })
73          .onClick(e => {
74            router.back();
75          })
76        Image($r('app.media.app_icon'))
77          .width(50)
78          .height(50)
79          .objectFit(ImageFit.Contain)
80          .margin({ left: 16, right: 16 })
81          .borderRadius(25)
82        Text(this.oppositeUser?.getUsername())
83          .height(30)
84          .fontColor($r('app.color.COLOR_FFFFFF'))
85          .fontSize(20)
86          .fontFamily($r('app.string.Font_family_regular'))
87          .textAlign(TextAlign.Center)
88
89        Blank()
90
91        Image($r('app.media.app_icon'))
92          .width(32)
93          .height(32)
94          .objectFit(ImageFit.Contain)
95          .margin({ left: 20 })
96        Image($r('app.media.app_icon'))
97          .width(32)
98          .height(32)
99          .objectFit(ImageFit.Contain)
100          .margin({ left: 20 })
101        Image($r('app.media.app_icon'))
102          .width(32)
103          .height(32)
104          .objectFit(ImageFit.Contain)
105          .margin({ left: 20, right: 20 })
106      }
107      .width('100%')
108      .height('8%')
109      .justifyContent(FlexAlign.SpaceBetween)
110
111      Divider()
112        .vertical(false)
113        .height(2)
114        .color($r('app.color.COLOR_1E1E1E'))
115
116      // 消息滚动面板
117      Column() {
118        Scroll(this.scroller) {
119          Column() {
120            LazyForEach(this.chats, (item: ChatBox, index: number) => {
121              Row() {
122                ChatComponent({ item: item })
123              }
124              .margin({ top: 5, bottom: 10 })
125            }, (item: ChatBox) => item.message)
126          }
127          .width('100%')
128          .margin({ top: 10 })
129        }
130        .scrollable(ScrollDirection.Vertical)
131        .scrollBar(BarState.Off)
132        .width('100%')
133        .height('100%')
134        .margin({ bottom: 8 })
135        .align(Alignment.Top)
136      }
137      .width('100%')
138      .height('75%')
139
140      Column() {
141        // 工具栏
142        Row() {
143          // 横向工具栏列表
144          Scroll(this.scrollerTool) {
145            Row() {
146              ForEach(this.toolArr, (tool: Tool) => {
147                Row() {
148                  Image($r('app.media.app_icon'))
149                    .width(30)
150                    .height(30)
151                    .objectFit(ImageFit.Contain)
152                    .margin({ right: 8 })
153                  Text(tool.getToolName())
154                    .height(20)
155                    .fontColor($r('app.color.COLOR_E6FFFFFF'))
156                    .fontSize(16)
157                    .fontFamily($r('app.string.Font_family_regular'))
158                    .textAlign(TextAlign.Center)
159                    .textOverflow({ overflow: TextOverflow.Ellipsis })
160                }
161                .width(120)
162                .height('80%')
163                .margin({ left: 12 })
164                .backgroundColor($r('app.color.COLOR_393939'))
165                .borderRadius(18)
166                .justifyContent(FlexAlign.Center)
167              })
168            }
169            .height('100%')
170            .justifyContent(FlexAlign.Start)
171          }
172          .scrollable(ScrollDirection.Horizontal)
173          .scrollBar(BarState.Off)
174          .width('95%')
175          .height('100%')
176        }
177        .width('100%')
178        .height('40%')
179
180        // 消息输入框
181        Row() {
182          this.inputComponent()
183        }
184        .width('100%')
185        .height('60%')
186      }
187      .width('100%')
188      .height('17%')
189    }
190    .width('100%')
191    .height('100%')
192    .backgroundColor($r('app.color.COLOR_000000'))
193  }
194
195  @Builder
196  inputComponent() {
197    Stack() {
198      Row()
199        .width('95%')
200        .height('70%')
201        .borderRadius(32)
202        .backgroundColor($r('app.color.COLOR_393939'))
203
204      if (this.isInput) {
205        Row() {
206          Row() {
207            Image($r('app.media.app_icon'))
208              .width(26)
209              .height(26)
210              .objectFit(ImageFit.Contain)
211          }
212          .width(44)
213          .height(44)
214          .margin({ left: 5 })
215          .borderRadius(22)
216          .backgroundColor($r('app.color.COLOR_168CF6'))
217          .justifyContent(FlexAlign.Center)
218
219          Blank()
220
221          Image($r('app.media.app_icon'))
222            .width(42)
223            .height(42)
224            .objectFit(ImageFit.Contain)
225
226          Row() {
227            Image($r('app.media.app_icon'))
228              .width(32)
229              .height(32)
230              .objectFit(ImageFit.Contain)
231          }
232          .id('msgSend')
233          .width(36)
234          .height(36)
235          .margin({ left: 15, right: 10 })
236          .borderRadius(22)
237          .backgroundColor($r('app.color.COLOR_FE2B54'))
238          .justifyContent(FlexAlign.Center)
239          .onClick(e => {
240            Logger.info(TAG, 'onClick send');
241            if (this.inputValue) {
242              this.chats.pushData(new ChatBox(true, this.inputValue, this.currentUser?.getUserIcon()));
243              this.chatController.sendMessage(this.oppositeUser?.getUsername(), this.inputValue);
244              this.inputValue = '';
245            }
246          })
247        }
248        .width('95%')
249        .height('70%')
250      } else {
251        Row() {
252          Row() {
253            Image($r('app.media.app_icon'))
254              .width(28)
255              .height(28)
256              .objectFit(ImageFit.Contain)
257          }
258          .width(44)
259          .height(44)
260          .margin({ left: 5 })
261          .borderRadius(22)
262          .backgroundColor($r('app.color.COLOR_AE4EF7'))
263          .justifyContent(FlexAlign.Center)
264
265          Blank()
266
267          Image($r('app.media.app_icon'))
268            .width(42)
269            .height(42)
270            .objectFit(ImageFit.Contain)
271          Image($r('app.media.app_icon'))
272            .width(42)
273            .height(42)
274            .objectFit(ImageFit.Contain)
275            .margin({ left: 15, right: 15 })
276          Image($r('app.media.app_icon'))
277            .width(36)
278            .height(36)
279            .objectFit(ImageFit.Contain)
280            .margin({ right: 10 })
281        }
282        .width('95%')
283        .height('70%')
284      }
285
286      TextInput({ placeholder: $r('app.string.Send_Message'), text: this.inputValue })
287        .id('chatInput')
288        .width('50%')
289        .height('65%')
290        .placeholderColor($r('app.color.COLOR_99F1F3F5'))
291        .backgroundColor($r('app.color.COLOR_393939'))
292        .fontColor($r('app.color.COLOR_FFFFFF'))
293        .offset({ x: -50 })
294        .padding({ left: 0 })
295        .onChange(value => {
296          Logger.info(TAG, `TextInput onChange value= ${value}`);
297          this.inputValue = value;
298          if (this.inputValue) {
299            this.isInput = true;
300          } else {
301            this.isInput = false;
302          }
303        })
304    }
305    .alignContent(Alignment.Center)
306    .width('100%')
307    .height('100%')
308    .backgroundColor($r('app.color.COLOR_000000'))
309  }
310}