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