1/*
2 * Copyright (c) 2023-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
16const EMPTY_STRING: string = ''
17const MAX_PROGRESS: number = 100
18const MAX_PERCENTAGE: string = '100%'
19const MIN_PERCENTAGE: string = '0%'
20
21@Component
22export struct ProgressButton {
23  @Prop @Watch('getProgressContext') progress: number
24  @State textProgress: string = EMPTY_STRING
25  @Prop content: string = EMPTY_STRING
26  @State isLoading: boolean = false
27  progressButtonWidth?: Length = 44
28  clickCallback: () => void = null
29  @Prop enable: boolean = true
30
31  private getButtonProgress(): number {
32    if (this.progress < 0) {
33      return 0
34    } else if (this.progress > MAX_PROGRESS) {
35      return MAX_PROGRESS
36    }
37    return this.progress
38  }
39
40  private getProgressContext() {
41    if (this.progress < 0) {
42      this.isLoading = false
43      this.textProgress = MIN_PERCENTAGE
44    } else if (this.progress >= MAX_PROGRESS) {
45      this.isLoading = false
46      this.textProgress = MAX_PERCENTAGE
47    } else {
48      this.textProgress = Math.floor(this.progress / MAX_PROGRESS * MAX_PROGRESS).toString() + "%"
49    }
50  }
51
52  build() {
53    Button() {
54      Stack(){
55        Progress({ value: this.getButtonProgress(), total: MAX_PROGRESS,
56          style: ProgressStyle.Capsule })
57          .height(28)
58          .borderRadius(14)
59          .width('100%')
60          .hoverEffect(HoverEffect.None)
61          .clip(false)
62          .enabled(this.enable)
63        Row() {
64          Text(this.isLoading? this.textProgress: this.content)
65            .fontSize($r('sys.float.ohos_id_text_size_button3'))
66            .fontWeight(FontWeight.Medium)
67            .fontColor(this.isLoading? $r('sys.color.ohos_id_color_text_primary')
68              :$r('sys.color.ohos_id_color_emphasize'))
69            .maxLines(1)
70            .textOverflow({ overflow: TextOverflow.Ellipsis })
71            .padding({left: 8, right: 8})
72            .opacity(this.enable? 1.0: 0.4)
73        }
74      }
75    }
76    .borderRadius(14)
77    .clip(false)
78    .hoverEffect(HoverEffect.None)
79    .backgroundColor($r("sys.color.ohos_id_color_foreground_contrary"))
80    .border({ width: 0.5, color: this.enable ? $r("sys.color.ohos_id_color_toolbar_text_actived")
81      : $r('sys.color.ohos_id_color_foreground_contrary_disable') })
82    .constraintSize({minWidth: 44})
83    .width(this.progressButtonWidth < 44? 44: this.progressButtonWidth)
84    .stateEffect(this.enable)
85    .onClick(() => {
86      if(!this.enable){
87        return
88      }
89      if (this.progress < MAX_PROGRESS) {
90        this.isLoading = !this.isLoading
91      }
92      this.clickCallback && this.clickCallback()
93    })
94  }
95}