1/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17'use strict';
18
19class DeviceListApp {
20  #url;
21  #selectDeviceCb;
22
23  constructor({url, selectDeviceCb}) {
24    this.#url = url;
25    this.#selectDeviceCb = selectDeviceCb;
26  }
27
28  start() {
29    // Get any devices that are already connected
30    this.#UpdateDeviceList();
31
32    // Update the list at the user's request
33    document.getElementById('refresh-list')
34        .addEventListener('click', evt => this.#UpdateDeviceList());
35  }
36
37  async #UpdateDeviceList() {
38    try {
39      const device_ids = await fetch(this.#url, {
40        method: 'GET',
41        cache: 'no-cache',
42        redirect: 'follow',
43      });
44      this.#ShowNewDeviceList(await device_ids.json());
45    } catch (e) {
46      console.error('Error getting list of device ids: ', e);
47    }
48  }
49
50  #ShowNewDeviceList(device_ids) {
51    let ul = document.getElementById('device-list');
52    ul.innerHTML = '';
53    let count = 1;
54    let device_to_button_map = {};
55    for (const devId of device_ids) {
56      const buttonId = 'connect_' + count++;
57      let entry = this.#createDeviceEntry(devId, buttonId);
58      ul.appendChild(entry);
59      device_to_button_map[devId] = buttonId;
60    }
61
62    for (const [devId, buttonId] of Object.entries(device_to_button_map)) {
63      let button = document.getElementById(buttonId);
64      button.addEventListener('click', evt => {
65        this.#selectDeviceCb(devId);
66      });
67    }
68  }
69
70  #createDeviceEntry(devId, buttonId) {
71    let li = document.createElement('li');
72    li.className = 'device_entry';
73    li.title = 'Connect to ' + devId;
74    let div = document.createElement('div');
75    let span = document.createElement('span');
76    span.appendChild(document.createTextNode(devId));
77    let button = document.createElement('button');
78    button.id = buttonId;
79    button.appendChild(document.createTextNode('Connect'));
80    div.appendChild(span);
81    div.appendChild(button);
82    li.appendChild(div);
83    return li;
84  }
85}  // DeviceListApp
86
87window.addEventListener('load', e => {
88  let listDevicesUrl = '/devices';
89  let selectDeviceCb = deviceId => {
90    return new Promise((resolve, reject) => {
91      let client = window.open(`client.html?deviceId=${deviceId}`, deviceId);
92      client.addEventListener('load', evt => {
93        console.debug('loaded');
94        resolve();
95      });
96    });
97  };
98  let deviceListApp = new DeviceListApp({url: listDevicesUrl, selectDeviceCb});
99  deviceListApp.start();
100});
101