• 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 { BusinessError } from '@ohos.base';
17import { staffItem } from './staff';
18import Constants from '../constant';
19import { AccountTipsConfig } from '../AccountTipsConfig';
20import { HiLog } from '../HiLog';
21
22interface Staff {
23  authAccount: string;
24  textContent: string;
25}
26
27const TAG = 'AddStaff';
28
29@Extend(Text)
30function inputMessageText() {
31  .fontSize($r('sys.float.ohos_id_text_size_body3'))
32  .lineHeight(Constants.PP_TEXT_LINE_HEIGHT2)
33  .fontColor($r('sys.color.ohos_id_color_handup'))
34  .fontWeight(FontWeight.Medium)
35  .margin({ top: Constants.ENCRYPTION_ADD_STAFF_BORDER_MARGIN_TOP })
36  .textAlign(TextAlign.Start)
37}
38
39@Component
40struct AddStaff {
41  @State succ: number = 0;
42  @State fail: number = 0;
43  @Link isAccountCheckSuccess: boolean;
44  @State staffArrayLength: boolean = false;
45  @State @Watch('onErrorStyleChange') isInputInvalid: boolean = false;
46  @State isNetworkInvalid: boolean = false;
47  @State textContent: string = '';
48  @Link @Watch('onDataChange') staffArray: Staff[];
49  @State focusFlag: boolean = false;
50  @Prop isDisable: boolean = false;
51  @State isInitDataStatus: boolean = false;
52  @State errInput: string[] = [];
53  @State inputArray: string[] = [];
54  @State isInputInvalidFlag: boolean = false;
55  private controller: RichEditorController = new RichEditorController();
56  private options: RichEditorOptions = { controller: this.controller };
57
58  @Builder
59  StaffItemBuilder(authAccount: string, textContent: string, index: number) {
60    Column() {
61      staffItem({
62        authAccount: authAccount,
63        textContent: textContent,
64        isActive: true,
65        changeIndex: Number(index)
66      });
67    }
68    .alignItems(HorizontalAlign.Start);
69  }
70
71  removeItem(i: number) {
72    this.staffArray.splice(i, 1)
73    this.staffArrayLength = false;
74  }
75
76  private async onSubmitMock(inputId: string, startOffset: number[], endOffset: number[]) {
77    if (!inputId) {
78      return;
79    }
80    if (this.staffArray.length >= Constants.ENCRYPTION_ADD_STAFF_LENGTH_MAX) {
81      this.staffArrayLength = true;
82      this.deleteBuildSpan(startOffset, endOffset);
83      return;
84    }
85    this.isAccountCheckSuccess = false;
86    let regex: RegExp = new RegExp('(\r|\n)*', 'g');
87    let inputString = inputId.replace(regex, '');
88    this.inputArray = inputString.split(';');
89    this.errInput = [];
90    if (this.inputArray.length > Constants.RICH_EDITOR_FIRST) {
91      this.deleteBuildSpan(startOffset, endOffset);
92    }
93    for (let i = 0; i < this.inputArray.length; i++) {
94      if (!this.inputArray[i]) {
95        continue;
96      }
97      if (this.staffArray.length >= Constants.ENCRYPTION_ADD_STAFF_LENGTH_MAX) {
98        this.errInput = [];
99        break;
100      }
101      await this.createStaffByDomain(i, startOffset, endOffset);
102    }
103    this.isAccountCheckSuccess = true;
104    if (this.staffArray.length < Constants.ENCRYPTION_ADD_STAFF_LENGTH_MAX) {
105      this.controller.addTextSpan(this.errInput.join(';'));
106      if (this.errInput.length && this.isInputInvalidFlag) {
107        this.isInputInvalid = true;
108      }
109    }
110  }
111
112  private createStaffByDomain(i: number, startOffset: number[], endOffset: number[]) {
113    return new Promise<void>(async (resolve, reject) => {
114      try {
115        let result = await AccountTipsConfig.getAccountInfo(this.inputArray[i]);
116        let o1: Staff = {
117          authAccount: result.accountName,
118          textContent: result[this.textContent] as string
119        };
120        this.staffArray.push(o1);
121        if (this.inputArray.length === Constants.RICH_EDITOR_FIRST) {
122          this.deleteBuildSpan(startOffset, endOffset);
123        }
124        this.succ = AppStorage.get('hiAccountVerifySucc') as number + 1;
125        AppStorage.setOrCreate('hiAccountVerifySucc', this.succ);
126        this.addBuildSpan(i, result[this.textContent]);
127      } catch (error) {
128        HiLog.info(TAG, `getAccountInfo fail: ${JSON.stringify(error)}`);
129        this.showErrInput(i, error, startOffset, endOffset);
130      }
131      resolve();
132    });
133  }
134
135  private deleteBuildSpan(startOffset: number[], endOffset: number[]) {
136    for (let i: number = startOffset.length - 1; i >= 0; i--) {
137      this.controller.deleteSpans({ start: startOffset[i], end: endOffset[i] });
138    }
139  }
140
141  private addBuildSpan(i: number, textContent: string) {
142    let index: number = this.controller.getCaretOffset();
143    let staffBuilder: CustomBuilder = () => {
144      this.StaffItemBuilder(this.inputArray[i], textContent, index);
145    };
146    this.controller.addBuilderSpan(staffBuilder);
147  }
148
149  private showErrInput(i: number, error: BusinessError, startOffset: number[], endOffset: number[]) {
150    if (this.inputArray.length === Constants.RICH_EDITOR_FIRST) {
151      this.deleteBuildSpan(startOffset, endOffset);
152    }
153    this.errInput.push(this.inputArray[i]);
154    this.fail = AppStorage.get('hiAccountVerifyFail') as number + 1;
155    AppStorage.setOrCreate('hiAccountVerifyFail', this.fail);
156    if ([
157      Constants.ERR_JS_INVALID_PARAMETER,
158      Constants.ERR_JS_ACCOUNT_NOT_FOUND
159    ].includes(error.code)) {
160      this.isInputInvalidFlag = true;
161    } else {
162      this.isNetworkInvalid = true;
163    }
164  }
165
166  private onDataChange() {
167    !this.isInitDataStatus && this.staffArray && this.staffArray.forEach((item: Staff, index: number) => {
168      let staffItemBuilder: CustomBuilder = () => {
169        this.StaffItemBuilder(item.authAccount, item.textContent, index);
170      };
171      this.controller.addBuilderSpan(staffItemBuilder);
172    });
173  }
174
175  private onErrorStyleChange() {
176    this.controller.updateSpanStyle({
177      textStyle: {
178        fontSize: $r('sys.float.ohos_id_text_size_body1'),
179        fontColor: this.isInputInvalid ?
180        $r('sys.color.ohos_id_color_handup') : $r('sys.color.ohos_id_color_text_primary')
181      }
182    });
183  }
184
185  async aboutToAppear() {
186    await AccountTipsConfig.getConfigTips();
187    this.textContent = AccountTipsConfig.showContentKey;
188    if (this.staffArray.length) {
189      setTimeout(() => {
190        this.onDataChange();
191      }, Constants.ENCRYPTION_SET_TIMEOUT_TIME);
192    }
193  }
194
195  build() {
196    Column() {
197      Flex({
198        direction: FlexDirection.Row,
199        wrap: FlexWrap.Wrap,
200      }) {
201        RichEditor(this.options)
202          .placeholder(!this.staffArray.length ? ($r('app.string.enter_a_complete_work_ID')) : '',
203            {
204              font: { size: $r('sys.float.ohos_id_text_size_body1') },
205              fontColor: $r('sys.color.ohos_id_color_text_hint')
206            })
207          .flexGrow(Constants.ENCRYPTION_ADD_STAFF_FLEX_GROW)
208          .backgroundColor($r('sys.color.ohos_id_color_dialog_bg'))
209          .borderRadius(Constants.PP_ROW_RADIUS)
210          .align(Alignment.Center)
211          .padding({
212            top: Constants.PP_BUTTON_PAD,
213            bottom: Constants.PP_BUTTON_PAD,
214            left: Constants.PP_BUTTON_PAD,
215            right: Constants.PP_BUTTON_PAD
216          })
217          .width(Constants.FOOTER_ROW_WIDTH)
218          .constraintSize({
219            minHeight: Constants.RICH_EDITOR_MIN_HEIGHT
220          })
221          .aboutToIMEInput((value: RichEditorInsertValue) => {
222            this.isInitDataStatus = true;
223            if (this.isInputInvalid || this.isNetworkInvalid) {
224              this.isInputInvalid = false;
225              this.isNetworkInvalid = false;
226            }
227            if (value.insertValue === Constants.ENTER_KEY_VALUE) {
228              let richEditorSpans: (RichEditorTextSpanResult | RichEditorImageSpanResult)[] =
229              this.controller.getSpans();
230              let inputId: string = '';
231              let startOffset: number[] = [];
232              let endOffset: number[] = [];
233              for (let index: number = 0; index < richEditorSpans.length; index++) {
234                let buildSpan: RichEditorTextSpanResult = richEditorSpans[index] as RichEditorTextSpanResult;
235                if (buildSpan.textStyle) {
236                  inputId += buildSpan.value;
237                  startOffset.push(buildSpan.spanPosition.spanRange[0]);
238                  endOffset.push(buildSpan.spanPosition.spanRange[1]);
239                }
240              }
241              if (this.isAccountCheckSuccess) {
242                this.onSubmitMock(inputId, startOffset, endOffset);
243              };
244              return false;
245            }
246            return true;
247          })
248          .aboutToDelete((value: RichEditorDeleteValue) => {
249            if (!value.richEditorDeleteSpans.length) {
250              return false;
251            };
252            this.isInitDataStatus = true;
253            if (this.isInputInvalid || this.isNetworkInvalid) {
254              this.isInputInvalid = false;
255              this.isNetworkInvalid = false;
256            }
257
258            let richEditorSpansAll: (RichEditorTextSpanResult | RichEditorImageSpanResult)[] =
259              this.controller.getSpans();
260
261            let richEditorDeleteSpans: (RichEditorTextSpanResult | RichEditorImageSpanResult)[] =
262            value.richEditorDeleteSpans;
263            let len = richEditorDeleteSpans[richEditorDeleteSpans.length - 1].spanPosition.spanIndex;
264            let textNum: number = 0;
265            for (let i = 0; i <= len; i++) {
266              let buildSpan: RichEditorTextSpanResult = richEditorSpansAll[i] as RichEditorTextSpanResult;
267              if (buildSpan?.textStyle) {
268                textNum++;
269              }
270            }
271            for (let index: number = richEditorDeleteSpans.length - 1; index >= 0; index--) {
272              let buildSpan: RichEditorImageSpanResult = richEditorDeleteSpans[index] as RichEditorImageSpanResult;
273              if (buildSpan.imageStyle) {
274                let spanIndex: number = buildSpan.spanPosition.spanIndex;
275                spanIndex -= textNum;
276                this.removeItem(spanIndex);
277              } else {
278                textNum--;
279              }
280            }
281            return true;
282          })
283      }
284      .onFocus(() => {
285        this.focusFlag = !this.focusFlag;
286      })
287      .onBlur(() => {
288        this.focusFlag = !this.focusFlag;
289      })
290
291      Divider()
292        .strokeWidth(this.focusFlag ?
293        px2vp(Constants.ENCRYPTION_ADD_STAFF_BORDER2) : px2vp(Constants.ENCRYPTION_ADD_STAFF_BORDER))
294        .color((this.isInputInvalid || this.staffArrayLength || this.isNetworkInvalid)
295          ? $r('sys.color.ohos_id_color_handup') :
296          this.focusFlag ? $r('sys.color.ohos_id_color_primary') : $r('sys.color.ohos_id_color_list_separator'))
297        .opacity(this.focusFlag ? Constants.FOOTER_OPACITY_SEPC : Constants.FOOTER_OPACITY_ONE);
298
299      Flex({ direction: FlexDirection.Row }) {
300        if (this.isInputInvalid && !this.isNetworkInvalid) {
301          Text($r('app.string.incorrect_work_ID'))
302            .inputMessageText()
303        }
304        if (this.isNetworkInvalid) {
305          Text($r('app.string.network_invalid'))
306            .inputMessageText()
307        }
308        Blank()
309        if (this.staffArray.length >=
310          Constants.ENCRYPTION_ADD_STAFF_LENGTH_MAX * Constants.ENCRYPTION_ADD_STAFF_LENGTH) {
311          Text(`${this.staffArray.length}/${Constants.ENCRYPTION_ADD_STAFF_LENGTH_MAX}`)
312            .fontSize($r('sys.float.ohos_id_text_size_body3'))
313            .lineHeight(Constants.PP_TEXT_LINE_HEIGHT2)
314            .fontColor(this.staffArrayLength
315              ? $r('sys.color.ohos_id_color_handup') : $r('sys.color.ohos_id_color_text_secondary'))
316            .fontWeight(FontWeight.Medium)
317            .margin({ top: Constants.ENCRYPTION_ADD_STAFF_BORDER_MARGIN_TOP })
318            .textAlign(TextAlign.End)
319        }
320      }
321    }
322    .opacity(this.isDisable ? Constants.DU_LINE_WIDTH : Constants.FOOTER_OPACITY_ONE)
323    .enabled(this.isDisable ? false : true)
324  }
325}
326
327export { AddStaff };
328