Completed
Push — master ( 4fcad4...efcce7 )
by Muhammad Dyas
19s queued 16s
created

PollCard.choiceSection   B

Complexity

Conditions 5

Size

Total Lines 28
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 21
dl 0
loc 28
rs 8.9093
c 0
b 0
f 0
1
import BaseCard from './BaseCard';
2
import {PollState, Voter} from '../helpers/interfaces';
3
import {chat_v1 as chatV1} from 'googleapis/build/src/apis/chat/v1';
4
import {ICON_URL_48X48} from '../config/default';
5
import {progressBarText} from '../helpers/vote';
6
7
export default class PollCard extends BaseCard {
8
  private readonly state: PollState;
9
10
  constructor(state: PollState) {
11
    super();
12
    this.state = state;
13
  }
14
15
  create() {
16
    this.buildHeader();
17
    this.buildSections();
18
    this.buildButtons();
19
    return this.card;
20
  }
21
22
  buildHeader() {
23
    if (this.state.topic.length > 40) {
24
      const widgetHeader = this.sectionHeader();
25
      this.card.sections!.slice().unshift(widgetHeader);
26
    } else {
27
      this.card.header = this.cardHeader();
28
    }
29
  }
30
31
  getAuthorName() {
32
    return this.state.author?.displayName ?? '';
33
  }
34
35
  getSerializedState() {
36
    return JSON.stringify(this.state);
37
  }
38
39
  cardHeader(): chatV1.Schema$GoogleAppsCardV1CardHeader {
40
    return {
41
      title: this.state.topic,
42
      subtitle: `Posted by ${this.getAuthorName()}`,
43
      imageUrl: ICON_URL_48X48,
44
      imageType: 'CIRCLE',
45
    };
46
  }
47
48
  sectionHeader(): chatV1.Schema$GoogleAppsCardV1Section {
49
    return {
50
      widgets: [
51
        {
52
          'decoratedText': {
53
            'text': this.state.topic,
54
            'wrapText': true,
55
            'bottomLabel': `Posted by ${this.getAuthorName()}`,
56
            'startIcon': {
57
              'altText': 'Absolute Poll',
58
              'iconUrl': ICON_URL_48X48,
59
              'imageType': 'SQUARE',
60
            },
61
          },
62
        },
63
      ],
64
    };
65
  }
66
67
  buildSections() {
68
    const votes: Array<Array<Voter>> = Object.values(this.state.votes!);
69
    const totalVotes: number = votes.reduce((sum, vote) => sum + vote.length, 0);
70
    for (let i = 0; i < this.state.choices.length; ++i) {
71
      const creator = this.state.choiceCreator?.[i] ?? '';
72
      const section = this.choiceSection(i, totalVotes, creator);
73
      this.card.sections!.push(section);
74
    }
75
  }
76
77
  buildButtons() {
78
    if (this.state.optionable) {
79
      this.card.sections!.push(
80
        {
81
          'widgets': [
82
            {
83
              'buttonList': {
84
                'buttons': [
85
                  {
86
                    'text': 'Add Option',
87
                    'onClick': {
88
                      'action': {
89
                        'function': 'add_option_form',
90
                        'interaction': 'OPEN_DIALOG',
91
                        'parameters': [],
92
                      },
93
                    },
94
                  },
95
                ],
96
              },
97
            },
98
          ],
99
        });
100
    }
101
  }
102
103
  choiceSection(i: number, totalVotes: number, creator = '') {
104
    if (this.state.votes === undefined) {
105
      this.state.votes = {};
106
    }
107
108
    if (this.state.votes[i] === undefined) {
109
      this.state.votes[i] = [];
110
    }
111
    const voteCount = this.state.votes[i].length;
112
    const choiceTag = this.choice(i, this.state.choices[i], voteCount, totalVotes);
113
    if (creator) {
114
      choiceTag.decoratedText!.topLabel = 'Added by ' + creator;
115
    }
116
    const section: chatV1.Schema$GoogleAppsCardV1Section = {
117
      widgets: [choiceTag],
118
    };
119
    if (this.state.votes[i].length > 0 && !this.state.anon) {
120
      section.collapsible = true;
121
      section.uncollapsibleWidgetsCount = 1;
122
      // @ts-ignore: already defined above
123
      section.widgets.push({
124
        'textParagraph': {
125
          'text': this.state.votes[i].map((u) => u.name).join(', '),
126
        },
127
      });
128
    }
129
    return section;
130
  }
131
132
  choice(index: number, text: string, voteCount: number, totalVotes: number): chatV1.Schema$GoogleAppsCardV1Widget {
133
    const progressBar = progressBarText(voteCount, totalVotes);
134
    return {
135
      decoratedText: {
136
        bottomLabel: `${progressBar} ${voteCount}`,
137
        text: text,
138
        button: {
139
          text: 'vote',
140
          onClick: {
141
            action: {
142
              function: 'vote',
143
              parameters: [
144
                {
145
                  key: 'state',
146
                  value: this.getSerializedState(),
147
                },
148
                {
149
                  key: 'index',
150
                  value: index.toString(10),
151
                },
152
              ],
153
            },
154
          },
155
        },
156
      },
157
    };
158
  }
159
}
160