• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2022 The Android Open Source Project
2//
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
15import m from 'mithril';
16
17import {
18  RecordingTargetV2,
19  TargetFactory,
20} from '../../common/recordingV2/recording_interfaces_v2';
21import {RecordingPageController} from '../../common/recordingV2/recording_page_controller';
22import {RECORDING_MODAL_DIALOG_KEY} from '../../common/recordingV2/recording_utils';
23import {closeModal} from '../../widgets/modal';
24
25interface RecordingMultipleChoiceAttrs {
26  targetFactories: TargetFactory[];
27  // Reference to the controller which maintains the state of the recording
28  // page.
29  controller: RecordingPageController;
30}
31
32export class RecordingMultipleChoice
33  implements m.ClassComponent<RecordingMultipleChoiceAttrs>
34{
35  private selectedIndex: number = -1;
36
37  targetSelection(
38    targets: RecordingTargetV2[],
39    controller: RecordingPageController,
40  ): m.Vnode | undefined {
41    const targetInfo = controller.getTargetInfo();
42    const targetNames = [];
43    this.selectedIndex = -1;
44    for (let i = 0; i < targets.length; i++) {
45      const targetName = targets[i].getInfo().name;
46      targetNames.push(m('option', targetName));
47      if (targetInfo && targetName === targetInfo.name) {
48        this.selectedIndex = i;
49      }
50    }
51
52    const selectedIndex = this.selectedIndex;
53    return m(
54      'label',
55      m(
56        'select',
57        {
58          selectedIndex,
59          onchange: (e: Event) => {
60            controller.onTargetSelection((e.target as HTMLSelectElement).value);
61          },
62          onupdate: (select) => {
63            // Work around mithril bug
64            // (https://github.com/MithrilJS/mithril.js/issues/2107): We
65            // may update the select's options while also changing the
66            // selectedIndex at the same time. The update of selectedIndex
67            // may be applied before the new options are added to the
68            // select element. Because the new selectedIndex may be
69            // outside of the select's options at that time, we have to
70            // reselect the correct index here after any new children were
71            // added.
72            (select.dom as HTMLSelectElement).selectedIndex =
73              this.selectedIndex;
74          },
75          ...{size: targets.length, multiple: 'multiple'},
76        },
77        ...targetNames,
78      ),
79    );
80  }
81
82  view({attrs}: m.CVnode<RecordingMultipleChoiceAttrs>): m.Vnode[] | undefined {
83    const controller = attrs.controller;
84    if (!controller.shouldShowTargetSelection()) {
85      return undefined;
86    }
87    const targets: RecordingTargetV2[] = [];
88    for (const targetFactory of attrs.targetFactories) {
89      for (const target of targetFactory.listTargets()) {
90        targets.push(target);
91      }
92    }
93    if (targets.length === 0) {
94      return undefined;
95    }
96
97    return [
98      m('text', 'Select target:'),
99      m(
100        '.record-modal-command',
101        this.targetSelection(targets, controller),
102        m(
103          'button.record-modal-button-high',
104          {
105            disabled: this.selectedIndex === -1,
106            onclick: () => {
107              closeModal(RECORDING_MODAL_DIALOG_KEY);
108              controller.onStartRecordingPressed();
109            },
110          },
111          'Connect',
112        ),
113      ),
114    ];
115  }
116}
117