Merge tag 'dey-3.2-r3.1' into master
Digi Embedded Yocto 3.2-r3.1 Signed-off-by: Javier Viguera <javier.viguera@digi.com>
|
|
@ -31,8 +31,8 @@ The I2C connections for this example depend on the running platform:
|
|||
- **ConnectCore 6UL SBC Pro**: I2C connector of the board (J28).
|
||||
- VCC: Pin 3
|
||||
- GND: Pin 6
|
||||
- I2C-2 SDA: Pin 2
|
||||
- I2C-2 SCL: Pin 1
|
||||
- I2C-1 SDA: Pin 2
|
||||
- I2C-1 SCL: Pin 1
|
||||
- **ConnectCore 6UL SBC Express**: Expansion connector of the board (J8).
|
||||
- VCC: Pin 1
|
||||
- GND: Pin 6
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
#include <libgen.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
ConnectCore Demo Application
|
||||
============================
|
||||
|
||||
The ConnectCore demo allows you to monitor and manage your ConnectCore device
|
||||
from a friendly front-end.
|
||||
You can monitor device data, such as memory, CPU temperature and statistics, or
|
||||
network interfaces traffic. It allows you to toggle a user LED, reboot the
|
||||
device, and upgrade its firmware, as well as test its multimedia capabilities.
|
||||
|
||||
This demo is compatible with:
|
||||
|
||||
* ConnectCore 8M Mini Development Kit
|
||||
* ConnectCore 8M Nano Development Kit
|
||||
* ConnectCore 8X SBC Pro
|
||||
|
||||
Running the application
|
||||
-----------------------
|
||||
|
||||
The application is included in `dey-image-webkit` image. For more information,
|
||||
go to:
|
||||
|
||||
* [ConnectCore demo for ConnectCore 8M Mini](https://www.digi.com/resources/documentation/digidocs/embedded/dey/latest/cc8mmini/yocto_c_ccdemo-intro)
|
||||
* [ConnectCore demo for ConnectCore 8M Nano](https://www.digi.com/resources/documentation/digidocs/embedded/dey/latest/cc8mnano/yocto_c_ccdemo-intro)
|
||||
* [ConnectCore demo for ConnectCore 8X](https://www.digi.com/resources/documentation/digidocs/embedded/dey/latest/cc8x/yocto_c_ccdemo-intro)
|
||||
|
||||
License
|
||||
-------
|
||||
Copyright 2022, Digi International Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||
with or without fee is hereby granted, provided that the above copyright notice
|
||||
and this permission notice appears in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
|
|
@ -0,0 +1,820 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
Digi Demo - Dashboard
|
||||
</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="./static/css/stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||
<link href="./static/css/cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/css/bootstrap4-toggle.min.css" rel="stylesheet">
|
||||
<link href="./static/css/cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.3/css/bootstrap-slider.min.css" rel="stylesheet">
|
||||
<link href="./static/css/fontawesome5.15.4/all.min.css" rel="stylesheet">
|
||||
|
||||
<link rel="stylesheet" href="./static/css/general.css">
|
||||
<link rel="stylesheet" href="./static/css/toastr.css">
|
||||
|
||||
<!-- JS, Popper.js, and jQuery -->
|
||||
<script src="./static/js/code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
|
||||
<script src="./static/js/cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
|
||||
<script src="./static/js/stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
|
||||
<script src="./static/js/cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js"></script>
|
||||
<script src="./static/js/cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.3/bootstrap-slider.min.js"></script>
|
||||
<script type="text/javascript" src="./static/js/common.js"></script>
|
||||
<script type="text/javascript" src="./static/js/devices.js"></script>
|
||||
<script type="text/javascript" src="./static/js/jquery.pjax.js"></script>
|
||||
<script type="text/javascript" src="./static/js/jquery.matchHeight-min.js"></script>
|
||||
<script type="text/javascript" src="./static/js/toastr.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="topBar" class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
|
||||
<div class="nav-container">
|
||||
<a id="banner-link" class="navbar-brand align-middle" href="/">
|
||||
<div class="d-flex align-items-baseline">
|
||||
<img id="banner-logo" class="banner-icon" src="./static/images/Digi_logo_banner.png">
|
||||
<p id="banner-text">ConnectCore Demo</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="nav-right-container">
|
||||
|
||||
<div>
|
||||
<img src="./static/images/board.png" class="device-title-img" title="Device">
|
||||
</div>
|
||||
<div id="device-name">DEY DEVICE</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="bg-light" id="body-row">
|
||||
|
||||
<!-- Sidebar https://www.codeply.com/go/3e0RAjccRO/bootstrap-4-collapsing-sidebar-menu# -->
|
||||
<div id="sidebar-container" class="sidebar-expanded d-none d-md-block">
|
||||
<!-- d-* hides the Sidebar in smaller devices. Its items can be kept on the Navbar 'Menu' -->
|
||||
<div id="sidebar-contents">
|
||||
<!-- Bootstrap List Group -->
|
||||
|
||||
<ul id="sections" data-pjax class="list-group">
|
||||
<li>
|
||||
<a data-pjax href="index.html" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||
<span class="digi-menu-icon fas fa-tachometer-alt fa-fw fa-lg mr-3"></span>
|
||||
<span class="menu-collapsed">Dashboard</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a data-pjax href="multimedia.html" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||
<span class="digi-menu-icon fas fa-film fa-fw fa-lg mr-3"></span>
|
||||
<span class="menu-collapsed">Multimedia</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a data-pjax href="management.html" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||
<span class="digi-menu-icon fas fa-cog fa-fw fa-lg mr-3"></span>
|
||||
<span class="menu-collapsed">Management</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul id="collapsator" class="list-group">
|
||||
<a href="#top" data-toggle="sidebar-collapse" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||
<span id="collapse-icon" class="digi-menu-icon fas fa-fw fa-lg mr-3"></span>
|
||||
<span id="collapse-text" class="menu-collapsed">Collapse</span>
|
||||
</div>
|
||||
</a>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div id="loading">
|
||||
<img id="loading-image" src="./static/images/loading.gif" alt="Loading..." />
|
||||
</div>
|
||||
<div id="pjax-container">
|
||||
|
||||
<input type="file" id="file_to_upload" style="display:none"/>
|
||||
<div class="row justify-content-lg-center">
|
||||
<div class="col-lg-12 col-xl-12">
|
||||
<div class="column main-row">
|
||||
<div class="card dashboard-device-card">
|
||||
<div class="card-body">
|
||||
<div id="dashboard_device" class="dashboard-device">
|
||||
<div id="loading_popup" class="popup popup-loading shadow">
|
||||
<img class="popup-item" src="./static/images/loading.gif" alt="Loading..." />
|
||||
<div id="loading_popup_message" class="popup-text">Loading device...</div>
|
||||
</div>
|
||||
<div id="info_popup" class="popup popup-info shadow d-none">
|
||||
<div id="info_popup_title" class="popup-title">Error</div>
|
||||
<div id="info_popup_message" class="popup-text">-</div>
|
||||
</div>
|
||||
<div id="confirm_dialog" class="confirm-dialog d-none">
|
||||
<div class="device-card-header">
|
||||
<span class="fas fa-question-circle fa-lg mr-2"></span>
|
||||
<span id="confirm_dialog_title"></span>
|
||||
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="showPopup(ID_LOADING_WRAPPER, ID_CONFIRM_DIALOG, false)"></div>
|
||||
</div>
|
||||
<div id="confirm_dialog_message" class="confirm-dialog-message"></div>
|
||||
<div class="confirm-dialog-buttons-container">
|
||||
<div id="confirm_dialog_no_button" class="device-card-button confirm-dialog-button">No</div>
|
||||
<div id="confirm_dialog_yes_button" class="device-card-button confirm-dialog-button">Yes</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="loading_wrapper" class="loading-wrapper element-grayed">
|
||||
<div id="device_board" class="device-board">
|
||||
<div class="dashboard-top-panel shadow-sm">
|
||||
<div id="device_toolbar" class="device-toolbar">
|
||||
<div id="platform_name" class="platform-name"></div>
|
||||
<div id="device-button-show-info" class="device-button" onclick="setInfoPanelsVisible(true)">
|
||||
<img id="device-button-show-info-img" src="./static/images/show_info.png" width="32px" data-toggle="tooltip" data-placement="bottom" title="Show all information panels">
|
||||
</div>
|
||||
<div id="device-button-hide-info" class="device-button" onclick="setInfoPanelsVisible(false)">
|
||||
<img id="device-button-hide-info-img" src="./static/images/hide_info.png" width="32px" data-toggle="tooltip" data-placement="bottom" title="Hide all information panels">
|
||||
</div>
|
||||
</div>
|
||||
<div id="board_image_container" class="device-board-container">
|
||||
<center><img id="board_image" class="device-board-image" width="" src=""/></center>
|
||||
</div>
|
||||
</div>
|
||||
<div id="device_info" class="device-info">
|
||||
<div id="device_info_panel_header" class="device-card-header" style="cursor: pointer;" onclick="toggleDeviceInfoVisibility()">
|
||||
<span class="fas fa-info-circle fa-lg mr-2"></span>
|
||||
<span>Device information</span>
|
||||
<div id="device_info_toggle_button" class="fas fa-caret-down fa-lg device-card-header-button"></div>
|
||||
</div>
|
||||
<div id="device_info_panel_container" class="device-card-content shadow-sm" style="display: none;">
|
||||
<table>
|
||||
<tr>
|
||||
<td style="vertical-align: top;">
|
||||
<span class="device-card-content-text">Serial number:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="serial_number" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;">
|
||||
<span class="device-card-content-text">DEY version:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="dey_version" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;">
|
||||
<span class="device-card-content-text">Kernel version:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="kernel_version" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;">
|
||||
<span class="device-card-content-text">U-Boot version:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="uboot_version" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;">
|
||||
<span class="device-card-content-text">Module variant:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="module_variant" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;">
|
||||
<span class="device-card-content-text">Board variant:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="board_variant" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;">
|
||||
<span class="device-card-content-text">Board ID:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="board_id" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;">
|
||||
<span class="device-card-content-text">MCA FW version:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="mca_fw_version" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;">
|
||||
<span class="device-card-content-text">MCA HW version:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="mca_hw_version" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="device-error" class="device-error"></div>
|
||||
<div id="help_panel_area" class="help-panel-area fas fa-question fa-2x d-flex align-items-center justify-content-center" onclick="toggleHelpPopup()"></div>
|
||||
<div id="help_panel" class="help-panel">
|
||||
<span id="help_panel_arrow" class="help-arrow"></span>
|
||||
<div class="help-panel-content">
|
||||
<p><b>Welcome to the device dashboard.</b></p>
|
||||
<span>From this page you can explore and interact with the different device components. Hover and click the green-highlighted panels to discover the board interfaces and specific enabled functionality.</span>
|
||||
<div class="help-panel-button" onclick="setHelpPopupVisible(false)">Got it!</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="cpu_panel_area" class="panel-area panel-tooltip" onclick="toggleInfoPanelVisibility('cpu')">
|
||||
<span class="panel-tooltip-text">CPU stats</span>
|
||||
<span id="cpu_panel_icon" class="fas fa-microchip panel-area-icon"></span>
|
||||
</div>
|
||||
<div id="cpu_panel" class="device-card cpu-panel shadow-sm">
|
||||
<span id="cpu_panel_arrow" class="panel-arrow"></span>
|
||||
<div class="device-card-header">
|
||||
<span class="fas fa-microchip fa-lg mr-2"></span>
|
||||
<span>CPU stats</span>
|
||||
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="setInfoPanelVisible('cpu', false)"></div>
|
||||
</div>
|
||||
<div class="device-card-content">
|
||||
<div class="cpu-info">
|
||||
<table>
|
||||
<tr style="vertical-align: baseline;">
|
||||
<td>
|
||||
<span class="device-card-content-text">Usage:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="cpu_load" class="device-card-content-value">-</span> %
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="vertical-align: baseline;">
|
||||
<td>
|
||||
<span class="device-card-content-text">Uptime:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="cpu_uptime" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="vertical-align: baseline;">
|
||||
<td>
|
||||
<span class="device-card-content-text">Frequency:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="cpu_frequency" class="device-card-content-value">-</span> MHz
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="vertical-align: baseline;">
|
||||
<td>
|
||||
<span class="device-card-content-text">Temperature:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="cpu_temperature" class="device-card-content-value">-</span> C
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="cores">
|
||||
<div id="core-1" class="core">
|
||||
<table class="core-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan="2">
|
||||
<div class="core-name-container">
|
||||
<span class="digi-icon-color fas fa-microchip fa-2x"></span>
|
||||
<span>Core 1</span>
|
||||
</div>
|
||||
</td>
|
||||
<td><span id="core-1-usage">-</span> %</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span id="core-1-speed">-</span> MHz</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="core-2" class="core">
|
||||
<table class="core-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan="2">
|
||||
<div class="core-name-container">
|
||||
<span class="digi-icon-color fas fa-microchip fa-2x"></span>
|
||||
<span>Core 2</span>
|
||||
</div>
|
||||
</td>
|
||||
<td><span id="core-2-usage">-</span> %</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span id="core-2-speed">-</span> MHz</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="core-3" class="core">
|
||||
<table class="core-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan="2">
|
||||
<div class="core-name-container">
|
||||
<span class="digi-icon-color fas fa-microchip fa-2x"></span>
|
||||
<span>Core 3</span>
|
||||
</div>
|
||||
</td>
|
||||
<td><span id="core-3-usage">-</span> %</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span id="core-3-speed">-</span> MHz</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="core-4" class="core">
|
||||
<table class="core-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan="2">
|
||||
<div class="core-name-container">
|
||||
<span class="digi-icon-color fas fa-microchip fa-2x"></span>
|
||||
<span>Core 4</span>
|
||||
</div>
|
||||
</td>
|
||||
<td><span id="core-4-usage">-</span> %</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span id="core-4-speed">-</span> MHz</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="memory_panel_area" class="panel-area panel-tooltip" onclick="toggleInfoPanelVisibility('memory')">
|
||||
<span class="panel-tooltip-text">RAM memory</span>
|
||||
<span id="memory_panel_icon" class="fas fa-memory panel-area-icon"></span>
|
||||
</div>
|
||||
<div id="memory_panel" class="device-card memory-panel shadow-sm">
|
||||
<span id="memory_panel_arrow" class="panel-arrow"></span>
|
||||
<div class="device-card-header">
|
||||
<span class="fas fa-memory fa-lg mr-2"></span>
|
||||
<span>RAM memory stats</span>
|
||||
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="setInfoPanelVisible('memory', false)"></div>
|
||||
</div>
|
||||
<div class="device-card-content">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">Total memory:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="memory_total" class="device-card-content-value">-</span> MB
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">Used memory:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="memory_used" class="device-card-content-value">-</span> MB
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">Free memory:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="memory_free" class="device-card-content-value">-</span> MB
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="filesystem_panel" class="filesystem-panel">
|
||||
<div class="filesystem-background"></div>
|
||||
<div id="filesystem_container" class="filesystem-container">
|
||||
<div id="filesystem_header" class="device-card-header">
|
||||
<span class="fas fa-folder-open fa-lg mr-2"></span>
|
||||
<span>Device file system</span>
|
||||
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="closeFileSystem()"></div>
|
||||
</div>
|
||||
<div id="filesystem_hover_background" class="filesystem-hover-background"></div>
|
||||
<div id="filesystem_dir_name_panel" class="filesystem-dir-name-panel">
|
||||
<div class="filesystem-dir-name-background"></div>
|
||||
<div class="filesystem-dir-name-container">
|
||||
<div class="device-card-header">
|
||||
<span class="fas fa-folder-plus fa-lg mr-2"></span>
|
||||
<span>Create new directory</span>
|
||||
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="closeDirectoryNamePanel()"></div>
|
||||
</div>
|
||||
<div class="filesystem-dir-name-label">Enter the new directory name</div>
|
||||
<input id="filesystem_directory_name" class="filesystem-dir-name-input" type="text"/>
|
||||
<div id="filesystem_directory_name_error" class="filesystem-dir-name-error"></div>
|
||||
<div id="filesystem_directory_name_button" class="device-card-button filesystem-dir-name-button filesystem-dir-name-button-disabled" onclick="onCreateDirectory()">Create directory</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="filesystem_toolbar" class="filesystem-toolbar">
|
||||
<div class="filesystem-current-directory-container">
|
||||
<div class="filesystem-current-directory-label">Current dir:</div>
|
||||
<div id="current_directory" class="filesystem-current-directory"></div>
|
||||
</div>
|
||||
<div id="filesystem_toolbar_buttons_container" class="filesystem-toolbar-buttons-container">
|
||||
<div id="filesystem_create_directory_button" class="filesystem-button fas fa-folder-plus fa-2x" onclick="openDirectoryNamePanel()" title="Create directory"></div>
|
||||
<div id="filesystem_upload_file_button" class="filesystem-button fas fa-upload fa-2x" onclick="openFileBrowser()" title="Upload file"></div>
|
||||
<div id="filesystem_download_file_button" class="filesystem-button fas fa-file-download fa-2x" onclick="downloadSelectedFile()" title="Download file"></div>
|
||||
<div id="filesystem_remove_file_button" class="filesystem-button fas fa-trash fa-2x" onclick="askRemoveFile()" title="Remove file"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="filesystem_items_header" class="filesystem-items-header">
|
||||
<div class="filesystem-entry-icon"></div>
|
||||
<div class="filesystem-entry-name">Name</div>
|
||||
<div class="filesystem-entry-size">Size</div>
|
||||
<div class="filesystem-entry-last-modified">Last modified</div>
|
||||
</div>
|
||||
<div id="filesystem_items_container" class="filesystem-items-container"></div>
|
||||
<div id="filesystem_loading" class="popup shadow" style="top: 33%">
|
||||
<img class="popup-item" src="./static/images/loading.gif" alt="Loading..." />
|
||||
<div class="popup-text">Loading...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="wifi_bt_panel_area" class="panel-area panel-tooltip" onclick="toggleInfoPanelVisibility('wifi-bt')">
|
||||
<span class="panel-tooltip-text">WiFi/BT stats</span>
|
||||
<span id="wifi_bt_panel_icon" class="fas fa-wifi panel-area-icon"></span>
|
||||
</div>
|
||||
<div id="wifi_bt_panel" class="device-card wifi-panel shadow-sm">
|
||||
<span id="wifi_bt_panel_arrow" class="panel-arrow"></span>
|
||||
<div class="device-card-header">
|
||||
<span class="fas fa-wifi fa-lg mr-2"></span>
|
||||
<span>Wi-Fi/BT stats</span>
|
||||
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="setInfoPanelVisible('wifi-bt', false)"></div>
|
||||
</div>
|
||||
<div class="device-card-content">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">Status:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="wifi_state" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">MAC address:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="wifi_mac" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">IP address:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="wifi_ip" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">Sent data:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="wifi_sent_data" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">Received data:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="wifi_received_data" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="device-card-header">
|
||||
<span class="fab fa-bluetooth-b fa-lg mr-2"></span>
|
||||
<span>Bluetooth</span>
|
||||
</div>
|
||||
<div class="device-card-content">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">Status:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="bluetooth_state" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">MAC address:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="bluetooth_mac" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">Sent data:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="bluetooth_sent_data" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">Received data:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="bluetooth_received_data" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="ethernet_panel_area" class="panel-area panel-tooltip" onclick="toggleInfoPanelVisibility('ethernet')">
|
||||
<span class="panel-tooltip-text">Ethernet stats</span>
|
||||
<span id="ethernet_panel_icon" class="fas fa-ethernet panel-area-icon"></span>
|
||||
</div>
|
||||
<div id="ethernet_panel" class="device-card ethernet-panel shadow-sm">
|
||||
<span id="ethernet_panel_arrow" class="panel-arrow"></span>
|
||||
<div class="device-card-header">
|
||||
<span class="fas fa-ethernet fa-lg mr-2"></span>
|
||||
<span>Ethernet stats</span>
|
||||
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="setInfoPanelVisible('ethernet', false)"></div>
|
||||
</div>
|
||||
<div class="device-card-content">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">Status:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="ethernet_state" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">MAC address:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="ethernet_mac" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">IP address:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="ethernet_ip" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">Sent data:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="ethernet_sent_data" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">Received data:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="ethernet_received_data" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="video_panel_area" class="panel-area panel-tooltip" onclick="toggleInfoPanelVisibility('video')">
|
||||
<span class="panel-tooltip-text">Video info</span>
|
||||
<span id="video_panel_icon" class="fas fa-desktop panel-area-icon"></span>
|
||||
</div>
|
||||
<div id="video_panel" class="device-card video-panel shadow-sm">
|
||||
<span id="video_panel_arrow" class="panel-arrow"></span>
|
||||
<div class="device-card-header">
|
||||
<span class="fas fa-desktop fa-lg mr-2"></span>
|
||||
<span>Video info</span>
|
||||
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="setInfoPanelVisible('video', false)"></div>
|
||||
</div>
|
||||
<div class="device-card-content">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">Resolution:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="video_resolution" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="video_brightness_container">
|
||||
<span class="device-card-content-text">Brightness:</span>
|
||||
<span class="device-card-content-value"> 0%</span>
|
||||
<input id="video_brightness"/>
|
||||
<span class="device-card-content-value"> 100%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="audio_panel_area" class="panel-area panel-tooltip" onclick="toggleInfoPanelVisibility('audio')">
|
||||
<span class="panel-tooltip-text">Audio control</span>
|
||||
<span id="audio_panel_icon" class="fas fa-volume-up panel-area-icon"></span>
|
||||
</div>
|
||||
<div id="audio_panel" class="device-card audio-panel shadow-sm">
|
||||
<span id="audio_panel_arrow" class="panel-arrow"></span>
|
||||
<div class="device-card-header">
|
||||
<span class="fas fa-volume-up fa-lg mr-2"></span>
|
||||
<span>Audio control</span>
|
||||
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="setInfoPanelVisible('audio', false)"></div>
|
||||
</div>
|
||||
<div class="device-card-content">
|
||||
<div>
|
||||
<span class="device-card-content-text">Volume:</span>
|
||||
<span class="device-card-content-value"> 0%</span>
|
||||
<input id="audio_volume"/>
|
||||
<span class="device-card-content-value"> 100%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="led_panel_area" class="led-panel-area-off"></div>
|
||||
<div id="led_panel" class="led-panel shadow-sm panel-tooltip" onclick="toggleUserLED()">
|
||||
<span class="panel-tooltip-text">Toggle LED</span>
|
||||
<span id="led_panel_arrow" class="panel-arrow"></span>
|
||||
<img id ="led_image" class="led-image" src="./static/images/led_bubble.png"/>
|
||||
</div>
|
||||
<div id="flash_memory_panel_area" class="panel-area panel-tooltip" onclick="toggleInfoPanelVisibility('flash_memory')">
|
||||
<span class="panel-tooltip-text">Flash memory</span>
|
||||
<span id="flash_memory_panel_icon" class="fas fa-database panel-area-icon"></span>
|
||||
</div>
|
||||
<div id="flash_memory_panel" class="device-card flash-memory-panel shadow-sm">
|
||||
<span id="flash_memory_panel_arrow" class="panel-arrow"></span>
|
||||
<div class="device-card-header">
|
||||
<span class="fas fa-database fa-lg mr-2"></span>
|
||||
<span>Flash memory stats</span>
|
||||
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="setInfoPanelVisible('flash_memory', false)"></div>
|
||||
</div>
|
||||
<div class="device-card-content">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="device-card-content-text">Total flash memory:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="flash_size" class="device-card-content-value">-</span> GB
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="device-card-button filesystem-explore-button" onclick="openFileSystem()">Explore file system...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Initialize the device.
|
||||
initDevice();
|
||||
// Initialize sliders.
|
||||
initSliders();
|
||||
// Register resize event.
|
||||
window.onresize = adjustImageSize;
|
||||
// Change the color of the device toolbar icons when hovering.
|
||||
$("#device-button-hide-info").on({
|
||||
"mouseover" : function() {
|
||||
$("#device-button-hide-info-img").attr("src", "./static/images/hide_info_green.png");
|
||||
},
|
||||
"mouseout" : function() {
|
||||
$("#device-button-hide-info-img").attr("src", "./static/images/hide_info.png");
|
||||
}
|
||||
});
|
||||
$("#device-button-show-info").on({
|
||||
"mouseover" : function() {
|
||||
$("#device-button-show-info-img").attr("src", "./static/images/show_info_green.png");
|
||||
},
|
||||
"mouseout" : function() {
|
||||
$("#device-button-show-info-img").attr("src", "./static/images/show_info.png");
|
||||
}
|
||||
});
|
||||
// Register file upload change event.
|
||||
$("#file_to_upload").on("change", function(event) {
|
||||
uploadFile(event.target.files[0]);
|
||||
});
|
||||
// Register directory name input changed.
|
||||
$("#filesystem_directory_name").on("input", function(event) {
|
||||
validateDirectoryName(event.target.value);
|
||||
});
|
||||
// Change image of the LED panel when hovering.
|
||||
$("#led_panel").on({
|
||||
"mouseover" : function() {
|
||||
$("#led_image").attr("src", "./static/images/led_bubble_hover.png");
|
||||
},
|
||||
"mouseout" : function() {
|
||||
$("#led_image").attr("src", "./static/images/led_bubble.png");
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$("#banner-link").on({
|
||||
"mouseover" : function() {
|
||||
$("#banner-logo").attr("src", "./static/images/Digi_logo_banner_gray.png");
|
||||
},
|
||||
"mouseout" : function() {
|
||||
$("#banner-logo").attr("src", "./static/images/Digi_logo_banner.png");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Enable the tooltip library.
|
||||
$(function() {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Local JS files and functions -->
|
||||
<script type="text/javascript" src="./static/js/sidebar.js"></script>
|
||||
<script type="text/javascript" src="./static/js/ccimx8mm-dvk.js"></script>
|
||||
<script type="text/javascript" src="./static/js/ccimx8m-nano.js"></script>
|
||||
<script type="text/javascript" src="./static/js/ccimx8x-sbc-pro.js"></script>
|
||||
<script type="text/javascript" src="./static/js/dashboard.js"></script>
|
||||
<script type="text/javascript" src="./static/js/multimedia.js"></script>
|
||||
<script type="text/javascript" src="./static/js/management.js"></script>
|
||||
<script type="text/javascript" src="./static/js/file-system.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Don't show the loading spinner at the beginning. Initial page
|
||||
// load is full, so not relying on AJAX.
|
||||
$("#loading").hide();
|
||||
|
||||
// Set up PJAX.
|
||||
if ($.support.pjax) {
|
||||
$.pjax.defaults.timeout = 20000;
|
||||
$.pjax.defaults.fragment = "#pjax-container";
|
||||
$(document).pjax("a[data-pjax]", "#pjax-container");
|
||||
|
||||
$(document).on("pjax:beforeSend", function() {
|
||||
// Do not load new content if there are unsaved changes.
|
||||
if ($("#save-schedule").length && !$("#save-schedule").attr("disabled") && !confirm("There are unsaved changes. Do you want to exit?"))
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).on("pjax:send", function(e) {
|
||||
setSelectedSection(e.currentTarget.activeElement);
|
||||
$("#pjax-container").hide();
|
||||
$("#loading").show();
|
||||
});
|
||||
|
||||
$(document).on("pjax:complete", function() {
|
||||
$("#loading").hide();
|
||||
$("#pjax-container").show();
|
||||
});
|
||||
}
|
||||
|
||||
// Append the URL parameters to the section links.
|
||||
var params = new URLSearchParams(window.location.search).toString();
|
||||
if (params) {
|
||||
$("#sections li").each(function(i, n) {
|
||||
n.children[0].href += "?" + params;
|
||||
});
|
||||
}
|
||||
|
||||
// Set the selected section.
|
||||
setSelectedSection();
|
||||
});
|
||||
|
||||
// Callback executed when the page loads.
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
// Start the timer that updates device status.
|
||||
var statsTimer = setInterval(refreshDevice, 5000);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -0,0 +1,342 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
Digi Demo - Management
|
||||
</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="./static/css/stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||
<link href="./static/css/cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/css/bootstrap4-toggle.min.css" rel="stylesheet">
|
||||
<link href="./static/css/cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.3/css/bootstrap-slider.min.css" rel="stylesheet">
|
||||
<link href="./static/css/fontawesome5.15.4/all.min.css" rel="stylesheet">
|
||||
|
||||
<link rel="stylesheet" href="./static/css/general.css">
|
||||
<link rel="stylesheet" href="./static/css/toastr.css">
|
||||
|
||||
<!-- JS, Popper.js, and jQuery -->
|
||||
<script src="./static/js/code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
|
||||
<script src="./static/js/cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
|
||||
<script src="./static/js/stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
|
||||
<script src="./static/js/cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js"></script>
|
||||
<script src="./static/js/cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.3/bootstrap-slider.min.js"></script>
|
||||
<script type="text/javascript" src="./static/js/common.js"></script>
|
||||
<script type="text/javascript" src="./static/js/devices.js"></script>
|
||||
<script type="text/javascript" src="./static/js/jquery.pjax.js"></script>
|
||||
<script type="text/javascript" src="./static/js/jquery.matchHeight-min.js"></script>
|
||||
<script type="text/javascript" src="./static/js/toastr.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="topBar" class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
|
||||
<div class="nav-container">
|
||||
<a id="banner-link" class="navbar-brand align-middle" href="/">
|
||||
<div class="d-flex align-items-baseline">
|
||||
<img id="banner-logo" class="banner-icon" src="./static/images/Digi_logo_banner.png">
|
||||
<p id="banner-text">ConnectCore Demo</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="nav-right-container">
|
||||
|
||||
<div>
|
||||
<img src="./static/images/board.png" class="device-title-img" title="Device">
|
||||
</div>
|
||||
<div id="device-name">DEY DEVICE</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="bg-light" id="body-row">
|
||||
|
||||
<!-- Sidebar https://www.codeply.com/go/3e0RAjccRO/bootstrap-4-collapsing-sidebar-menu# -->
|
||||
<div id="sidebar-container" class="sidebar-expanded d-none d-md-block">
|
||||
<!-- d-* hides the Sidebar in smaller devices. Its items can be kept on the Navbar 'Menu' -->
|
||||
<div id="sidebar-contents">
|
||||
<!-- Bootstrap List Group -->
|
||||
|
||||
<ul id="sections" data-pjax class="list-group">
|
||||
<li>
|
||||
<a data-pjax href="index.html" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||
<span class="digi-menu-icon fas fa-tachometer-alt fa-fw fa-lg mr-3"></span>
|
||||
<span class="menu-collapsed">Dashboard</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a data-pjax href="multimedia.html" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||
<span class="digi-menu-icon fas fa-film fa-fw fa-lg mr-3"></span>
|
||||
<span class="menu-collapsed">Multimedia</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a data-pjax href="management.html" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||
<span class="digi-menu-icon fas fa-cog fa-fw fa-lg mr-3"></span>
|
||||
<span class="menu-collapsed">Management</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul id="collapsator" class="list-group">
|
||||
<a href="#top" data-toggle="sidebar-collapse" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||
<span id="collapse-icon" class="digi-menu-icon fas fa-fw fa-lg mr-3"></span>
|
||||
<span id="collapse-text" class="menu-collapsed">Collapse</span>
|
||||
</div>
|
||||
</a>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div id="loading">
|
||||
<img id="loading-image" src="./static/images/loading.gif" alt="Loading..." />
|
||||
</div>
|
||||
<div id="pjax-container">
|
||||
|
||||
<!-- <input type="file" id="firmware_file" style="display:none" onchange="firmwareFileChanged()" accept=".swu,.json,.txt"/>-->
|
||||
<input type="file" id="firmware_file" style="display:none" onchange="firmwareFileChanged()" accept=".swu"/>
|
||||
<div class="row justify-content-lg-center">
|
||||
<div class="col-lg-12 col-xl-12">
|
||||
<div id="loading_popup" class="popup popup-loading shadow">
|
||||
<img class="popup-item" src="./static/images/loading.gif" alt="Loading..." />
|
||||
<div id="loading_popup_message" class="popup-text">Loading information...</div>
|
||||
</div>
|
||||
<div id="info_popup" class="popup popup-info shadow d-none">
|
||||
<div id="info_popup_title" class="popup-title">Error</div>
|
||||
<div id="info_popup_message" class="popup-text">-</div>
|
||||
</div>
|
||||
<div id="confirm_dialog" class="confirm-dialog d-none">
|
||||
<div class="device-card-header">
|
||||
<span class="fas fa-question-circle fa-lg mr-2"></span>
|
||||
<span id="confirm_dialog_title"></span>
|
||||
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="showPopup(ID_LOADING_WRAPPER, ID_CONFIRM_DIALOG, false)"></div>
|
||||
</div>
|
||||
<div id="confirm_dialog_message" class="confirm-dialog-message"></div>
|
||||
<div class="confirm-dialog-buttons-container">
|
||||
<div id="confirm_dialog_no_button" class="device-card-button confirm-dialog-button">No</div>
|
||||
<div id="confirm_dialog_yes_button" class="device-card-button confirm-dialog-button">Yes</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="rebooted_dialog" class="popup popup-info shadow d-none">
|
||||
<div class="popup-title"><p><i class="fa fa-check success-message fa-lg"></i> Device rebooted</p></div>
|
||||
<div class="popup-text">Reload the page to continue.</div>
|
||||
<div class="confirm-dialog-buttons-container" style="padding-top: 30px;">
|
||||
<div id="reload_button" class="device-card-button confirm-dialog-button" onclick="document.location.replace('index.html')">Reload</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="loading_wrapper" class="loading-wrapper element-grayed">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Reboot device</h5>
|
||||
<div>Click <b>REBOOT</b> to restart your device.</div>
|
||||
<div id="reboot_button" class="device-card-button reboot-button" onclick="askReboot()">REBOOT</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Firmware update</h5>
|
||||
<table style="margin: 15px;">
|
||||
<tr>
|
||||
<td style="width: 180px; vertical-align: top;">
|
||||
<span class="device-card-content-text">Current DEY version:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="dey_version" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;">
|
||||
<span class="device-card-content-text">Current kernel version:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="kernel_version" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;">
|
||||
<span class="device-card-content-text">Current U-Boot version:</span>
|
||||
</td>
|
||||
<td>
|
||||
<span id="uboot_version" class="device-card-content-value">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="firmware-tabs">
|
||||
<div id="firmware_tab_upload_header" class="firmware-tab-header firmware-tab-header-active" onclick="showFirmwareTab(ID_FIRMWARE_TAB_UPLOAD)">
|
||||
<span class="fas fa-upload fa-lg"></span>
|
||||
<span class="firmware-tab-text">Upload file</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="firmware-tab-container">
|
||||
<div id="firmware_tab_upload" class="firmware-tab firmware-tab-upload">
|
||||
<div>Upload and install a firmware file from your computer.</div>
|
||||
<div class="firmware-file-container">
|
||||
<div id="select_firmware_button" class="device-card-button browse-firmware-button" onclick="openFirmwareBrowser()">Choose file...</div>
|
||||
<div id="firmware_file_label" class="firmware-file-label">No file chosen</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="update_firmware_progress" class="update-firmware-progress">
|
||||
<div id="update_firmware_progress_title" class="update-firmware-progress-title">Firmware update in progress...</div>
|
||||
<div class="progress update-firmware-progress-bar">
|
||||
<div id="update_firmware_progress_bar" class="progress-bar progress-bar-striped update-firmware-progress-bar update-firmware-progress-bar-info update-firmware-progress-bar-hover" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width:40%">40%</div>
|
||||
</div>
|
||||
<span id="update_firmware_progress_message" class="update-firmware-progress-status">Waiting for firmware update...</span>
|
||||
</div>
|
||||
<div>
|
||||
<div id="update_firmware_button" class="device-card-button update-firmware-button management-button-disabled" onclick="askUpdateFirmware()">Update Firmware</div>
|
||||
</div>
|
||||
</div> <!-- card body -->
|
||||
</div> <!-- card shadow -->
|
||||
<div id="filesystem_panel" class="filesystem-panel">
|
||||
<div class="filesystem-background"></div>
|
||||
<div id="filesystem_container" class="filesystem-container">
|
||||
<div id="filesystem_header" class="device-card-header">
|
||||
<span class="fas fa-folder-open fa-lg mr-2"></span>
|
||||
<span>Device's file system</span>
|
||||
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="closeFileSystem()"></div>
|
||||
</div>
|
||||
<div id="filesystem_hover_background" class="filesystem-hover-background"></div>
|
||||
<div id="filesystem_dir_name_panel" class="filesystem-dir-name-panel">
|
||||
<div class="filesystem-dir-name-background"></div>
|
||||
<div class="filesystem-dir-name-container">
|
||||
<div class="device-card-header">
|
||||
<span class="fas fa-folder-plus fa-lg mr-2"></span>
|
||||
<span>Create new directory</span>
|
||||
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="closeDirectoryNamePanel()"></div>
|
||||
</div>
|
||||
<div class="filesystem-dir-name-label">Enter the new directory name</div>
|
||||
<input id="filesystem_directory_name" class="filesystem-dir-name-input" type="text"/>
|
||||
<div id="filesystem_directory_name_error" class="filesystem-dir-name-error"></div>
|
||||
<div id="filesystem_directory_name_button" class="device-card-button filesystem-dir-name-button filesystem-dir-name-button-disabled" onclick="onCreateDirectory()">Create directory</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="filesystem_toolbar" class="filesystem-toolbar">
|
||||
<div class="filesystem-current-directory-container">
|
||||
<div class="filesystem-current-directory-label">Current dir:</div>
|
||||
<div id="current_directory" class="filesystem-current-directory"></div>
|
||||
</div>
|
||||
<div id="filesystem_toolbar_buttons_container" class="filesystem-toolbar-buttons-container">
|
||||
<div id="filesystem_select_file_button" class="filesystem-button fas fa-bolt fa-2x" onclick="selectFirmwareFile()" title="Select firmware file"></div>
|
||||
<div id="filesystem_create_directory_button" class="filesystem-button fas fa-folder-plus fa-2x" onclick="openDirectoryNamePanel()" title="Create directory"></div>
|
||||
<div id="filesystem_upload_file_button" class="filesystem-button fas fa-upload fa-2x" onclick="openFileBrowser()" title="Upload file"></div>
|
||||
<div id="filesystem_download_file_button" class="filesystem-button fas fa-file-download fa-2x" onclick="downloadSelectedFile()" title="Download file"></div>
|
||||
<div id="filesystem_remove_file_button" class="filesystem-button fas fa-trash fa-2x" onclick="askRemoveFile()" title="Remove file"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="filesystem_items_header" class="filesystem-items-header">
|
||||
<div class="filesystem-entry-icon"></div>
|
||||
<div class="filesystem-entry-name">Name</div>
|
||||
<div class="filesystem-entry-size">Size</div>
|
||||
<div class="filesystem-entry-last-modified">Last modified</div>
|
||||
</div>
|
||||
<div id="filesystem_items_container" class="filesystem-items-container"></div>
|
||||
<div id="filesystem_loading" class="popup shadow" style="top: 33%">
|
||||
<img class="popup-item" src="./static/images/loading.gif" alt="Loading..." />
|
||||
<div class="popup-text">Loading...</div>
|
||||
</div>
|
||||
</div> <!-- filesystem_container -->
|
||||
</div> <!-- filesystem_panel -->
|
||||
</div> <!-- loading wrapper -->
|
||||
</div> <!-- col -->
|
||||
</div> <!-- row justify -->
|
||||
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Reset variables.
|
||||
readingManagementInfo = false;
|
||||
managementInfoRead = false;
|
||||
deviceRebooting = false;
|
||||
updatingFirmware = false;
|
||||
firmwareUpdateTimer = null;
|
||||
selectedFilesetEntry = null;
|
||||
filesLoaded = false;
|
||||
// Initialize page.
|
||||
initializeManagementPage();
|
||||
});
|
||||
</script>
|
||||
|
||||
</div> <!-- pjax-container -->
|
||||
|
||||
</div> <!-- container fluid -->
|
||||
</div> <!--bg light -->
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$("#banner-link").on({
|
||||
"mouseover" : function() {
|
||||
$("#banner-logo").attr("src", "./static/images/Digi_logo_banner_gray.png");
|
||||
},
|
||||
"mouseout" : function() {
|
||||
$("#banner-logo").attr("src", "./static/images/Digi_logo_banner.png");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Enable the tooltip library.
|
||||
$(function() {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Local JS files and functions -->
|
||||
<script type="text/javascript" src="./static/js/sidebar.js"></script>
|
||||
<script type="text/javascript" src="./static/js/ccimx8mm-dvk.js"></script>
|
||||
<script type="text/javascript" src="./static/js/ccimx8m-nano.js"></script>
|
||||
<script type="text/javascript" src="./static/js/ccimx8x-sbc-pro.js"></script>
|
||||
<script type="text/javascript" src="./static/js/dashboard.js"></script>
|
||||
<script type="text/javascript" src="./static/js/multimedia.js"></script>
|
||||
<script type="text/javascript" src="./static/js/management.js"></script>
|
||||
<script type="text/javascript" src="./static/js/file-system.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Don't show the loading spinner at the beginning. Initial page
|
||||
// load is full, so not relying on AJAX.
|
||||
$("#loading").hide();
|
||||
|
||||
// Set up PJAX.
|
||||
if ($.support.pjax) {
|
||||
$.pjax.defaults.timeout = 20000;
|
||||
$.pjax.defaults.fragment = "#pjax-container";
|
||||
$(document).pjax("a[data-pjax]", "#pjax-container");
|
||||
|
||||
$(document).on("pjax:beforeSend", function() {
|
||||
// Do not load new content if there are unsaved changes.
|
||||
if ($("#save-schedule").length && !$("#save-schedule").attr("disabled") && !confirm("There are unsaved changes. Do you want to exit?"))
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).on("pjax:send", function(e) {
|
||||
setSelectedSection(e.currentTarget.activeElement);
|
||||
$("#pjax-container").hide();
|
||||
$("#loading").show();
|
||||
});
|
||||
|
||||
$(document).on("pjax:complete", function() {
|
||||
$("#loading").hide();
|
||||
$("#pjax-container").show();
|
||||
});
|
||||
}
|
||||
|
||||
// Append the URL parameters to the section links.
|
||||
var params = new URLSearchParams(window.location.search).toString();
|
||||
if (params) {
|
||||
$("#sections li").each(function(i, n) {
|
||||
n.children[0].href += "?" + params;
|
||||
});
|
||||
}
|
||||
|
||||
// Set the selected section.
|
||||
setSelectedSection();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -0,0 +1,283 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
Digi Demo - Multimedia
|
||||
</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="./static/css/stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||
<link href="./static/css/cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/css/bootstrap4-toggle.min.css" rel="stylesheet">
|
||||
<link href="./static/css/cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.3/css/bootstrap-slider.min.css" rel="stylesheet">
|
||||
<link href="./static/css/fontawesome5.15.4/all.min.css" rel="stylesheet">
|
||||
|
||||
<link rel="stylesheet" href="./static/css/general.css">
|
||||
<link rel="stylesheet" href="./static/css/toastr.css">
|
||||
|
||||
<!-- JS, Popper.js, and jQuery -->
|
||||
<script src="./static/js/code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
|
||||
<script src="./static/js/cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
|
||||
<script src="./static/js/stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
|
||||
<script src="./static/js/cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js"></script>
|
||||
<script src="./static/js/cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.3/bootstrap-slider.min.js"></script>
|
||||
<script type="text/javascript" src="./static/js/common.js"></script>
|
||||
<script type="text/javascript" src="./static/js/devices.js"></script>
|
||||
<script type="text/javascript" src="./static/js/jquery.pjax.js"></script>
|
||||
<script type="text/javascript" src="./static/js/jquery.matchHeight-min.js"></script>
|
||||
<script type="text/javascript" src="./static/js/toastr.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav id="topBar" class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
|
||||
<div class="nav-container">
|
||||
<a id="banner-link" class="navbar-brand align-middle" href="/">
|
||||
<div class="d-flex align-items-baseline">
|
||||
<img id="banner-logo" class="banner-icon" src="./static/images/Digi_logo_banner.png">
|
||||
<p id="banner-text">ConnectCore Demo</p>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div class="nav-right-container">
|
||||
|
||||
<div>
|
||||
<img src="./static/images/board.png" class="device-title-img" title="Device">
|
||||
</div>
|
||||
<div id="device-name">DEY DEVICE</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="bg-light" id="body-row">
|
||||
|
||||
<!-- Sidebar https://www.codeply.com/go/3e0RAjccRO/bootstrap-4-collapsing-sidebar-menu# -->
|
||||
<div id="sidebar-container" class="sidebar-expanded d-none d-md-block">
|
||||
<!-- d-* hides the Sidebar in smaller devices. Its items can be kept on the Navbar 'Menu' -->
|
||||
<div id="sidebar-contents">
|
||||
<!-- Bootstrap List Group -->
|
||||
|
||||
<ul id="sections" data-pjax class="list-group">
|
||||
<li>
|
||||
<a data-pjax href="index.html" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||
<span class="digi-menu-icon fas fa-tachometer-alt fa-fw fa-lg mr-3"></span>
|
||||
<span class="menu-collapsed">Dashboard</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a data-pjax href="multimedia.html" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||
<span class="digi-menu-icon fas fa-film fa-fw fa-lg mr-3"></span>
|
||||
<span class="menu-collapsed">Multimedia</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a data-pjax href="management.html" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||
<span class="digi-menu-icon fas fa-cog fa-fw fa-lg mr-3"></span>
|
||||
<span class="menu-collapsed">Management</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul id="collapsator" class="list-group">
|
||||
<a href="#top" data-toggle="sidebar-collapse" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||
<span id="collapse-icon" class="digi-menu-icon fas fa-fw fa-lg mr-3"></span>
|
||||
<span id="collapse-text" class="menu-collapsed">Collapse</span>
|
||||
</div>
|
||||
</a>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div id="loading">
|
||||
<img id="loading-image" src="./static/images/loading.gif" alt="Loading..." />
|
||||
</div>
|
||||
<div id="pjax-container">
|
||||
|
||||
<div class="row justify-content-lg-center">
|
||||
<div class="col-lg-12 col-xl-12">
|
||||
<div id="loading_popup" class="popup popup-loading shadow">
|
||||
<img class="popup-item" src="./static/images/loading.gif" alt="Loading..." />
|
||||
<div id="loading_popup_message" class="popup-text">Loading information...</div>
|
||||
</div>
|
||||
<div id="info_popup" class="popup popup-info shadow d-none">
|
||||
<div id="info_popup_title" class="popup-title">Error</div>
|
||||
<div id="info_popup_message" class="popup-text">-</div>
|
||||
</div>
|
||||
<div id="loading_wrapper" class="loading-wrapper element-grayed">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">WebGL examples</h5>
|
||||
<!-- Multimedia items section -->
|
||||
<div class="row">
|
||||
<div class="col-xl-2 multimedia-container">
|
||||
<div class="d-flex justify-content-center align-items-center multimedia-box">
|
||||
<div class="multimedia-item" onclick="location.href='multimedia_viewer.html?exampleURL=aquarium/aquarium.html'">
|
||||
<div class="multimedia-title">Aquarium</div>
|
||||
<img src="./static/images/aquarium.jpg" alt="Aquarium">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-2 multimedia-container">
|
||||
<div class="d-flex justify-content-center align-items-center multimedia-box">
|
||||
<div class="multimedia-item" onclick="location.href='multimedia_viewer.html?exampleURL=blob/blob.html'">
|
||||
<div class="multimedia-title">Blob</div>
|
||||
<img src="./static/images/blob.jpg" alt="Blob">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-2 multimedia-container">
|
||||
<div class="d-flex justify-content-center align-items-center multimedia-box">
|
||||
<div class="multimedia-item" onclick="location.href='multimedia_viewer.html?exampleURL=electricflower/electricflower.html'">
|
||||
<div class="multimedia-title">Electricflower</div>
|
||||
<img src="./static/images/electricflower.jpg" alt="Electricflower">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-2 multimedia-container">
|
||||
<div class="d-flex justify-content-center align-items-center multimedia-box">
|
||||
<div class="multimedia-item" onclick="location.href='multimedia_viewer.html?exampleURL=multiple-views/multiple-views.html'">
|
||||
<div class="multimedia-title">Multiple Views</div>
|
||||
<img src="./static/images/multiple-views.jpg" alt="Multiple Views">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-2 multimedia-container">
|
||||
<div class="d-flex justify-content-center align-items-center multimedia-box">
|
||||
<div class="multimedia-item" onclick="location.href='multimedia_viewer.html?exampleURL=spacerocks/spacerocks.html'">
|
||||
<div class="multimedia-title">Spacerocks</div>
|
||||
<img src="./static/images/spacerocks.jpg" alt="Spacerocks">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-2 multimedia-container">
|
||||
<div class="d-flex justify-content-center align-items-center multimedia-box">
|
||||
<div class="multimedia-item" onclick="location.href='multimedia_viewer.html?exampleURL=toon-shading/toon-shading.html'">
|
||||
<div class="multimedia-title">Toon Shading</div>
|
||||
<img src="./static/images/toon-shading.jpg" alt="Toon Shading">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- Multimedia items -->
|
||||
<div style="padding-top: 20px;">
|
||||
All the WebGL examples have been obtained from <a href="#" onclick="location.href='multimedia_viewer.html?exampleURL=https://webglsamples.org/'">https://webglsamples.org/</a>
|
||||
</div>
|
||||
</div> <!-- card body -->
|
||||
</div> <!-- card shadow -->
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Videos</h5>
|
||||
<!-- Videos -->
|
||||
<div class="row">
|
||||
<div class="col-xl-2 multimedia-container">
|
||||
<div class="d-flex justify-content-center align-items-center multimedia-box">
|
||||
<div class="multimedia-item" onclick="location.href='multimedia_viewer.html?exampleURL=videos/big_buck_bunny.mov'">
|
||||
<div class="multimedia-title">Big Buck Bunny (MOV)</div>
|
||||
<img src="./static/images/big_buck_bunny.jpg" alt="Big Buck Bunny (MOV)">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-2 multimedia-container">
|
||||
<div class="d-flex justify-content-center align-items-center multimedia-box">
|
||||
<div class="multimedia-item" onclick="location.href='multimedia_viewer.html?exampleURL=videos/big_buck_bunny.webm'">
|
||||
<div class="multimedia-title">Big Buck Bunny (WEBM)</div>
|
||||
<img src="./static/images/big_buck_bunny.jpg" alt="Big Buck Bunny (WEBM)">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!--Videos -->
|
||||
</div> <!-- card body -->
|
||||
</div> <!-- card shadow -->
|
||||
</div> <!-- loading wrapper -->
|
||||
</div> <!-- col -->
|
||||
</div> <!-- row justify -->
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Reset variables.
|
||||
readingMultimediaInfo = false;
|
||||
multimediaInfoRead = false;
|
||||
// Initialize page.
|
||||
initializeMultimediaPage();
|
||||
});
|
||||
</script>
|
||||
</div> <!-- pjax-container -->
|
||||
</div> <!-- container-fluid -->
|
||||
</div> <!-- bg-light -->
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$("#banner-link").on({
|
||||
"mouseover" : function() {
|
||||
$("#banner-logo").attr("src", "./static/images/Digi_logo_banner_gray.png");
|
||||
},
|
||||
"mouseout" : function() {
|
||||
$("#banner-logo").attr("src", "./static/images/Digi_logo_banner.png");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Enable the tooltip library.
|
||||
$(function() {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Local JS files and functions -->
|
||||
<script type="text/javascript" src="./static/js/sidebar.js"></script>
|
||||
<script type="text/javascript" src="./static/js/ccimx8mm-dvk.js"></script>
|
||||
<script type="text/javascript" src="./static/js/ccimx8m-nano.js"></script>
|
||||
<script type="text/javascript" src="./static/js/ccimx8x-sbc-pro.js"></script>
|
||||
<script type="text/javascript" src="./static/js/dashboard.js"></script>
|
||||
<script type="text/javascript" src="./static/js/multimedia.js"></script>
|
||||
<script type="text/javascript" src="./static/js/management.js"></script>
|
||||
<script type="text/javascript" src="./static/js/file-system.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Don't show the loading spinner at the beginning. Initial page
|
||||
// load is full, so not relying on AJAX.
|
||||
$("#loading").hide();
|
||||
|
||||
// Set up PJAX.
|
||||
if ($.support.pjax) {
|
||||
$.pjax.defaults.timeout = 20000;
|
||||
$.pjax.defaults.fragment = "#pjax-container";
|
||||
$(document).pjax("a[data-pjax]", "#pjax-container");
|
||||
|
||||
$(document).on("pjax:beforeSend", function() {
|
||||
// Do not load new content if there are unsaved changes.
|
||||
if ($("#save-schedule").length && !$("#save-schedule").attr("disabled") && !confirm("There are unsaved changes. Do you want to exit?"))
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).on("pjax:send", function(e) {
|
||||
setSelectedSection(e.currentTarget.activeElement);
|
||||
$("#pjax-container").hide();
|
||||
$("#loading").show();
|
||||
});
|
||||
|
||||
$(document).on("pjax:complete", function() {
|
||||
$("#loading").hide();
|
||||
$("#pjax-container").show();
|
||||
});
|
||||
}
|
||||
|
||||
// Append the URL parameters to the section links.
|
||||
var params = new URLSearchParams(window.location.search).toString();
|
||||
if (params) {
|
||||
$("#sections li").each(function(i, n) {
|
||||
n.children[0].href += "?" + params;
|
||||
});
|
||||
}
|
||||
|
||||
// Set the selected section.
|
||||
setSelectedSection();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Digi Demo - Multimedia viewer</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="./static/css/stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||
<link href="./static/css/cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/css/bootstrap4-toggle.min.css" rel="stylesheet">
|
||||
<link href="./static/css/cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.3/css/bootstrap-slider.min.css" rel="stylesheet">
|
||||
<link href="./static/css/fontawesome5.15.4/all.min.css" rel="stylesheet">
|
||||
|
||||
<link rel="stylesheet" href="./static/css/general.css">
|
||||
<link rel="stylesheet" href="./static/css/toastr.css">
|
||||
|
||||
<!-- JS, Popper.js, and jQuery -->
|
||||
<script src="./static/js/code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
|
||||
<script src="./static/js/cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
|
||||
<script src="./static/js/stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
|
||||
<script src="./static/js/cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js"></script>
|
||||
<script src="./static/js/cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.3/bootstrap-slider.min.js"></script>
|
||||
<script type="text/javascript" src="./static/js/common.js"></script>
|
||||
<script type="text/javascript" src="./static/js/devices.js"></script>
|
||||
<script type="text/javascript" src="./static/js/jquery.pjax.js"></script>
|
||||
<script type="text/javascript" src="./static/js/jquery.matchHeight-min.js"></script>
|
||||
<script type="text/javascript" src="./static/js/toastr.min.js"></script>
|
||||
</head>
|
||||
<body class="multimedia-viewer">
|
||||
<nav id="topBar" class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
|
||||
<div class="nav-container" style="padding-right: 0px;">
|
||||
<a id="banner-link" class="navbar-brand align-middle" href="/">
|
||||
<div class="d-flex align-items-baseline">
|
||||
<img id="banner-logo" class="banner-icon" src="./static/images/Digi_logo_banner.png">
|
||||
<p id="banner-text">ConnectCore Demo</p>
|
||||
</div>
|
||||
</a>
|
||||
<div class="nav-right-container">
|
||||
<div class="stat" style="min-width: 200px">
|
||||
<div class="status-icon">
|
||||
<img src="./static/images/cpu.png" height=32px/>
|
||||
</div>
|
||||
<div class="status-text">CPU:</div>
|
||||
<div id="stats-cpu-load" class="status-text">-</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="status-icon">
|
||||
<img src="./static/images/ram.png" height=32px/>
|
||||
</div>
|
||||
<div class="status-text">Memory:</div>
|
||||
<div id="stats-memory" class="status-text">-</div>
|
||||
</div>
|
||||
<a href="multimedia.html">
|
||||
<div id="back-button" class="device-card-button back-button">Back</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- Demo content container -->
|
||||
<iframe frameborder="0" class="multimedia-content" id="multimedia-content"></iframe>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$("#banner-link").on({
|
||||
"mouseover" : function() {
|
||||
$("#banner-logo").attr("src", "./static/images/Digi_logo_banner_gray.png");
|
||||
},
|
||||
"mouseout" : function() {
|
||||
$("#banner-logo").attr("src", "./static/images/Digi_logo_banner.png");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Enable the tooltip library.
|
||||
$(function() {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
// Get the example ID from the URL parameters.
|
||||
let urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams == null)
|
||||
return;
|
||||
let exampleURL = urlParams.get('exampleURL');
|
||||
if (exampleURL !== null)
|
||||
// Load the example.
|
||||
loadExample(exampleURL);
|
||||
// Start the timer that updates the system stats.
|
||||
getSystemStats();
|
||||
var statsTimer = setInterval(getSystemStats, 5000);
|
||||
});
|
||||
|
||||
function loadExample(exampleURL) {
|
||||
if (exampleURL.startsWith("http"))
|
||||
document.getElementById('multimedia-content').src = exampleURL;
|
||||
else
|
||||
document.getElementById('multimedia-content').src = "./" + exampleURL;
|
||||
}
|
||||
|
||||
function getSystemStats() {
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
var url = "http://" + getServerAddress() + "/ajax/get_device_status";
|
||||
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
var jsonPayload = JSON.parse(this.responseText);
|
||||
updateStats(jsonPayload);
|
||||
}
|
||||
};
|
||||
xmlhttp.open("POST", url, true);
|
||||
xmlhttp.send();
|
||||
}
|
||||
|
||||
function updateStats(stats) {
|
||||
updateValueWithEffect("stats-cpu-load", roundToTwoDecimals(stats[STREAM_CPU_LOAD]) + " %");
|
||||
updateValueWithEffect("stats-memory", roundToTwoDecimals(kiloBytesToMegaBytes(stats[STREAM_MEMORY_FREE])) + " MB");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
/*\
|
||||
|*| ========================================================================
|
||||
|*| Bootstrap Toggle: bootstrap4-toggle.css v3.6.1
|
||||
|*| https://gitbrent.github.io/bootstrap4-toggle/
|
||||
|*| ========================================================================
|
||||
|*| Copyright 2018-2019 Brent Ely
|
||||
|*| Licensed under MIT
|
||||
|*| ========================================================================
|
||||
\*/
|
||||
.btn-group-xs>.btn,.btn-xs{padding:.35rem .4rem .25rem .4rem;font-size:.875rem;line-height:.5;border-radius:.2rem}.checkbox label .toggle,.checkbox-inline .toggle{margin-left:-1.25rem;margin-right:.35rem}.toggle{position:relative;overflow:hidden}.toggle.btn.btn-light,.toggle.btn.btn-outline-light{border-color:rgba(0,0,0,.15)}.toggle input[type=checkbox]{display:none}.toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;-moz-user-select:none;-webkit-user-select:none}.toggle-group label,.toggle-group span{cursor:pointer}.toggle.off .toggle-group{left:-100%}.toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0}.toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0;box-shadow:none}.toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px;background-color:#fff}.toggle.btn-outline-primary .toggle-handle{background-color:var(--primary);border-color:var(--primary)}.toggle.btn-outline-secondary .toggle-handle{background-color:var(--secondary);border-color:var(--secondary)}.toggle.btn-outline-success .toggle-handle{background-color:var(--success);border-color:var(--success)}.toggle.btn-outline-danger .toggle-handle{background-color:var(--danger);border-color:var(--danger)}.toggle.btn-outline-warning .toggle-handle{background-color:var(--warning);border-color:var(--warning)}.toggle.btn-outline-info .toggle-handle{background-color:var(--info);border-color:var(--info)}.toggle.btn-outline-light .toggle-handle{background-color:var(--light);border-color:var(--light)}.toggle.btn-outline-dark .toggle-handle{background-color:var(--dark);border-color:var(--dark)}.toggle[class*=btn-outline]:hover .toggle-handle{background-color:var(--light);opacity:.5}.toggle.btn{min-width:3.7rem;min-height:2.15rem}.toggle-on.btn{padding-right:1.5rem}.toggle-off.btn{padding-left:1.5rem}.toggle.btn-lg{min-width:5rem;min-height:2.815rem}.toggle-on.btn-lg{padding-right:2rem}.toggle-off.btn-lg{padding-left:2rem}.toggle-handle.btn-lg{width:2.5rem}.toggle.btn-sm{min-width:3.125rem;min-height:1.938rem}.toggle-on.btn-sm{padding-right:1rem}.toggle-off.btn-sm{padding-left:1rem}.toggle.btn-xs{min-width:2.19rem;min-height:1.375rem}.toggle-on.btn-xs{padding-right:.8rem}.toggle-off.btn-xs{padding-left:.8rem}
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
.toast-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
.toast-message {
|
||||
-ms-word-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.toast-message a,
|
||||
.toast-message label {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.toast-message a:hover {
|
||||
color: #CCCCCC;
|
||||
text-decoration: none;
|
||||
}
|
||||
.toast-close-button {
|
||||
position: relative;
|
||||
right: -0.3em;
|
||||
top: -0.3em;
|
||||
float: right;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #FFFFFF;
|
||||
-webkit-text-shadow: 0 1px 0 #ffffff;
|
||||
text-shadow: 0 1px 0 #ffffff;
|
||||
opacity: 0.8;
|
||||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
|
||||
filter: alpha(opacity=80);
|
||||
line-height: 1;
|
||||
}
|
||||
.toast-close-button:hover,
|
||||
.toast-close-button:focus {
|
||||
color: #000000;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
opacity: 0.4;
|
||||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
|
||||
filter: alpha(opacity=40);
|
||||
}
|
||||
.rtl .toast-close-button {
|
||||
left: -0.3em;
|
||||
float: left;
|
||||
right: 0.3em;
|
||||
}
|
||||
/*Additional properties for button version
|
||||
iOS requires the button element instead of an anchor tag.
|
||||
If you want the anchor version, it requires `href="#"`.*/
|
||||
button.toast-close-button {
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
.toast-top-center {
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.toast-bottom-center {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.toast-top-full-width {
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.toast-bottom-full-width {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.toast-top-left {
|
||||
top: 12px;
|
||||
left: 12px;
|
||||
}
|
||||
.toast-top-right {
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
}
|
||||
.toast-bottom-right {
|
||||
right: 12px;
|
||||
bottom: 12px;
|
||||
}
|
||||
.toast-bottom-left {
|
||||
bottom: 12px;
|
||||
left: 12px;
|
||||
}
|
||||
#toast-container {
|
||||
position: fixed;
|
||||
z-index: 999999;
|
||||
pointer-events: none;
|
||||
/*overrides*/
|
||||
}
|
||||
#toast-container * {
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#toast-container > div {
|
||||
position: relative;
|
||||
pointer-events: auto;
|
||||
overflow: hidden;
|
||||
margin: 0 0 6px;
|
||||
padding: 15px 15px 15px 50px;
|
||||
width: 300px;
|
||||
-moz-border-radius: 3px 3px 3px 3px;
|
||||
-webkit-border-radius: 3px 3px 3px 3px;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
background-position: 15px center;
|
||||
background-repeat: no-repeat;
|
||||
-moz-box-shadow: 0 0 12px #999999;
|
||||
-webkit-box-shadow: 0 0 12px #999999;
|
||||
box-shadow: 0 0 12px #999999;
|
||||
color: #FFFFFF;
|
||||
opacity: 0.8;
|
||||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
|
||||
filter: alpha(opacity=80);
|
||||
}
|
||||
#toast-container > div.rtl {
|
||||
direction: rtl;
|
||||
padding: 15px 50px 15px 15px;
|
||||
background-position: right 15px center;
|
||||
}
|
||||
#toast-container > div:hover {
|
||||
-moz-box-shadow: 0 0 12px #000000;
|
||||
-webkit-box-shadow: 0 0 12px #000000;
|
||||
box-shadow: 0 0 12px #000000;
|
||||
opacity: 1;
|
||||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
|
||||
filter: alpha(opacity=100);
|
||||
cursor: pointer;
|
||||
}
|
||||
#toast-container > .toast-info {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important;
|
||||
}
|
||||
#toast-container > .toast-error {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important;
|
||||
}
|
||||
#toast-container > .toast-success {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important;
|
||||
}
|
||||
#toast-container > .toast-warning {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important;
|
||||
}
|
||||
#toast-container.toast-top-center > div,
|
||||
#toast-container.toast-bottom-center > div {
|
||||
width: 300px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
#toast-container.toast-top-full-width > div,
|
||||
#toast-container.toast-bottom-full-width > div {
|
||||
width: 96%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.toast {
|
||||
background-color: #030303;
|
||||
}
|
||||
.toast-success {
|
||||
background-color: #51A351;
|
||||
}
|
||||
.toast-error {
|
||||
background-color: #BD362F;
|
||||
}
|
||||
.toast-info {
|
||||
background-color: #2F96B4;
|
||||
}
|
||||
.toast-warning {
|
||||
background-color: #F89406;
|
||||
}
|
||||
.toast-progress {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
height: 4px;
|
||||
background-color: #000000;
|
||||
opacity: 0.4;
|
||||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
|
||||
filter: alpha(opacity=40);
|
||||
}
|
||||
/*Responsive Design*/
|
||||
@media all and (max-width: 240px) {
|
||||
#toast-container > div {
|
||||
padding: 8px 8px 8px 50px;
|
||||
width: 11em;
|
||||
}
|
||||
#toast-container > div.rtl {
|
||||
padding: 8px 50px 8px 8px;
|
||||
}
|
||||
#toast-container .toast-close-button {
|
||||
right: -0.2em;
|
||||
top: -0.2em;
|
||||
}
|
||||
#toast-container .rtl .toast-close-button {
|
||||
left: -0.2em;
|
||||
right: 0.2em;
|
||||
}
|
||||
}
|
||||
@media all and (min-width: 241px) and (max-width: 480px) {
|
||||
#toast-container > div {
|
||||
padding: 8px 8px 8px 50px;
|
||||
width: 18em;
|
||||
}
|
||||
#toast-container > div.rtl {
|
||||
padding: 8px 50px 8px 8px;
|
||||
}
|
||||
#toast-container .toast-close-button {
|
||||
right: -0.2em;
|
||||
top: -0.2em;
|
||||
}
|
||||
#toast-container .rtl .toast-close-button {
|
||||
left: -0.2em;
|
||||
right: 0.2em;
|
||||
}
|
||||
}
|
||||
@media all and (min-width: 481px) and (max-width: 768px) {
|
||||
#toast-container > div {
|
||||
padding: 15px 15px 15px 50px;
|
||||
width: 25em;
|
||||
}
|
||||
#toast-container > div.rtl {
|
||||
padding: 15px 50px 15px 15px;
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 730 KiB |
|
After Width: | Height: | Size: 898 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 337 B |
|
After Width: | Height: | Size: 881 KiB |
|
After Width: | Height: | Size: 881 KiB |
|
After Width: | Height: | Size: 866 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 677 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 534 B |
|
After Width: | Height: | Size: 646 B |
|
After Width: | Height: | Size: 994 B |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 1019 B |
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright 2022, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
class CCIMX8MNANO extends ConnectCoreDevice {
|
||||
|
||||
// Public constants.
|
||||
static DEVICE_TYPE = "ccimx8mn-dvk";
|
||||
static PLATFORM_NAME = "ConnectCore 8M-Nano DVK";
|
||||
|
||||
// Variables.
|
||||
BOARD_IMAGE = "ccimx8m-nano_board.png";
|
||||
BOARD_IMAGE_SCALE = 85;
|
||||
|
||||
CPU_COMPONENT_VISIBLE = true;
|
||||
CPU_COMPONENT_HAS_PANEL = true;
|
||||
CPU_COMPONENT_HAS_ARROW = true;
|
||||
CPU_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
CPU_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
CPU_COMPONENT_PANEL_HORIZONTAL_PERCENT = 28.5;
|
||||
CPU_COMPONENT_PANEL_VERTICAL_PERCENT = 57;
|
||||
CPU_COMPONENT_ARROW_PERCENT = 33.5;
|
||||
CPU_COMPONENT_AREA_TOP_PERCENT = 45.7;
|
||||
CPU_COMPONENT_AREA_LEFT_PERCENT = 32.4;
|
||||
CPU_COMPONENT_AREA_WIDTH_PERCENT = 5.7;
|
||||
CPU_COMPONENT_AREA_HEIGHT_PERCENT = 9;
|
||||
|
||||
MEMORY_COMPONENT_VISIBLE = true;
|
||||
MEMORY_COMPONENT_HAS_PANEL = true;
|
||||
MEMORY_COMPONENT_HAS_ARROW = true;
|
||||
MEMORY_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
MEMORY_COMPONENT_PANEL_ORIENTATION = VALUE_BOTTOM;
|
||||
MEMORY_COMPONENT_PANEL_HORIZONTAL_PERCENT = 22;
|
||||
MEMORY_COMPONENT_PANEL_VERTICAL_PERCENT = 65;
|
||||
MEMORY_COMPONENT_ARROW_PERCENT = 33.7;
|
||||
MEMORY_COMPONENT_AREA_TOP_PERCENT = 37;
|
||||
MEMORY_COMPONENT_AREA_LEFT_PERCENT = 32.4;
|
||||
MEMORY_COMPONENT_AREA_WIDTH_PERCENT = 6;
|
||||
MEMORY_COMPONENT_AREA_HEIGHT_PERCENT = 7;
|
||||
|
||||
WIFI_BT_COMPONENT_VISIBLE = true;
|
||||
WIFI_BT_COMPONENT_HAS_PANEL = true;
|
||||
WIFI_BT_COMPONENT_HAS_ARROW = true;
|
||||
WIFI_BT_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
WIFI_BT_COMPONENT_PANEL_ORIENTATION = VALUE_RIGHT;
|
||||
WIFI_BT_COMPONENT_PANEL_HORIZONTAL_PERCENT = 73;
|
||||
WIFI_BT_COMPONENT_PANEL_VERTICAL_PERCENT = 38;
|
||||
WIFI_BT_COMPONENT_ARROW_PERCENT = 46;
|
||||
WIFI_BT_COMPONENT_AREA_TOP_PERCENT = 46.5;
|
||||
WIFI_BT_COMPONENT_AREA_LEFT_PERCENT = 28.3;
|
||||
WIFI_BT_COMPONENT_AREA_WIDTH_PERCENT = 4;
|
||||
WIFI_BT_COMPONENT_AREA_HEIGHT_PERCENT = 6;
|
||||
|
||||
ETHERNET_COMPONENT_VISIBLE = true;
|
||||
ETHERNET_COMPONENT_HAS_PANEL = true;
|
||||
ETHERNET_COMPONENT_HAS_ARROW = true;
|
||||
ETHERNET_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
ETHERNET_COMPONENT_PANEL_ORIENTATION = VALUE_LEFT;
|
||||
ETHERNET_COMPONENT_PANEL_HORIZONTAL_PERCENT = 21;
|
||||
ETHERNET_COMPONENT_PANEL_VERTICAL_PERCENT = 70;
|
||||
ETHERNET_COMPONENT_ARROW_PERCENT = 78;
|
||||
ETHERNET_COMPONENT_AREA_TOP_PERCENT = 77;
|
||||
ETHERNET_COMPONENT_AREA_LEFT_PERCENT = 11;
|
||||
ETHERNET_COMPONENT_AREA_WIDTH_PERCENT = 8.5;
|
||||
ETHERNET_COMPONENT_AREA_HEIGHT_PERCENT = 16;
|
||||
|
||||
CONSOLE_COMPONENT_VISIBLE = true;
|
||||
CONSOLE_COMPONENT_HAS_PANEL = false;
|
||||
CONSOLE_COMPONENT_HAS_ARROW = false;
|
||||
CONSOLE_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
CONSOLE_COMPONENT_AREA_TOP_PERCENT = 6.5;
|
||||
CONSOLE_COMPONENT_AREA_LEFT_PERCENT = 26.5;
|
||||
CONSOLE_COMPONENT_AREA_WIDTH_PERCENT = 3.4;
|
||||
CONSOLE_COMPONENT_AREA_HEIGHT_PERCENT = 4.5;
|
||||
|
||||
VIDEO_COMPONENT_VISIBLE = true;
|
||||
VIDEO_COMPONENT_HAS_PANEL = true;
|
||||
VIDEO_COMPONENT_HAS_ARROW = true;
|
||||
VIDEO_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
VIDEO_COMPONENT_PANEL_ORIENTATION = VALUE_BOTTOM;
|
||||
VIDEO_COMPONENT_PANEL_HORIZONTAL_PERCENT = 47.5;
|
||||
VIDEO_COMPONENT_PANEL_VERTICAL_PERCENT = 18;
|
||||
VIDEO_COMPONENT_ARROW_PERCENT = 58.5;
|
||||
VIDEO_COMPONENT_AREA_TOP_PERCENT = 84;
|
||||
VIDEO_COMPONENT_AREA_LEFT_PERCENT = 57;
|
||||
VIDEO_COMPONENT_AREA_WIDTH_PERCENT = 6;
|
||||
VIDEO_COMPONENT_AREA_HEIGHT_PERCENT = 8;
|
||||
|
||||
AUDIO_COMPONENT_VISIBLE = false;
|
||||
AUDIO_COMPONENT_HAS_PANEL = true;
|
||||
AUDIO_COMPONENT_HAS_ARROW = true;
|
||||
AUDIO_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
AUDIO_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
AUDIO_COMPONENT_PANEL_HORIZONTAL_PERCENT = 1;
|
||||
AUDIO_COMPONENT_PANEL_VERTICAL_PERCENT = 19;
|
||||
AUDIO_COMPONENT_ARROW_PERCENT = 16;
|
||||
AUDIO_COMPONENT_AREA_TOP_PERCENT = 7;
|
||||
AUDIO_COMPONENT_AREA_LEFT_PERCENT = 14.5;
|
||||
AUDIO_COMPONENT_AREA_WIDTH_PERCENT = 5.4;
|
||||
AUDIO_COMPONENT_AREA_HEIGHT_PERCENT = 11;
|
||||
|
||||
LED_COMPONENT_VISIBLE = true;
|
||||
LED_COMPONENT_HAS_PANEL = true;
|
||||
LED_COMPONENT_HAS_ARROW = false;
|
||||
LED_COMPONENT_PANEL_ALWAYS_VISIBLE = true;
|
||||
LED_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
LED_COMPONENT_PANEL_HORIZONTAL_PERCENT = 61;
|
||||
LED_COMPONENT_PANEL_VERTICAL_PERCENT = 14;
|
||||
LED_COMPONENT_AREA_TOP_PERCENT = 8.5;
|
||||
LED_COMPONENT_AREA_LEFT_PERCENT = 62.6;
|
||||
LED_COMPONENT_AREA_WIDTH_PERCENT = 1.5;
|
||||
LED_COMPONENT_AREA_HEIGHT_PERCENT = 4;
|
||||
|
||||
FLASH_MEMORY_COMPONENT_VISIBLE = true;
|
||||
FLASH_MEMORY_COMPONENT_HAS_PANEL = true;
|
||||
FLASH_MEMORY_COMPONENT_HAS_ARROW = true;
|
||||
FLASH_MEMORY_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
FLASH_MEMORY_COMPONENT_PANEL_ORIENTATION = VALUE_LEFT;
|
||||
FLASH_MEMORY_COMPONENT_PANEL_HORIZONTAL_PERCENT = 45;
|
||||
FLASH_MEMORY_COMPONENT_PANEL_VERTICAL_PERCENT = 36;
|
||||
FLASH_MEMORY_COMPONENT_ARROW_PERCENT = 38;
|
||||
FLASH_MEMORY_COMPONENT_AREA_TOP_PERCENT = 36.3;
|
||||
FLASH_MEMORY_COMPONENT_AREA_LEFT_PERCENT = 38.8;
|
||||
FLASH_MEMORY_COMPONENT_AREA_WIDTH_PERCENT = 5.4;
|
||||
FLASH_MEMORY_COMPONENT_AREA_HEIGHT_PERCENT = 8;
|
||||
|
||||
|
||||
// Capabilities
|
||||
SUPPORTS_VIDEO_BRIGHTNESS = false;
|
||||
|
||||
// Constructor.
|
||||
constructor(deviceData) {
|
||||
super(CCIMX8MNANO.DEVICE_TYPE, CCIMX8MNANO.PLATFORM_NAME, deviceData);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright 2022, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
class CCIMX8MMINI extends ConnectCoreDevice {
|
||||
|
||||
// Public constants.
|
||||
static DEVICE_TYPE = "ccimx8mm-dvk";
|
||||
static PLATFORM_NAME = "ConnectCore 8M-Mini DVK";
|
||||
|
||||
// Variables.
|
||||
BOARD_IMAGE = "ccimx8m-mini_board.png";
|
||||
BOARD_IMAGE_SCALE = 85;
|
||||
|
||||
CPU_COMPONENT_VISIBLE = true;
|
||||
CPU_COMPONENT_HAS_PANEL = true;
|
||||
CPU_COMPONENT_HAS_ARROW = true;
|
||||
CPU_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
CPU_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
CPU_COMPONENT_PANEL_HORIZONTAL_PERCENT = 28.5;
|
||||
CPU_COMPONENT_PANEL_VERTICAL_PERCENT = 57;
|
||||
CPU_COMPONENT_ARROW_PERCENT = 33.5;
|
||||
CPU_COMPONENT_AREA_TOP_PERCENT = 45.7;
|
||||
CPU_COMPONENT_AREA_LEFT_PERCENT = 32.4;
|
||||
CPU_COMPONENT_AREA_WIDTH_PERCENT = 5.7;
|
||||
CPU_COMPONENT_AREA_HEIGHT_PERCENT = 9;
|
||||
|
||||
MEMORY_COMPONENT_VISIBLE = true;
|
||||
MEMORY_COMPONENT_HAS_PANEL = true;
|
||||
MEMORY_COMPONENT_HAS_ARROW = true;
|
||||
MEMORY_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
MEMORY_COMPONENT_PANEL_ORIENTATION = VALUE_BOTTOM;
|
||||
MEMORY_COMPONENT_PANEL_HORIZONTAL_PERCENT = 22;
|
||||
MEMORY_COMPONENT_PANEL_VERTICAL_PERCENT = 65;
|
||||
MEMORY_COMPONENT_ARROW_PERCENT = 33.7;
|
||||
MEMORY_COMPONENT_AREA_TOP_PERCENT = 37;
|
||||
MEMORY_COMPONENT_AREA_LEFT_PERCENT = 32.4;
|
||||
MEMORY_COMPONENT_AREA_WIDTH_PERCENT = 6;
|
||||
MEMORY_COMPONENT_AREA_HEIGHT_PERCENT = 7;
|
||||
|
||||
WIFI_BT_COMPONENT_VISIBLE = true;
|
||||
WIFI_BT_COMPONENT_HAS_PANEL = true;
|
||||
WIFI_BT_COMPONENT_HAS_ARROW = true;
|
||||
WIFI_BT_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
WIFI_BT_COMPONENT_PANEL_ORIENTATION = VALUE_RIGHT;
|
||||
WIFI_BT_COMPONENT_PANEL_HORIZONTAL_PERCENT = 73;
|
||||
WIFI_BT_COMPONENT_PANEL_VERTICAL_PERCENT = 38;
|
||||
WIFI_BT_COMPONENT_ARROW_PERCENT = 46;
|
||||
WIFI_BT_COMPONENT_AREA_TOP_PERCENT = 46.5;
|
||||
WIFI_BT_COMPONENT_AREA_LEFT_PERCENT = 28.3;
|
||||
WIFI_BT_COMPONENT_AREA_WIDTH_PERCENT = 4;
|
||||
WIFI_BT_COMPONENT_AREA_HEIGHT_PERCENT = 6;
|
||||
|
||||
ETHERNET_COMPONENT_VISIBLE = true;
|
||||
ETHERNET_COMPONENT_HAS_PANEL = true;
|
||||
ETHERNET_COMPONENT_HAS_ARROW = true;
|
||||
ETHERNET_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
ETHERNET_COMPONENT_PANEL_ORIENTATION = VALUE_LEFT;
|
||||
ETHERNET_COMPONENT_PANEL_HORIZONTAL_PERCENT = 21;
|
||||
ETHERNET_COMPONENT_PANEL_VERTICAL_PERCENT = 70;
|
||||
ETHERNET_COMPONENT_ARROW_PERCENT = 78;
|
||||
ETHERNET_COMPONENT_AREA_TOP_PERCENT = 77;
|
||||
ETHERNET_COMPONENT_AREA_LEFT_PERCENT = 11;
|
||||
ETHERNET_COMPONENT_AREA_WIDTH_PERCENT = 8.5;
|
||||
ETHERNET_COMPONENT_AREA_HEIGHT_PERCENT = 16;
|
||||
|
||||
CONSOLE_COMPONENT_VISIBLE = true;
|
||||
CONSOLE_COMPONENT_HAS_PANEL = false;
|
||||
CONSOLE_COMPONENT_HAS_ARROW = false;
|
||||
CONSOLE_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
CONSOLE_COMPONENT_AREA_TOP_PERCENT = 6.5;
|
||||
CONSOLE_COMPONENT_AREA_LEFT_PERCENT = 26.5;
|
||||
CONSOLE_COMPONENT_AREA_WIDTH_PERCENT = 3.4;
|
||||
CONSOLE_COMPONENT_AREA_HEIGHT_PERCENT = 4.5;
|
||||
|
||||
VIDEO_COMPONENT_VISIBLE = true;
|
||||
VIDEO_COMPONENT_HAS_PANEL = true;
|
||||
VIDEO_COMPONENT_HAS_ARROW = true;
|
||||
VIDEO_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
VIDEO_COMPONENT_PANEL_ORIENTATION = VALUE_BOTTOM;
|
||||
VIDEO_COMPONENT_PANEL_HORIZONTAL_PERCENT = 47.5;
|
||||
VIDEO_COMPONENT_PANEL_VERTICAL_PERCENT = 18;
|
||||
VIDEO_COMPONENT_ARROW_PERCENT = 58.5;
|
||||
VIDEO_COMPONENT_AREA_TOP_PERCENT = 84;
|
||||
VIDEO_COMPONENT_AREA_LEFT_PERCENT = 57;
|
||||
VIDEO_COMPONENT_AREA_WIDTH_PERCENT = 6;
|
||||
VIDEO_COMPONENT_AREA_HEIGHT_PERCENT = 8;
|
||||
|
||||
AUDIO_COMPONENT_VISIBLE = false;
|
||||
AUDIO_COMPONENT_HAS_PANEL = true;
|
||||
AUDIO_COMPONENT_HAS_ARROW = true;
|
||||
AUDIO_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
AUDIO_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
AUDIO_COMPONENT_PANEL_HORIZONTAL_PERCENT = 1;
|
||||
AUDIO_COMPONENT_PANEL_VERTICAL_PERCENT = 19;
|
||||
AUDIO_COMPONENT_ARROW_PERCENT = 16;
|
||||
AUDIO_COMPONENT_AREA_TOP_PERCENT = 7;
|
||||
AUDIO_COMPONENT_AREA_LEFT_PERCENT = 14.5;
|
||||
AUDIO_COMPONENT_AREA_WIDTH_PERCENT = 5.4;
|
||||
AUDIO_COMPONENT_AREA_HEIGHT_PERCENT = 11;
|
||||
|
||||
LED_COMPONENT_VISIBLE = true;
|
||||
LED_COMPONENT_HAS_PANEL = true;
|
||||
LED_COMPONENT_HAS_ARROW = false;
|
||||
LED_COMPONENT_PANEL_ALWAYS_VISIBLE = true;
|
||||
LED_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
LED_COMPONENT_PANEL_HORIZONTAL_PERCENT = 61;
|
||||
LED_COMPONENT_PANEL_VERTICAL_PERCENT = 14;
|
||||
LED_COMPONENT_AREA_TOP_PERCENT = 8.5;
|
||||
LED_COMPONENT_AREA_LEFT_PERCENT = 62.6;
|
||||
LED_COMPONENT_AREA_WIDTH_PERCENT = 1.5;
|
||||
LED_COMPONENT_AREA_HEIGHT_PERCENT = 4;
|
||||
|
||||
FLASH_MEMORY_COMPONENT_VISIBLE = true;
|
||||
FLASH_MEMORY_COMPONENT_HAS_PANEL = true;
|
||||
FLASH_MEMORY_COMPONENT_HAS_ARROW = true;
|
||||
FLASH_MEMORY_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
FLASH_MEMORY_COMPONENT_PANEL_ORIENTATION = VALUE_LEFT;
|
||||
FLASH_MEMORY_COMPONENT_PANEL_HORIZONTAL_PERCENT = 45;
|
||||
FLASH_MEMORY_COMPONENT_PANEL_VERTICAL_PERCENT = 36;
|
||||
FLASH_MEMORY_COMPONENT_ARROW_PERCENT = 38;
|
||||
FLASH_MEMORY_COMPONENT_AREA_TOP_PERCENT = 36.3;
|
||||
FLASH_MEMORY_COMPONENT_AREA_LEFT_PERCENT = 38.8;
|
||||
FLASH_MEMORY_COMPONENT_AREA_WIDTH_PERCENT = 5.4;
|
||||
FLASH_MEMORY_COMPONENT_AREA_HEIGHT_PERCENT = 8;
|
||||
|
||||
|
||||
// Capabilities
|
||||
SUPPORTS_VIDEO_BRIGHTNESS = false;
|
||||
|
||||
// Constructor.
|
||||
constructor(deviceData) {
|
||||
super(CCIMX8MMINI.DEVICE_TYPE, CCIMX8MMINI.PLATFORM_NAME, deviceData);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright 2022, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
class CCIMX8X extends ConnectCoreDevice {
|
||||
|
||||
// Public constants.
|
||||
static DEVICE_TYPE = "ccimx8x-sbc-pro";
|
||||
static PLATFORM_NAME = "ConnectCore 8X SBC Pro";
|
||||
|
||||
// Variables.
|
||||
BOARD_IMAGE = "ccimx8x-sbc-pro_board.png";
|
||||
BOARD_IMAGE_SCALE = 60;
|
||||
|
||||
CPU_COMPONENT_VISIBLE = true;
|
||||
CPU_COMPONENT_HAS_PANEL = true;
|
||||
CPU_COMPONENT_HAS_ARROW = true;
|
||||
CPU_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
CPU_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
CPU_COMPONENT_PANEL_HORIZONTAL_PERCENT = 49;
|
||||
CPU_COMPONENT_PANEL_VERTICAL_PERCENT = 65;
|
||||
CPU_COMPONENT_ARROW_PERCENT = 62;
|
||||
CPU_COMPONENT_AREA_TOP_PERCENT = 40;
|
||||
CPU_COMPONENT_AREA_LEFT_PERCENT = 54;
|
||||
CPU_COMPONENT_AREA_WIDTH_PERCENT = 19.5;
|
||||
CPU_COMPONENT_AREA_HEIGHT_PERCENT = 24;
|
||||
|
||||
MEMORY_COMPONENT_VISIBLE = true;
|
||||
MEMORY_COMPONENT_HAS_PANEL = true;
|
||||
MEMORY_COMPONENT_HAS_ARROW = true;
|
||||
MEMORY_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
MEMORY_COMPONENT_PANEL_ORIENTATION = VALUE_RIGHT;
|
||||
MEMORY_COMPONENT_PANEL_HORIZONTAL_PERCENT = 43;
|
||||
MEMORY_COMPONENT_PANEL_VERTICAL_PERCENT = 22.5;
|
||||
MEMORY_COMPONENT_ARROW_PERCENT = 29;
|
||||
MEMORY_COMPONENT_AREA_TOP_PERCENT = 22.25;
|
||||
MEMORY_COMPONENT_AREA_LEFT_PERCENT = 57.75;
|
||||
MEMORY_COMPONENT_AREA_WIDTH_PERCENT = 9.5;
|
||||
MEMORY_COMPONENT_AREA_HEIGHT_PERCENT = 16.5;
|
||||
|
||||
WIFI_BT_COMPONENT_VISIBLE = true;
|
||||
WIFI_BT_COMPONENT_HAS_PANEL = true;
|
||||
WIFI_BT_COMPONENT_HAS_ARROW = true;
|
||||
WIFI_BT_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
WIFI_BT_COMPONENT_PANEL_ORIENTATION = VALUE_LEFT;
|
||||
WIFI_BT_COMPONENT_PANEL_HORIZONTAL_PERCENT = 83;
|
||||
WIFI_BT_COMPONENT_PANEL_VERTICAL_PERCENT = 35;
|
||||
WIFI_BT_COMPONENT_ARROW_PERCENT = 41;
|
||||
WIFI_BT_COMPONENT_AREA_TOP_PERCENT = 38;
|
||||
WIFI_BT_COMPONENT_AREA_LEFT_PERCENT = 73.5;
|
||||
WIFI_BT_COMPONENT_AREA_WIDTH_PERCENT = 8.5;
|
||||
WIFI_BT_COMPONENT_AREA_HEIGHT_PERCENT = 10;
|
||||
|
||||
ETHERNET_COMPONENT_VISIBLE = true;
|
||||
ETHERNET_COMPONENT_HAS_PANEL = true;
|
||||
ETHERNET_COMPONENT_HAS_ARROW = true;
|
||||
ETHERNET_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
ETHERNET_COMPONENT_PANEL_ORIENTATION = VALUE_BOTTOM;
|
||||
ETHERNET_COMPONENT_PANEL_HORIZONTAL_PERCENT = -7;
|
||||
ETHERNET_COMPONENT_PANEL_VERTICAL_PERCENT = 34;
|
||||
ETHERNET_COMPONENT_ARROW_PERCENT = 18;
|
||||
ETHERNET_COMPONENT_AREA_TOP_PERCENT = 68;
|
||||
ETHERNET_COMPONENT_AREA_LEFT_PERCENT = 12;
|
||||
ETHERNET_COMPONENT_AREA_WIDTH_PERCENT = 17;
|
||||
ETHERNET_COMPONENT_AREA_HEIGHT_PERCENT = 27;
|
||||
|
||||
CONSOLE_COMPONENT_VISIBLE = true;
|
||||
CONSOLE_COMPONENT_HAS_PANEL = false;
|
||||
CONSOLE_COMPONENT_HAS_ARROW = false;
|
||||
CONSOLE_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
CONSOLE_COMPONENT_AREA_TOP_PERCENT = 22.5;
|
||||
CONSOLE_COMPONENT_AREA_LEFT_PERCENT = 86;
|
||||
CONSOLE_COMPONENT_AREA_WIDTH_PERCENT = 7;
|
||||
CONSOLE_COMPONENT_AREA_HEIGHT_PERCENT = 4.5;
|
||||
|
||||
VIDEO_COMPONENT_VISIBLE = true;
|
||||
VIDEO_COMPONENT_HAS_PANEL = true;
|
||||
VIDEO_COMPONENT_HAS_ARROW = true;
|
||||
VIDEO_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
VIDEO_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
VIDEO_COMPONENT_PANEL_HORIZONTAL_PERCENT = -15;
|
||||
VIDEO_COMPONENT_PANEL_VERTICAL_PERCENT = 18;
|
||||
VIDEO_COMPONENT_ARROW_PERCENT = 20.75;
|
||||
VIDEO_COMPONENT_AREA_TOP_PERCENT = 8.5;
|
||||
VIDEO_COMPONENT_AREA_LEFT_PERCENT = 8.75;
|
||||
VIDEO_COMPONENT_AREA_WIDTH_PERCENT = 27.5;
|
||||
VIDEO_COMPONENT_AREA_HEIGHT_PERCENT = 7.5;
|
||||
|
||||
AUDIO_COMPONENT_VISIBLE = false;
|
||||
AUDIO_COMPONENT_HAS_PANEL = true;
|
||||
AUDIO_COMPONENT_HAS_ARROW = true;
|
||||
AUDIO_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
AUDIO_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
AUDIO_COMPONENT_PANEL_HORIZONTAL_PERCENT = 1;
|
||||
AUDIO_COMPONENT_PANEL_VERTICAL_PERCENT = 19;
|
||||
AUDIO_COMPONENT_ARROW_PERCENT = 16;
|
||||
AUDIO_COMPONENT_AREA_TOP_PERCENT = 7;
|
||||
AUDIO_COMPONENT_AREA_LEFT_PERCENT = 14.5;
|
||||
AUDIO_COMPONENT_AREA_WIDTH_PERCENT = 5.4;
|
||||
AUDIO_COMPONENT_AREA_HEIGHT_PERCENT = 11;
|
||||
|
||||
LED_COMPONENT_VISIBLE = true;
|
||||
LED_COMPONENT_HAS_PANEL = true;
|
||||
LED_COMPONENT_HAS_ARROW = false;
|
||||
LED_COMPONENT_PANEL_ALWAYS_VISIBLE = true;
|
||||
LED_COMPONENT_PANEL_ORIENTATION = VALUE_LEFT;
|
||||
LED_COMPONENT_PANEL_HORIZONTAL_PERCENT = 30;
|
||||
LED_COMPONENT_PANEL_VERTICAL_PERCENT = 52;
|
||||
LED_COMPONENT_AREA_TOP_PERCENT = 53.5;
|
||||
LED_COMPONENT_AREA_LEFT_PERCENT = 27;
|
||||
LED_COMPONENT_AREA_WIDTH_PERCENT = 2.5;
|
||||
LED_COMPONENT_AREA_HEIGHT_PERCENT = 5;
|
||||
|
||||
FLASH_MEMORY_COMPONENT_VISIBLE = true;
|
||||
FLASH_MEMORY_COMPONENT_HAS_PANEL = true;
|
||||
FLASH_MEMORY_COMPONENT_HAS_ARROW = true;
|
||||
FLASH_MEMORY_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
FLASH_MEMORY_COMPONENT_PANEL_ORIENTATION = VALUE_BOTTOM;
|
||||
FLASH_MEMORY_COMPONENT_PANEL_HORIZONTAL_PERCENT = 57.5;
|
||||
FLASH_MEMORY_COMPONENT_PANEL_VERTICAL_PERCENT = 79.5;
|
||||
FLASH_MEMORY_COMPONENT_ARROW_PERCENT = 71.5;
|
||||
FLASH_MEMORY_COMPONENT_AREA_TOP_PERCENT = 22.25;
|
||||
FLASH_MEMORY_COMPONENT_AREA_LEFT_PERCENT = 68;
|
||||
FLASH_MEMORY_COMPONENT_AREA_WIDTH_PERCENT = 10.8;
|
||||
FLASH_MEMORY_COMPONENT_AREA_HEIGHT_PERCENT = 15;
|
||||
|
||||
|
||||
// Capabilities
|
||||
SUPPORTS_VIDEO_BRIGHTNESS = false;
|
||||
|
||||
// Constructor.
|
||||
constructor(deviceData) {
|
||||
super(CCIMX8X.DEVICE_TYPE, CCIMX8X.PLATFORM_NAME, deviceData);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
/*\
|
||||
|*| ========================================================================
|
||||
|*| Bootstrap Toggle: bootstrap4-toggle.js v3.6.1
|
||||
|*| https://gitbrent.github.io/bootstrap4-toggle/
|
||||
|*| ========================================================================
|
||||
|*| Copyright 2018-2019 Brent Ely
|
||||
|*| Licensed under MIT
|
||||
|*| ========================================================================
|
||||
\*/
|
||||
!function(a){"use strict";function l(t,e){this.$element=a(t),this.options=a.extend({},this.defaults(),e),this.render()}l.VERSION="3.6.0",l.DEFAULTS={on:"On",off:"Off",onstyle:"primary",offstyle:"light",size:"normal",style:"",width:null,height:null},l.prototype.defaults=function(){return{on:this.$element.attr("data-on")||l.DEFAULTS.on,off:this.$element.attr("data-off")||l.DEFAULTS.off,onstyle:this.$element.attr("data-onstyle")||l.DEFAULTS.onstyle,offstyle:this.$element.attr("data-offstyle")||l.DEFAULTS.offstyle,size:this.$element.attr("data-size")||l.DEFAULTS.size,style:this.$element.attr("data-style")||l.DEFAULTS.style,width:this.$element.attr("data-width")||l.DEFAULTS.width,height:this.$element.attr("data-height")||l.DEFAULTS.height}},l.prototype.render=function(){this._onstyle="btn-"+this.options.onstyle,this._offstyle="btn-"+this.options.offstyle;var t="large"===this.options.size||"lg"===this.options.size?"btn-lg":"small"===this.options.size||"sm"===this.options.size?"btn-sm":"mini"===this.options.size||"xs"===this.options.size?"btn-xs":"",e=a('<label for="'+this.$element.prop("id")+'" class="btn">').html(this.options.on).addClass(this._onstyle+" "+t),s=a('<label for="'+this.$element.prop("id")+'" class="btn">').html(this.options.off).addClass(this._offstyle+" "+t),o=a('<span class="toggle-handle btn btn-light">').addClass(t),i=a('<div class="toggle-group">').append(e,s,o),l=a('<div class="toggle btn" data-toggle="toggle" role="button">').addClass(this.$element.prop("checked")?this._onstyle:this._offstyle+" off").addClass(t).addClass(this.options.style);this.$element.wrap(l),a.extend(this,{$toggle:this.$element.parent(),$toggleOn:e,$toggleOff:s,$toggleGroup:i}),this.$toggle.append(i);var n=this.options.width||Math.max(e.outerWidth(),s.outerWidth())+o.outerWidth()/2,h=this.options.height||Math.max(e.outerHeight(),s.outerHeight());e.addClass("toggle-on"),s.addClass("toggle-off"),this.$toggle.css({width:n,height:h}),this.options.height&&(e.css("line-height",e.height()+"px"),s.css("line-height",s.height()+"px")),this.update(!0),this.trigger(!0)},l.prototype.toggle=function(){this.$element.prop("checked")?this.off():this.on()},l.prototype.on=function(t){if(this.$element.prop("disabled"))return!1;this.$toggle.removeClass(this._offstyle+" off").addClass(this._onstyle),this.$element.prop("checked",!0),t||this.trigger()},l.prototype.off=function(t){if(this.$element.prop("disabled"))return!1;this.$toggle.removeClass(this._onstyle).addClass(this._offstyle+" off"),this.$element.prop("checked",!1),t||this.trigger()},l.prototype.enable=function(){this.$toggle.removeClass("disabled"),this.$toggle.removeAttr("disabled"),this.$element.prop("disabled",!1)},l.prototype.disable=function(){this.$toggle.addClass("disabled"),this.$toggle.attr("disabled","disabled"),this.$element.prop("disabled",!0)},l.prototype.update=function(t){this.$element.prop("disabled")?this.disable():this.enable(),this.$element.prop("checked")?this.on(t):this.off(t)},l.prototype.trigger=function(t){this.$element.off("change.bs.toggle"),t||this.$element.change(),this.$element.on("change.bs.toggle",a.proxy(function(){this.update()},this))},l.prototype.destroy=function(){this.$element.off("change.bs.toggle"),this.$toggleGroup.remove(),this.$element.removeData("bs.toggle"),this.$element.unwrap()};var t=a.fn.bootstrapToggle;a.fn.bootstrapToggle=function(o){var i=Array.prototype.slice.call(arguments,1)[0];return this.each(function(){var t=a(this),e=t.data("bs.toggle"),s="object"==typeof o&&o;e||t.data("bs.toggle",e=new l(this,s)),"string"==typeof o&&e[o]&&"boolean"==typeof i?e[o](i):"string"==typeof o&&e[o]&&e[o]()})},a.fn.bootstrapToggle.Constructor=l,a.fn.toggle.noConflict=function(){return a.fn.bootstrapToggle=t,this},a(function(){a("input[type=checkbox][data-toggle^=toggle]").bootstrapToggle()}),a(document).on("click.bs.toggle","div[data-toggle^=toggle]",function(t){a(this).find("input[type=checkbox]").bootstrapToggle("toggle"),t.preventDefault()})}(jQuery);
|
||||
//# sourceMappingURL=bootstrap4-toggle.min.js.map
|
||||
|
|
@ -0,0 +1,482 @@
|
|||
/*
|
||||
* Copyright 2022, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
// Constants.
|
||||
const ID_AREA = "area";
|
||||
const ID_AREA_HEIGHT = "area-height";
|
||||
const ID_AREA_LEFT_MARGIN = "area-left-margin";
|
||||
const ID_AREA_TOP_MARGIN = "area-top-margin";
|
||||
const ID_AREA_WIDTH = "area-width";
|
||||
const ID_ARROW = "arrow";
|
||||
const ID_ARROW_MARGIN = "arrow-margin";
|
||||
const ID_AUDIO = "audio";
|
||||
const ID_BLUETOOTH_MAC = "bluetooth_mac";
|
||||
const ID_BOARD_ID = "board_id";
|
||||
const ID_BOARD_VARIANT = "board_variant";
|
||||
const ID_BT_READ_DATA = "bluetooth_received_data";
|
||||
const ID_BT_SENT_DATA = "bluetooth_sent_data";
|
||||
const ID_BT_STATE = "bluetooth_state";
|
||||
const ID_CONSOLE = "console";
|
||||
const ID_CONFIRM_DIALOG = "confirm_dialog";
|
||||
const ID_CONFIRM_DIALOG_MESSAGE = "confirm_dialog_message";
|
||||
const ID_CONFIRM_DIALOG_NO_BUTTON = "confirm_dialog_no_button";
|
||||
const ID_CONFIRM_DIALOG_TITLE = "confirm_dialog_title";
|
||||
const ID_CONFIRM_DIALOG_YES_BUTTON = "confirm_dialog_yes_button";
|
||||
const ID_CPU = "cpu";
|
||||
const ID_CPU_FREQUENCY = "cpu_frequency";
|
||||
const ID_CPU_LOAD = "cpu_load";
|
||||
const ID_CPU_TEMPERATURE = "cpu_temperature";
|
||||
const ID_CPU_UPTIME = "cpu_uptime";
|
||||
const ID_CURRENT_DIR = "current_dir";
|
||||
const ID_DATA = "data";
|
||||
const ID_DEVICE_NAME = "device-name";
|
||||
const ID_DEVICE_TYPE = "device_type";
|
||||
const ID_DEVICES = "devices";
|
||||
const ID_DEY_VERSION = "dey_version";
|
||||
const ID_ERROR = "error";
|
||||
const ID_ERROR_GUIDE = "error_guide";
|
||||
const ID_ERROR_MESSAGE = "error_msg";
|
||||
const ID_ERROR_TITLE = "error_title";
|
||||
const ID_ETHERNET = "ethernet";
|
||||
const ID_ETHERNET_IP = "ethernet_ip";
|
||||
const ID_ETHERNET_MAC = "ethernet_mac";
|
||||
const ID_ETHERNET_READ_DATA = "ethernet_received_data";
|
||||
const ID_ETHERNET_SENT_DATA = "ethernet_sent_data";
|
||||
const ID_ETHERNET_STATE = "ethernet_state";
|
||||
const ID_FILES = "files";
|
||||
const ID_FLASH_MEMORY = "flash_memory";
|
||||
const ID_FLASH_SIZE = "flash_size";
|
||||
const ID_FW_STORE_PATH = "fw_store_path";
|
||||
const ID_HAS_ARROW = "has-arrow";
|
||||
const ID_HAS_PANEL = "has-panel";
|
||||
const ID_ICON = "icon";
|
||||
const ID_ID = "id";
|
||||
const ID_INFO_POPUP = "info_popup";
|
||||
const ID_INFO_POPUP_MESSAGE = "info_popup_message";
|
||||
const ID_INFO_POPUP_TITLE = "info_popup_title";
|
||||
const ID_KERNEL_VERSION = "kernel_version";
|
||||
const ID_LAST_MODIFIED = "last_modified";
|
||||
const ID_LED = "led";
|
||||
const ID_LOADING_POPUP = "loading_popup";
|
||||
const ID_LOADING_POPUP_MESSAGE = "loading_popup_message";
|
||||
const ID_LOADING_WRAPPER = "loading_wrapper";
|
||||
const ID_MCA_FW_VERSION = "mca_fw_version";
|
||||
const ID_MCA_HW_VERSION = "mca_hw_version";
|
||||
const ID_MEMORY = "memory";
|
||||
const ID_MEMORY_FREE = "memory_free";
|
||||
const ID_MEMORY_TOTAL = "memory_total";
|
||||
const ID_MEMORY_USED = "memory_used";
|
||||
const ID_MESSAGE = "message";
|
||||
const ID_MODULE_VARIANT = "module_variant";
|
||||
const ID_NAME = "name";
|
||||
const ID_NUM_SAMPLES_UPLOAD = "num_samples_upload";
|
||||
const ID_ONLINE = "online";
|
||||
const ID_PANEL = "panel";
|
||||
const ID_PANEL_ALWAYS_VISIBLE = "panel-always-visible";
|
||||
const ID_PANEL_HORIZONTAL_MARGIN = "panel-horizontal-margin";
|
||||
const ID_PANEL_ORIENTATION = "panel-orientation";
|
||||
const ID_PANEL_VERTICAL_MARGIN = "panel-vertical-margin";
|
||||
const ID_PATH = "path";
|
||||
const ID_PROGRESS = "progress";
|
||||
const ID_SAMPLE_RATE = "sample_rate";
|
||||
const ID_SERIAL_NUMBER = "serial_number";
|
||||
const ID_SESSION_ID = "session_id";
|
||||
const ID_SIZE = "size";
|
||||
const ID_STATUS = "status";
|
||||
const ID_STREAM = "stream";
|
||||
const ID_TIMESTAMP = "timestamp";
|
||||
const ID_TYPE = "type";
|
||||
const ID_UBOOT_VERSION = "uboot_version";
|
||||
const ID_VALUE = "value";
|
||||
const ID_VIDEO = "video";
|
||||
const ID_VIDEO_RESOLUTION = "video_resolution";
|
||||
const ID_VISIBLE = "visible";
|
||||
const ID_WIFI_BT = "wifi-bt";
|
||||
const ID_WIFI_IP = "wifi_ip";
|
||||
const ID_WIFI_MAC = "wifi_mac";
|
||||
const ID_WIFI_READ_DATA = "wifi_received_data";
|
||||
const ID_WIFI_SENT_DATA = "wifi_sent_data";
|
||||
const ID_WIFI_STATE = "wifi_state";
|
||||
|
||||
const VALUE_ACTIVE = "active";
|
||||
const VALUE_ABORT = "abort";
|
||||
const VALUE_BOTTOM = "bottom";
|
||||
const VALUE_CANCELED = "canceled";
|
||||
const VALUE_FAILED = "failed";
|
||||
const VALUE_LEFT = "left";
|
||||
const VALUE_OFF = "Off";
|
||||
const VALUE_ON = "On";
|
||||
const VALUE_RIGHT = "right";
|
||||
const VALUE_SUCCESSFUL = "successful";
|
||||
const VALUE_TOP = "top";
|
||||
const VALUE_UNKNOWN = "unknown";
|
||||
|
||||
const CLASS_D_NONE = "d-none";
|
||||
const CLASS_DISABLED_DIV = "disabled-div";
|
||||
const CLASS_ELEMENT_GRAYED = "element-grayed";
|
||||
const CLASS_SELECTED = "selected";
|
||||
const CLASS_VALUE_ANIMATION = "value-animation";
|
||||
const CLASS_VALUE_UPDATED = "value-updated";
|
||||
|
||||
const ERROR_ABORTED = "Operation aborted";
|
||||
const ERROR_URL_NOT_FOUND = "Requested URL not found";
|
||||
const ERROR_SERVER_ERROR = "Internal server error";
|
||||
const ERROR_TITLE = "Error";
|
||||
const ERROR_UNKNOWN_ERROR = "Unknown error";
|
||||
|
||||
const PREFIX_STREAM = "system_monitor/";
|
||||
const STREAM_CPU_LOAD = PREFIX_STREAM + "cpu_load";
|
||||
const STREAM_MEMORY_FREE = PREFIX_STREAM + "free_memory";
|
||||
|
||||
const PATH_IMAGES = "../static/images/";
|
||||
|
||||
const PORT = "9090";
|
||||
|
||||
String.prototype.format = function() {
|
||||
var formatted = this;
|
||||
for (var arg in arguments)
|
||||
formatted = formatted.replace("{" + arg + "}", arguments[arg]);
|
||||
return formatted;
|
||||
};
|
||||
|
||||
// Updates the value of the given element ID.
|
||||
function updateValueWithEffect(elementID, value) {
|
||||
// Initialize variables.
|
||||
var htmlElement = document.getElementById(elementID);
|
||||
// Sanity checks.
|
||||
if (htmlElement == null || htmlElement == "undefined" || value == null)
|
||||
return;
|
||||
// Apply value and classes.
|
||||
htmlElement.classList.add(CLASS_VALUE_UPDATED);
|
||||
htmlElement.innerText = value;
|
||||
htmlElement.classList.add(CLASS_VALUE_ANIMATION);
|
||||
setTimeout(function() {
|
||||
htmlElement.classList.remove(CLASS_VALUE_UPDATED);
|
||||
setTimeout(function() {
|
||||
htmlElement.classList.remove(CLASS_VALUE_ANIMATION);
|
||||
}, 3000);
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// Returns the server address.
|
||||
function getServerAddress() {
|
||||
var host = window.location.hostname;
|
||||
if (!Boolean(host))
|
||||
host = "127.0.0.1";
|
||||
|
||||
return host + ":" + PORT;
|
||||
}
|
||||
|
||||
function is_local_access() {
|
||||
var host = window.location.hostname;
|
||||
return !Boolean(host) || host == "127.0.0.1" || host == "localhost";
|
||||
}
|
||||
|
||||
// Shows/hides a front popup over the given background element.
|
||||
function showPopup(backElementID, frontElementID, visible) {
|
||||
// Initialize variables.
|
||||
var backElement = document.getElementById(backElementID);
|
||||
var frontElement = document.getElementById(frontElementID);
|
||||
// Sanity checks.
|
||||
if (backElement == null || frontElement == null)
|
||||
return;
|
||||
// Show/Hide the popup.
|
||||
if (visible) {
|
||||
if (!backElement.classList.contains(CLASS_ELEMENT_GRAYED))
|
||||
backElement.classList.add(CLASS_ELEMENT_GRAYED);
|
||||
if (frontElement.classList.contains(CLASS_D_NONE))
|
||||
frontElement.classList.remove(CLASS_D_NONE);
|
||||
} else {
|
||||
if (backElement.classList.contains(CLASS_ELEMENT_GRAYED))
|
||||
backElement.classList.remove(CLASS_ELEMENT_GRAYED);
|
||||
if (!frontElement.classList.contains(CLASS_D_NONE))
|
||||
frontElement.classList.add(CLASS_D_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
// Redirects to the login page.
|
||||
function redirectToLogin() {
|
||||
var url = "/access/login?dest=" + window.location.pathname.replaceAll("/", "");
|
||||
var params = new URLSearchParams(window.location.search);
|
||||
for (let param of params)
|
||||
url += "&" + param[0] + "=" + param[1];
|
||||
window.location.href = url;
|
||||
}
|
||||
|
||||
// Processes the error response of the AJAX request.
|
||||
function processAjaxErrorResponse(response) {
|
||||
// Check common error codes.
|
||||
if (response.status == 401)
|
||||
redirectToLogin();
|
||||
var errorMessage = "";
|
||||
if (response.statusText == VALUE_ABORT)
|
||||
errorMessage = ERROR_ABORTED;
|
||||
else if (response.status == 400) {
|
||||
errorMessage = response.responseJSON[ID_ERROR];
|
||||
// Show the error message (if any).
|
||||
if (errorMessage == null)
|
||||
errorMessage = ERROR_UNKNOWN_ERROR;
|
||||
} else if (response.status == 404)
|
||||
errorMessage = ERROR_URL_NOT_FOUND;
|
||||
else if (response.status == 500)
|
||||
errorMessage = ERROR_SERVER_ERROR;
|
||||
else
|
||||
errorMessage = ERROR_UNKNOWN_ERROR;
|
||||
// Show toast with the error message.
|
||||
toastr.error(errorMessage);
|
||||
// Return the error message.
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
// Check if there is any error in the response.
|
||||
function checkErrorResponse(response, showErrorDialog) {
|
||||
if (response[ID_ERROR_MESSAGE] != null || response[ID_ERROR] != null) {
|
||||
// Process error.
|
||||
var errorTitle = ERROR_TITLE;
|
||||
var errorMessage = getErrorFromResponse(response);
|
||||
if (response[ID_ERROR_TITLE] != null)
|
||||
errorTitle = response[ID_ERROR_TITLE];
|
||||
// Show toast error.
|
||||
if (errorMessage != null && errorMessage != "")
|
||||
toastr.error(errorMessage);
|
||||
// Hide the loading panel.
|
||||
showLoadingPopup(false);
|
||||
// Show error dialog.
|
||||
if (showErrorDialog)
|
||||
showInfoPopup(true, errorTitle, errorMessage);
|
||||
// There was an error, return true.
|
||||
return true;
|
||||
}
|
||||
// No error found.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns the error message from the response.
|
||||
function getErrorFromResponse(response) {
|
||||
var error = "";
|
||||
if (response[ID_ERROR_MESSAGE] != null || response[ID_ERROR] != null) {
|
||||
if (response[ID_ERROR_MESSAGE] != null) {
|
||||
error = response[ID_ERROR_MESSAGE];
|
||||
if (response[ID_ERROR_GUIDE] != null)
|
||||
error += response[ID_ERROR_GUIDE];
|
||||
} else
|
||||
error = response[ID_ERROR];
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// Shows/hides the loading popup panel.
|
||||
function showLoadingPopup(visible, message=null) {
|
||||
// Set loading message only if it is not null and the popup will be visible.
|
||||
if (visible && message != null)
|
||||
document.getElementById(ID_LOADING_POPUP_MESSAGE).innerHTML = message;
|
||||
// Show/Hide the popup.
|
||||
showPopup(ID_LOADING_WRAPPER, ID_LOADING_POPUP, visible);
|
||||
}
|
||||
|
||||
// Shows/hides the info popup panel.
|
||||
function showInfoPopup(visible, tittle=null, message=null) {
|
||||
// Set title and message.
|
||||
if (visible && tittle != null && message != null) {
|
||||
// Initialize vars.
|
||||
var infoPopupTittleElement = document.getElementById(ID_INFO_POPUP_TITLE);
|
||||
var infoPopupMessageElement = document.getElementById(ID_INFO_POPUP_MESSAGE);
|
||||
// Set the info title.
|
||||
if (infoPopupTittleElement != null)
|
||||
infoPopupTittleElement.innerHTML = tittle;
|
||||
// Set the info message.
|
||||
if (infoPopupMessageElement != null)
|
||||
infoPopupMessageElement.innerHTML = message;
|
||||
}
|
||||
// Show/Hide the popup.
|
||||
showPopup(ID_LOADING_WRAPPER, ID_INFO_POPUP, visible);
|
||||
}
|
||||
|
||||
// Shows the confirm dialog.
|
||||
function showConfirmDialog(title, message, yesCallback, noCallback) {
|
||||
// Initialize variables.
|
||||
var confirmDialogTitleElement = document.getElementById(ID_CONFIRM_DIALOG_TITLE);
|
||||
var confirmDialogMessageElement = document.getElementById(ID_CONFIRM_DIALOG_MESSAGE);
|
||||
var confirmDialogYesButtonElement = document.getElementById(ID_CONFIRM_DIALOG_YES_BUTTON);
|
||||
var confirmDialogNoButtonElement = document.getElementById(ID_CONFIRM_DIALOG_NO_BUTTON);
|
||||
// Check if the elements are valid.
|
||||
if (confirmDialogTitleElement != null && confirmDialogMessageElement != null &&
|
||||
confirmDialogYesButtonElement != null && confirmDialogNoButtonElement != null) {
|
||||
// Set the dialog title.
|
||||
confirmDialogTitleElement.innerHTML = title;
|
||||
// Set the dialog message.
|
||||
confirmDialogMessageElement.innerHTML = message;
|
||||
// Show the dialog.
|
||||
showPopup(ID_LOADING_WRAPPER, ID_CONFIRM_DIALOG, true);
|
||||
// Set the yes button callback.
|
||||
confirmDialogYesButtonElement.onclick = function() {
|
||||
// Hide the dialog.
|
||||
showPopup(ID_LOADING_WRAPPER, ID_CONFIRM_DIALOG, false);
|
||||
// Call the callback.
|
||||
if (yesCallback != null)
|
||||
yesCallback();
|
||||
};
|
||||
// Set the no button callback.
|
||||
confirmDialogNoButtonElement.onclick = function() {
|
||||
// Hide the dialog.
|
||||
showPopup(ID_LOADING_WRAPPER, ID_CONFIRM_DIALOG, false);
|
||||
// Call the callback.
|
||||
if (noCallback != null)
|
||||
noCallback();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Transforms the given ISO8601 date to human readable date.
|
||||
function transformDate(iso8601Date) {
|
||||
// Initialize variables.
|
||||
var date = new Date(iso8601Date);
|
||||
var humanReadableDate = "";
|
||||
// Check if the date is valid.
|
||||
if (date != null) {
|
||||
// Transform the date to human readable date.
|
||||
humanReadableDate = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + " " +
|
||||
date.getHours().toString().padStart(2, '0') + ":" + date.getMinutes().toString().padStart(2, '0');
|
||||
}
|
||||
// Return the human readable date.
|
||||
return humanReadableDate;
|
||||
}
|
||||
|
||||
// Transforms the given kilo-bytes to mega-bytes
|
||||
function kiloBytesToMegaBytes(kiloBytes) {
|
||||
return (kiloBytes / 1024).toFixed(2);
|
||||
}
|
||||
|
||||
// Format bytes as human-readable text.
|
||||
function sizeToHumanRead(bytes, si=true, dp=2) {
|
||||
// Initialize variables.
|
||||
var threshold = si ? 1000 : 1024;
|
||||
var units = si
|
||||
? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
||||
: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
|
||||
var unit = -1;
|
||||
// Check if minimum threshold is reached.
|
||||
if (Math.abs(bytes) < threshold)
|
||||
return bytes + ' Bytes';
|
||||
|
||||
const r = 10**dp;
|
||||
do {
|
||||
bytes /= threshold;
|
||||
++unit;
|
||||
} while (Math.round(Math.abs(bytes) * r) / r >= threshold && unit < units.length - 1);
|
||||
|
||||
return bytes.toFixed(dp) + ' ' + units[unit];
|
||||
}
|
||||
|
||||
// Rounds the given number to two decimals.
|
||||
function roundToTwoDecimals(number) {
|
||||
return Math.round(number * 100) / 100;
|
||||
}
|
||||
|
||||
// Returns human readable time from the given seconds.
|
||||
function secondsToTime(numSeconds) {
|
||||
// Initialize variables.
|
||||
var days = 0;
|
||||
var hours = 0;
|
||||
var minutes = 0;
|
||||
var seconds = 0;
|
||||
// Calculate the time values.
|
||||
if (numSeconds < 60)
|
||||
seconds = numSeconds;
|
||||
else if (numSeconds < (60 * 60)) {
|
||||
minutes = Math.floor(numSeconds / 60);
|
||||
seconds = numSeconds % 60;
|
||||
} else if (numSeconds < (60 * 60 * 24)) {
|
||||
hours = Math.floor(numSeconds / (60 * 60));
|
||||
minutes = Math.floor((numSeconds % (60 * 60)) / 60);
|
||||
seconds = numSeconds % 60;
|
||||
} else {
|
||||
days = Math.floor(numSeconds / (60 * 60 * 24));
|
||||
hours = Math.floor((numSeconds % (60 * 60 * 24)) / (60 * 60));
|
||||
minutes = Math.floor((numSeconds % (60 * 60)) / 60);
|
||||
seconds = numSeconds % 60;
|
||||
}
|
||||
// Build time string.
|
||||
var time = "";
|
||||
var numFields = 0;
|
||||
if (days > 0) {
|
||||
time += days + " day";
|
||||
if (days > 1)
|
||||
time += "s";
|
||||
time += " ";
|
||||
numFields += 1;
|
||||
}
|
||||
if (hours > 0) {
|
||||
time += hours + " hour";
|
||||
if (hours > 1)
|
||||
time += "s";
|
||||
time += " ";
|
||||
numFields += 1;
|
||||
}
|
||||
if (minutes > 0 && numFields < 2) {
|
||||
time += minutes + " minute";
|
||||
if (minutes > 1)
|
||||
time += "s";
|
||||
time += " ";
|
||||
numFields += 1;
|
||||
}
|
||||
if ((seconds > 0 && numFields < 2) || time == "") {
|
||||
time += seconds + " second";
|
||||
if (seconds > 1)
|
||||
time += "s";
|
||||
}
|
||||
// Return the time string.
|
||||
return time;
|
||||
}
|
||||
|
||||
// Returns on/off status from the given integer.
|
||||
function onOffStatus(status) {
|
||||
return status == 1 ? VALUE_ON : VALUE_OFF;
|
||||
}
|
||||
|
||||
// Updates the given field ID with the given value.
|
||||
function updateFieldValue(fieldID, value) {
|
||||
var fieldElement = document.getElementById(fieldID);
|
||||
if (fieldElement != null && fieldElement != "undefined")
|
||||
fieldElement.innerText = value;
|
||||
}
|
||||
|
||||
// Rounds the given amount of kilo-bytes to giga bytes.
|
||||
function roundToGigaBytes(kiloBytes) {
|
||||
return (kiloBytes / (1024 * 1024)).toFixed(2);
|
||||
}
|
||||
|
||||
// Returns whether the dashboard page is showing or not.
|
||||
function isDashboardShowing() {
|
||||
if (window.location.pathname == "/")
|
||||
return true;
|
||||
return window.location.pathname.indexOf("index") > -1;
|
||||
}
|
||||
|
||||
// Returns whether the management page is showing or not.
|
||||
function isManagementShowing() {
|
||||
return window.location.pathname.indexOf("management") > -1;
|
||||
}
|
||||
|
||||
// Returns whether the multimedia page is showing or not.
|
||||
function isMultimediaShowing() {
|
||||
return window.location.pathname.indexOf("multimedia") > -1;
|
||||
}
|
||||
|
||||
// Returns the device name.
|
||||
function getDeviceName() {
|
||||
return new URLSearchParams(window.location.search).get(ID_DEVICE_NAME);
|
||||
}
|
||||
|
|
@ -0,0 +1,492 @@
|
|||
/*
|
||||
* Copyright 2022, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
// Constants.
|
||||
const TEMPLATE_COMPONENT_DATA = "" +
|
||||
"{" +
|
||||
" \"" + ID_VISIBLE + "\" : {0}," +
|
||||
" \"" + ID_HAS_PANEL + "\" : {1}," +
|
||||
" \"" + ID_HAS_ARROW + "\" : {2}," +
|
||||
" \"" + ID_PANEL_ALWAYS_VISIBLE + "\" : {3}," +
|
||||
" \"" + ID_PANEL_ORIENTATION + "\" : \"{4}\"," +
|
||||
" \"" + ID_PANEL_HORIZONTAL_MARGIN + "\" : {5}," +
|
||||
" \"" + ID_PANEL_VERTICAL_MARGIN + "\" : {6}," +
|
||||
" \"" + ID_ARROW_MARGIN + "\" : {7}," +
|
||||
" \"" + ID_AREA_TOP_MARGIN + "\" : {8}," +
|
||||
" \"" + ID_AREA_LEFT_MARGIN + "\" : {9}," +
|
||||
" \"" + ID_AREA_WIDTH + "\" : {10}," +
|
||||
" \"" + ID_AREA_HEIGHT + "\" : {11}" +
|
||||
"}"
|
||||
|
||||
// Class that represents a ConnectCore device.
|
||||
class ConnectCoreDevice {
|
||||
|
||||
// Variables
|
||||
// Board image.
|
||||
BOARD_IMAGE;
|
||||
BOARD_IMAGE_SCALE;
|
||||
|
||||
// CPU panel.
|
||||
CPU_COMPONENT_VISIBLE = false;
|
||||
CPU_COMPONENT_HAS_PANEL = false;
|
||||
CPU_COMPONENT_HAS_ARROW = false;
|
||||
CPU_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
CPU_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
CPU_COMPONENT_PANEL_HORIZONTAL_PERCENT = 0;
|
||||
CPU_COMPONENT_PANEL_VERTICAL_PERCENT = 0;
|
||||
CPU_COMPONENT_ARROW_PERCENT = 0;
|
||||
CPU_COMPONENT_AREA_TOP_PERCENT = 0;
|
||||
CPU_COMPONENT_AREA_LEFT_PERCENT = 0;
|
||||
CPU_COMPONENT_AREA_WIDTH_PERCENT = 0;
|
||||
CPU_COMPONENT_AREA_HEIGHT_PERCENT = 0;
|
||||
|
||||
// Memory panel.
|
||||
MEMORY_COMPONENT_VISIBLE = false;
|
||||
MEMORY_COMPONENT_HAS_PANEL = false;
|
||||
MEMORY_COMPONENT_HAS_ARROW = false;
|
||||
MEMORY_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
MEMORY_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
MEMORY_COMPONENT_PANEL_HORIZONTAL_PERCENT = 0;
|
||||
MEMORY_COMPONENT_PANEL_VERTICAL_PERCENT = 0;
|
||||
MEMORY_COMPONENT_ARROW_PERCENT = 0;
|
||||
MEMORY_COMPONENT_AREA_TOP_PERCENT = 0;
|
||||
MEMORY_COMPONENT_AREA_LEFT_PERCENT = 0;
|
||||
MEMORY_COMPONENT_AREA_WIDTH_PERCENT = 0;
|
||||
MEMORY_COMPONENT_AREA_HEIGHT_PERCENT = 0;
|
||||
|
||||
// WiFi/BT panel.
|
||||
WIFI_BT_COMPONENT_VISIBLE = false;
|
||||
WIFI_BT_COMPONENT_HAS_PANEL = false;
|
||||
WIFI_BT_COMPONENT_HAS_ARROW = false;
|
||||
WIFI_BT_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
WIFI_BT_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
WIFI_BT_COMPONENT_PANEL_HORIZONTAL_PERCENT = 0;
|
||||
WIFI_BT_COMPONENT_PANEL_VERTICAL_PERCENT = 0;
|
||||
WIFI_BT_COMPONENT_ARROW_PERCENT = 0;
|
||||
WIFI_BT_COMPONENT_AREA_TOP_PERCENT = 0;
|
||||
WIFI_BT_COMPONENT_AREA_LEFT_PERCENT = 0;
|
||||
WIFI_BT_COMPONENT_AREA_WIDTH_PERCENT = 0;
|
||||
WIFI_BT_COMPONENT_AREA_HEIGHT_PERCENT = 0;
|
||||
|
||||
// Ethernet panel.
|
||||
ETHERNET_COMPONENT_VISIBLE = false;
|
||||
ETHERNET_COMPONENT_HAS_PANEL = false;
|
||||
ETHERNET_COMPONENT_HAS_ARROW = false;
|
||||
ETHERNET_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
ETHERNET_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
ETHERNET_COMPONENT_PANEL_HORIZONTAL_PERCENT = 0;
|
||||
ETHERNET_COMPONENT_PANEL_VERTICAL_PERCENT = 0;
|
||||
ETHERNET_COMPONENT_ARROW_PERCENT = 0;
|
||||
ETHERNET_COMPONENT_AREA_TOP_PERCENT = 0;
|
||||
ETHERNET_COMPONENT_AREA_LEFT_PERCENT = 0;
|
||||
ETHERNET_COMPONENT_AREA_WIDTH_PERCENT = 0;
|
||||
ETHERNET_COMPONENT_AREA_HEIGHT_PERCENT = 0;
|
||||
|
||||
// Console.
|
||||
CONSOLE_COMPONENT_VISIBLE = false;
|
||||
CONSOLE_COMPONENT_HAS_PANEL = false;
|
||||
CONSOLE_COMPONENT_HAS_ARROW = false;
|
||||
CONSOLE_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
CONSOLE_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
CONSOLE_COMPONENT_PANEL_HORIZONTAL_PERCENT = 0;
|
||||
CONSOLE_COMPONENT_PANEL_VERTICAL_PERCENT = 0;
|
||||
CONSOLE_COMPONENT_ARROW_PERCENT = 0;
|
||||
CONSOLE_COMPONENT_AREA_TOP_PERCENT = 0;
|
||||
CONSOLE_COMPONENT_AREA_LEFT_PERCENT = 0;
|
||||
CONSOLE_COMPONENT_AREA_WIDTH_PERCENT = 0;
|
||||
CONSOLE_COMPONENT_AREA_HEIGHT_PERCENT = 0;
|
||||
|
||||
// Video panel.
|
||||
VIDEO_COMPONENT_VISIBLE = false;
|
||||
VIDEO_COMPONENT_HAS_PANEL = false;
|
||||
VIDEO_COMPONENT_HAS_ARROW = false;
|
||||
VIDEO_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
VIDEO_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
VIDEO_COMPONENT_PANEL_HORIZONTAL_PERCENT = 0;
|
||||
VIDEO_COMPONENT_PANEL_VERTICAL_PERCENT = 0;
|
||||
VIDEO_COMPONENT_ARROW_PERCENT = 0;
|
||||
VIDEO_COMPONENT_AREA_TOP_PERCENT = 0;
|
||||
VIDEO_COMPONENT_AREA_LEFT_PERCENT = 0;
|
||||
VIDEO_COMPONENT_AREA_WIDTH_PERCENT = 0;
|
||||
VIDEO_COMPONENT_AREA_HEIGHT_PERCENT = 0;
|
||||
|
||||
// Audio panel.
|
||||
AUDIO_COMPONENT_VISIBLE = false;
|
||||
AUDIO_COMPONENT_HAS_PANEL = false;
|
||||
AUDIO_COMPONENT_HAS_ARROW = false;
|
||||
AUDIO_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
AUDIO_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
AUDIO_COMPONENT_PANEL_HORIZONTAL_PERCENT = 0;
|
||||
AUDIO_COMPONENT_PANEL_VERTICAL_PERCENT = 0;
|
||||
AUDIO_COMPONENT_ARROW_PERCENT = 0;
|
||||
AUDIO_COMPONENT_AREA_TOP_PERCENT = 0;
|
||||
AUDIO_COMPONENT_AREA_LEFT_PERCENT = 0;
|
||||
AUDIO_COMPONENT_AREA_WIDTH_PERCENT = 0;
|
||||
AUDIO_COMPONENT_AREA_HEIGHT_PERCENT = 0;
|
||||
|
||||
// LED panel.
|
||||
LED_COMPONENT_VISIBLE = false;
|
||||
LED_COMPONENT_HAS_PANEL = false;
|
||||
LED_COMPONENT_HAS_ARROW = false;
|
||||
LED_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
LED_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
LED_COMPONENT_PANEL_HORIZONTAL_PERCENT = 0;
|
||||
LED_COMPONENT_PANEL_VERTICAL_PERCENT = 0;
|
||||
LED_COMPONENT_ARROW_PERCENT = 0;
|
||||
LED_COMPONENT_AREA_TOP_PERCENT = 0;
|
||||
LED_COMPONENT_AREA_LEFT_PERCENT = 0;
|
||||
LED_COMPONENT_AREA_WIDTH_PERCENT = 0;
|
||||
LED_COMPONENT_AREA_HEIGHT_PERCENT = 0;
|
||||
|
||||
// Flash memory panel.
|
||||
FLASH_MEMORY_COMPONENT_VISIBLE = false;
|
||||
FLASH_MEMORY_COMPONENT_HAS_PANEL = false;
|
||||
FLASH_MEMORY_COMPONENT_HAS_ARROW = false;
|
||||
FLASH_MEMORY_COMPONENT_PANEL_ALWAYS_VISIBLE = false;
|
||||
FLASH_MEMORY_COMPONENT_PANEL_ORIENTATION = VALUE_TOP;
|
||||
FLASH_MEMORY_COMPONENT_PANEL_HORIZONTAL_PERCENT = 0;
|
||||
FLASH_MEMORY_COMPONENT_PANEL_VERTICAL_PERCENT = 0;
|
||||
FLASH_MEMORY_COMPONENT_ARROW_PERCENT = 0;
|
||||
FLASH_MEMORY_COMPONENT_AREA_TOP_PERCENT = 0;
|
||||
FLASH_MEMORY_COMPONENT_AREA_LEFT_PERCENT = 0;
|
||||
FLASH_MEMORY_COMPONENT_AREA_WIDTH_PERCENT = 0;
|
||||
FLASH_MEMORY_COMPONENT_AREA_HEIGHT_PERCENT = 0;
|
||||
|
||||
// Capabilities
|
||||
SUPPORTS_VIDEO_BRIGHTNESS;
|
||||
|
||||
// Device information.
|
||||
#deviceType;
|
||||
#platformName;
|
||||
#serialNumber;
|
||||
#ubootVersion;
|
||||
#kernelVersion;
|
||||
#deyVersion;
|
||||
#moduleVariant;
|
||||
#boardVariant;
|
||||
#boardID;
|
||||
#mcaHWVersion;
|
||||
#mcaFWVersion;
|
||||
#ethernetMAC;
|
||||
#ethernetIP;
|
||||
#wifiMAC;
|
||||
#wifiIP;
|
||||
#bluetoothMAC;
|
||||
#memoryTotal;
|
||||
#flashSize;
|
||||
#videoResolution;
|
||||
#sampleRate;
|
||||
#numSamplesUpload;
|
||||
|
||||
// Class constructor.
|
||||
constructor(deviceType, platformName, deviceData) {
|
||||
this.#deviceType = deviceType;
|
||||
this.#platformName = platformName;
|
||||
this.#initDevice(deviceData);
|
||||
}
|
||||
|
||||
// Initializes the device with the provided data.
|
||||
#initDevice(deviceData) {
|
||||
this.#ubootVersion = deviceData[ID_UBOOT_VERSION];
|
||||
this.#serialNumber = deviceData[ID_SERIAL_NUMBER];
|
||||
this.#kernelVersion = deviceData[ID_KERNEL_VERSION];
|
||||
this.#deyVersion = deviceData[ID_DEY_VERSION];
|
||||
this.#moduleVariant = deviceData[ID_MODULE_VARIANT];
|
||||
this.#boardVariant = deviceData[ID_BOARD_VARIANT];
|
||||
this.#boardID = deviceData[ID_BOARD_ID];
|
||||
this.#mcaHWVersion = deviceData[ID_MCA_HW_VERSION];
|
||||
this.#mcaFWVersion = deviceData[ID_MCA_FW_VERSION];
|
||||
this.#ethernetMAC = deviceData[ID_ETHERNET_MAC];
|
||||
this.#ethernetIP = deviceData[ID_ETHERNET_IP];
|
||||
this.#wifiMAC = deviceData[ID_WIFI_MAC];
|
||||
this.#wifiIP = deviceData[ID_WIFI_IP];
|
||||
this.#bluetoothMAC = deviceData[ID_BLUETOOTH_MAC];
|
||||
this.#memoryTotal = deviceData[ID_MEMORY_TOTAL];
|
||||
this.#flashSize = deviceData[ID_FLASH_SIZE];
|
||||
this.#videoResolution = deviceData[ID_VIDEO_RESOLUTION];
|
||||
this.#sampleRate = deviceData[ID_SAMPLE_RATE];
|
||||
this.#numSamplesUpload = deviceData[ID_NUM_SAMPLES_UPLOAD];
|
||||
}
|
||||
|
||||
refreshIPs(eth_ip, wifi_ip) {
|
||||
this.#ethernetIP = eth_ip;
|
||||
this.#wifiIP = wifi_ip;
|
||||
}
|
||||
|
||||
// Returns the device type.
|
||||
getDeviceType() {
|
||||
return this.#deviceType;
|
||||
}
|
||||
|
||||
// Returns the platform name.
|
||||
getPlatformName() {
|
||||
return this.#platformName;
|
||||
}
|
||||
|
||||
// Returns the device serial number.
|
||||
getSerialNumber() {
|
||||
return this.#serialNumber;
|
||||
}
|
||||
|
||||
// Returns the board image file name.
|
||||
getBoardImage() {
|
||||
return this.BOARD_IMAGE;
|
||||
}
|
||||
|
||||
// Returns the board image scale.
|
||||
getBoardImageScale() {
|
||||
return this.BOARD_IMAGE_SCALE;
|
||||
}
|
||||
|
||||
// Returns the device U-Boot version.
|
||||
getUbootVersion() {
|
||||
return this.#ubootVersion;
|
||||
}
|
||||
|
||||
// Returns the device Kernel version.
|
||||
getKernelVersion() {
|
||||
return this.#kernelVersion;
|
||||
}
|
||||
|
||||
// Returns the device DEY version.
|
||||
getDEYVersion() {
|
||||
return this.#deyVersion;
|
||||
}
|
||||
|
||||
// Returns the device module variant.
|
||||
getModuleVariant() {
|
||||
return this.#moduleVariant;
|
||||
}
|
||||
|
||||
// Returns the device board variant.
|
||||
getBoardVariant() {
|
||||
return this.#boardVariant;
|
||||
}
|
||||
|
||||
// Returns the device board ID.
|
||||
getBoardID() {
|
||||
return this.#boardID;
|
||||
}
|
||||
|
||||
// Returns the device MCA hardware version.
|
||||
getMCAHWVersion() {
|
||||
return this.#mcaHWVersion;
|
||||
}
|
||||
|
||||
// Returns the device MCA firmware version.
|
||||
getMCAFWVersion() {
|
||||
return this.#mcaFWVersion;
|
||||
}
|
||||
|
||||
// Returns the device Ethernet MAC address.
|
||||
getEthernetMAC() {
|
||||
return this.#ethernetMAC;
|
||||
}
|
||||
|
||||
// Returns the device Ethernet IP address.
|
||||
getEthernetIP() {
|
||||
return this.#ethernetIP;
|
||||
}
|
||||
|
||||
// Returns the device WiFi MAC address.
|
||||
getWifiMAC() {
|
||||
return this.#wifiMAC;
|
||||
}
|
||||
|
||||
// Returns the device WiFi IP address.
|
||||
getWifiIP() {
|
||||
return this.#wifiIP;
|
||||
}
|
||||
|
||||
// Returns the device Bluetooth MAC address.
|
||||
getBluetoothMAC() {
|
||||
return this.#bluetoothMAC;
|
||||
}
|
||||
|
||||
// Returns the device total memory.
|
||||
getMemoryTotal() {
|
||||
return this.#memoryTotal;
|
||||
}
|
||||
|
||||
// Returns the device flash size.
|
||||
getFlashSize() {
|
||||
return this.#flashSize;
|
||||
}
|
||||
|
||||
// Returns the video resolution.
|
||||
getVideoResolution() {
|
||||
return this.#videoResolution;
|
||||
}
|
||||
|
||||
// Returns the sample rate.
|
||||
getSampleRate() {
|
||||
return this.#sampleRate;
|
||||
}
|
||||
|
||||
// Returns the number of samples to upload each batch.
|
||||
getNumSamplesUpload() {
|
||||
return this.#numSamplesUpload;
|
||||
}
|
||||
|
||||
// Returns the CPU panel data.
|
||||
getCPUComponentData() {
|
||||
return JSON.parse(TEMPLATE_COMPONENT_DATA.format(this.CPU_COMPONENT_VISIBLE,
|
||||
this.CPU_COMPONENT_HAS_PANEL,
|
||||
this.CPU_COMPONENT_HAS_ARROW,
|
||||
this.CPU_COMPONENT_PANEL_ALWAYS_VISIBLE,
|
||||
this.CPU_COMPONENT_PANEL_ORIENTATION,
|
||||
this.CPU_COMPONENT_PANEL_HORIZONTAL_PERCENT,
|
||||
this.CPU_COMPONENT_PANEL_VERTICAL_PERCENT,
|
||||
this.CPU_COMPONENT_ARROW_PERCENT,
|
||||
this.CPU_COMPONENT_AREA_TOP_PERCENT,
|
||||
this.CPU_COMPONENT_AREA_LEFT_PERCENT,
|
||||
this.CPU_COMPONENT_AREA_WIDTH_PERCENT,
|
||||
this.CPU_COMPONENT_AREA_HEIGHT_PERCENT));
|
||||
}
|
||||
|
||||
// Returns the Memory panel data.
|
||||
getMemoryComponentData() {
|
||||
return JSON.parse(TEMPLATE_COMPONENT_DATA.format(this.MEMORY_COMPONENT_VISIBLE,
|
||||
this.MEMORY_COMPONENT_HAS_PANEL,
|
||||
this.MEMORY_COMPONENT_HAS_ARROW,
|
||||
this.MEMORY_COMPONENT_PANEL_ALWAYS_VISIBLE,
|
||||
this.MEMORY_COMPONENT_PANEL_ORIENTATION,
|
||||
this.MEMORY_COMPONENT_PANEL_HORIZONTAL_PERCENT,
|
||||
this.MEMORY_COMPONENT_PANEL_VERTICAL_PERCENT,
|
||||
this.MEMORY_COMPONENT_ARROW_PERCENT,
|
||||
this.MEMORY_COMPONENT_AREA_TOP_PERCENT,
|
||||
this.MEMORY_COMPONENT_AREA_LEFT_PERCENT,
|
||||
this.MEMORY_COMPONENT_AREA_WIDTH_PERCENT,
|
||||
this.MEMORY_COMPONENT_AREA_HEIGHT_PERCENT));
|
||||
}
|
||||
|
||||
// Returns the WiFi panel data.
|
||||
getWifiBtComponentData() {
|
||||
return JSON.parse(TEMPLATE_COMPONENT_DATA.format(this.WIFI_BT_COMPONENT_VISIBLE,
|
||||
this.WIFI_BT_COMPONENT_HAS_PANEL,
|
||||
this.WIFI_BT_COMPONENT_HAS_ARROW,
|
||||
this.WIFI_BT_COMPONENT_PANEL_ALWAYS_VISIBLE,
|
||||
this.WIFI_BT_COMPONENT_PANEL_ORIENTATION,
|
||||
this.WIFI_BT_COMPONENT_PANEL_HORIZONTAL_PERCENT,
|
||||
this.WIFI_BT_COMPONENT_PANEL_VERTICAL_PERCENT,
|
||||
this.WIFI_BT_COMPONENT_ARROW_PERCENT,
|
||||
this.WIFI_BT_COMPONENT_AREA_TOP_PERCENT,
|
||||
this.WIFI_BT_COMPONENT_AREA_LEFT_PERCENT,
|
||||
this.WIFI_BT_COMPONENT_AREA_WIDTH_PERCENT,
|
||||
this.WIFI_BT_COMPONENT_AREA_HEIGHT_PERCENT));
|
||||
}
|
||||
|
||||
// Returns the Ethernet panel data.
|
||||
getEthernetComponentData() {
|
||||
return JSON.parse(TEMPLATE_COMPONENT_DATA.format(this.ETHERNET_COMPONENT_VISIBLE,
|
||||
this.ETHERNET_COMPONENT_HAS_PANEL,
|
||||
this.ETHERNET_COMPONENT_HAS_ARROW,
|
||||
this.ETHERNET_COMPONENT_PANEL_ALWAYS_VISIBLE,
|
||||
this.ETHERNET_COMPONENT_PANEL_ORIENTATION,
|
||||
this.ETHERNET_COMPONENT_PANEL_HORIZONTAL_PERCENT,
|
||||
this.ETHERNET_COMPONENT_PANEL_VERTICAL_PERCENT,
|
||||
this.ETHERNET_COMPONENT_ARROW_PERCENT,
|
||||
this.ETHERNET_COMPONENT_AREA_TOP_PERCENT,
|
||||
this.ETHERNET_COMPONENT_AREA_LEFT_PERCENT,
|
||||
this.ETHERNET_COMPONENT_AREA_WIDTH_PERCENT,
|
||||
this.ETHERNET_COMPONENT_AREA_HEIGHT_PERCENT));
|
||||
}
|
||||
|
||||
// Returns the Console panel data.
|
||||
getConsoleComponentData() {
|
||||
return JSON.parse(TEMPLATE_COMPONENT_DATA.format(this.CONSOLE_COMPONENT_VISIBLE,
|
||||
this.CONSOLE_COMPONENT_HAS_PANEL,
|
||||
this.CONSOLE_COMPONENT_HAS_ARROW,
|
||||
this.CONSOLE_COMPONENT_PANEL_ALWAYS_VISIBLE,
|
||||
this.CONSOLE_COMPONENT_PANEL_ORIENTATION,
|
||||
this.CONSOLE_COMPONENT_PANEL_HORIZONTAL_PERCENT,
|
||||
this.CONSOLE_COMPONENT_PANEL_VERTICAL_PERCENT,
|
||||
this.CONSOLE_COMPONENT_ARROW_PERCENT,
|
||||
this.CONSOLE_COMPONENT_AREA_TOP_PERCENT,
|
||||
this.CONSOLE_COMPONENT_AREA_LEFT_PERCENT,
|
||||
this.CONSOLE_COMPONENT_AREA_WIDTH_PERCENT,
|
||||
this.CONSOLE_COMPONENT_AREA_HEIGHT_PERCENT));
|
||||
}
|
||||
|
||||
// Returns the Video panel data.
|
||||
getVideoComponentData() {
|
||||
return JSON.parse(TEMPLATE_COMPONENT_DATA.format(this.VIDEO_COMPONENT_VISIBLE,
|
||||
this.VIDEO_COMPONENT_HAS_PANEL,
|
||||
this.VIDEO_COMPONENT_HAS_ARROW,
|
||||
this.VIDEO_COMPONENT_PANEL_ALWAYS_VISIBLE,
|
||||
this.VIDEO_COMPONENT_PANEL_ORIENTATION,
|
||||
this.VIDEO_COMPONENT_PANEL_HORIZONTAL_PERCENT,
|
||||
this.VIDEO_COMPONENT_PANEL_VERTICAL_PERCENT,
|
||||
this.VIDEO_COMPONENT_ARROW_PERCENT,
|
||||
this.VIDEO_COMPONENT_AREA_TOP_PERCENT,
|
||||
this.VIDEO_COMPONENT_AREA_LEFT_PERCENT,
|
||||
this.VIDEO_COMPONENT_AREA_WIDTH_PERCENT,
|
||||
this.VIDEO_COMPONENT_AREA_HEIGHT_PERCENT));
|
||||
}
|
||||
|
||||
// Returns the Audio panel data.
|
||||
getAudioComponentData() {
|
||||
return JSON.parse(TEMPLATE_COMPONENT_DATA.format(this.AUDIO_COMPONENT_VISIBLE,
|
||||
this.AUDIO_COMPONENT_HAS_PANEL,
|
||||
this.AUDIO_COMPONENT_HAS_ARROW,
|
||||
this.AUDIO_COMPONENT_PANEL_ALWAYS_VISIBLE,
|
||||
this.AUDIO_COMPONENT_PANEL_ORIENTATION,
|
||||
this.AUDIO_COMPONENT_PANEL_HORIZONTAL_PERCENT,
|
||||
this.AUDIO_COMPONENT_PANEL_VERTICAL_PERCENT,
|
||||
this.AUDIO_COMPONENT_ARROW_PERCENT,
|
||||
this.AUDIO_COMPONENT_AREA_TOP_PERCENT,
|
||||
this.AUDIO_COMPONENT_AREA_LEFT_PERCENT,
|
||||
this.AUDIO_COMPONENT_AREA_WIDTH_PERCENT,
|
||||
this.AUDIO_COMPONENT_AREA_HEIGHT_PERCENT));
|
||||
}
|
||||
|
||||
// Returns the LED panel data.
|
||||
getLEDComponentData() {
|
||||
return JSON.parse(TEMPLATE_COMPONENT_DATA.format(this.LED_COMPONENT_VISIBLE,
|
||||
this.LED_COMPONENT_HAS_PANEL,
|
||||
this.LED_COMPONENT_HAS_ARROW,
|
||||
this.LED_COMPONENT_PANEL_ALWAYS_VISIBLE,
|
||||
this.LED_COMPONENT_PANEL_ORIENTATION,
|
||||
this.LED_COMPONENT_PANEL_HORIZONTAL_PERCENT,
|
||||
this.LED_COMPONENT_PANEL_VERTICAL_PERCENT,
|
||||
this.LED_COMPONENT_ARROW_PERCENT,
|
||||
this.LED_COMPONENT_AREA_TOP_PERCENT,
|
||||
this.LED_COMPONENT_AREA_LEFT_PERCENT,
|
||||
this.LED_COMPONENT_AREA_WIDTH_PERCENT,
|
||||
this.LED_COMPONENT_AREA_HEIGHT_PERCENT));
|
||||
}
|
||||
|
||||
// Returns the flash memory panel data.
|
||||
getFlashMemoryComponentData() {
|
||||
return JSON.parse(TEMPLATE_COMPONENT_DATA.format(this.FLASH_MEMORY_COMPONENT_VISIBLE,
|
||||
this.FLASH_MEMORY_COMPONENT_HAS_PANEL,
|
||||
this.FLASH_MEMORY_COMPONENT_HAS_ARROW,
|
||||
this.FLASH_MEMORY_COMPONENT_PANEL_ALWAYS_VISIBLE,
|
||||
this.FLASH_MEMORY_COMPONENT_PANEL_ORIENTATION,
|
||||
this.FLASH_MEMORY_COMPONENT_PANEL_HORIZONTAL_PERCENT,
|
||||
this.FLASH_MEMORY_COMPONENT_PANEL_VERTICAL_PERCENT,
|
||||
this.FLASH_MEMORY_COMPONENT_ARROW_PERCENT,
|
||||
this.FLASH_MEMORY_COMPONENT_AREA_TOP_PERCENT,
|
||||
this.FLASH_MEMORY_COMPONENT_AREA_LEFT_PERCENT,
|
||||
this.FLASH_MEMORY_COMPONENT_AREA_WIDTH_PERCENT,
|
||||
this.FLASH_MEMORY_COMPONENT_AREA_HEIGHT_PERCENT));
|
||||
}
|
||||
|
||||
// Returns whether the device supports video brightness or not.
|
||||
supportsVideoBrightness() {
|
||||
return this.SUPPORTS_VIDEO_BRIGHTNESS;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,699 @@
|
|||
/*
|
||||
* Copyright 2022, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
// Constants.
|
||||
const ID_CURRENT_DIRECTORY = "current_directory";
|
||||
const ID_FILE_SYSTEM_CONTAINER = "filesystem_container";
|
||||
const ID_FILE_SYSTEM_CREATE_DIR_BUTTON = "filesystem_create_directory_button";
|
||||
const ID_FILE_SYSTEM_DIR_NAME = "filesystem_directory_name";
|
||||
const ID_FILE_SYSTEM_DIR_NAME_BUTTON = "filesystem_directory_name_button";
|
||||
const ID_FILE_SYSTEM_DIR_NAME_ERROR = "filesystem_directory_name_error";
|
||||
const ID_FILE_SYSTEM_DIR_NAME_PANEL = "filesystem_dir_name_panel";
|
||||
const ID_FILE_SYSTEM_DOWNLOAD_FILE_BUTTON = "filesystem_download_file_button";
|
||||
const ID_FILE_SYSTEM_HEADER = "filesystem_header";
|
||||
const ID_FILE_SYSTEM_HOVER_BACKGROUND = "filesystem_hover_background";
|
||||
const ID_FILE_SYSTEM_ITEMS_CONTAINER = "filesystem_items_container";
|
||||
const ID_FILE_SYSTEM_ITEMS_HEADER = "filesystem_items_header";
|
||||
const ID_FILE_SYSTEM_LOADING = "filesystem_loading";
|
||||
const ID_FILE_SYSTEM_PANEL = "filesystem_panel";
|
||||
const ID_FILE_SYSTEM_REMOVE_FILE_BUTTON = "filesystem_remove_file_button";
|
||||
const ID_FILE_SYSTEM_SELECT_FILE_BUTTON = "filesystem_select_file_button";
|
||||
const ID_FILE_SYSTEM_UPLOAD_FILE_BUTTON = "filesystem_upload_file_button";
|
||||
const ID_FILE_SYSTEM_TOOLBAR = "filesystem_toolbar";
|
||||
const ID_FILE_SYSTEM_TOOLBAR_BUTTONS_CONTAINER = "filesystem_toolbar_buttons_container";
|
||||
const ID_FILE_TO_UPLOAD = "file_to_upload";
|
||||
|
||||
const CLASS_FA_FILE = "fa-file";
|
||||
const CLASS_FILE_SYSTEM_BUTTON_DISABLED = "filesystem-button-disabled";
|
||||
const CLASS_FILE_SYSTEM_DIR_NAME_BUTTON_DISABLED = "filesystem-dir-name-button-disabled";
|
||||
const CLASS_FILE_SYSTEM_DIR_NAME_INPUT_ERROR = "filesystem-dir-name-input-error";
|
||||
const CLASS_FILE_SYSTEM_ENTRY_SELECTED = "filesystem-entry-selected";
|
||||
|
||||
const FS_TYPE_FILE = "file";
|
||||
const FS_TYPE_DIRECTORY = "dir";
|
||||
|
||||
const TITLE_CONFIRM_REMOVE = "Confirm Remove";
|
||||
|
||||
const MESSAGE_CONFIRM_REMOVE = "Are you sure you want to remove the selected file?";
|
||||
|
||||
const PREFIX_FS = "fs_";
|
||||
|
||||
const REGEX_DIRECTORY_NAME = '^[^\\s^\x00-\x1f\\?*:"";<>|\\/.][^\x00-\x1f\\?*:"";<>|\\/]*[^\\s^\x00-\x1f\\?*:"";<>|\\/.]+$';
|
||||
|
||||
const TEMPLATE_DIRECTORY = "" +
|
||||
"<div id='fs_{0}' class='filesystem-entry' title='{1}' onclick='listDirectory(\"{2}\", filters=\"{3}\")'>" +
|
||||
" <div class='fas fa-folder fa-lg filesystem-entry-icon'></div>" +
|
||||
" <div class='filesystem-entry-name'>{4}</div>" +
|
||||
" <div class='filesystem-entry-size'></div>" +
|
||||
" <div class='filesystem-entry-last-modified'>{5}</div>" +
|
||||
"</div>";
|
||||
const TEMPLATE_FILE = "" +
|
||||
"<div id='fs_{0}' class='filesystem-entry' title='{1}' onclick='selectFileSystemEntry(\"fs_{2}\", filters=\"{3}\")' ondblclick='downloadFile(\"{4}\")'>" +
|
||||
" <div class='fas fa-file fa-lg filesystem-entry-icon'></div>" +
|
||||
" <div class='filesystem-entry-name'>{5}</div>" +
|
||||
" <div class='filesystem-entry-size'>{6}</div>" +
|
||||
" <div class='filesystem-entry-last-modified'>{7}</div>" +
|
||||
"</div>";
|
||||
|
||||
const ERROR_DIR_NAME_EMPTY = "Directory name cannot be empty.";
|
||||
const ERROR_DIR_NAME_INVALID = "The entered name is not valid.";
|
||||
|
||||
const ROOT_DIRECTORY = "/";
|
||||
|
||||
// Variables.
|
||||
var currentDirectory = null;
|
||||
var selectedFileSystemEntry = null;
|
||||
var filesystemResizeObserver = null;
|
||||
|
||||
// Opens the file system panel.
|
||||
function openFileSystem(showButtons=true, filters="") {
|
||||
// Check if the file system is showing.
|
||||
if (isFileSystemShowing())
|
||||
return;
|
||||
// Reset current directory.
|
||||
currentDirectory = null;
|
||||
$("#" + ID_CURRENT_DIRECTORY).text("");
|
||||
// Unselect all entries.
|
||||
unselectFileSystemEntries();
|
||||
// Clear all the file system entries.
|
||||
clearFileSystemEntries();
|
||||
// Setup resize observer.
|
||||
if (filesystemResizeObserver == null || filesystemResizeObserver == "undefined") {
|
||||
filesystemResizeObserver = new ResizeObserver((entries) => {
|
||||
resizeFileSystemElements();
|
||||
})
|
||||
filesystemResizeObserver.observe(document.getElementById(ID_FILE_SYSTEM_CONTAINER));
|
||||
}
|
||||
// Resize filesystem elements.
|
||||
resizeFileSystemElements();
|
||||
// Show the file system.
|
||||
var fileSystemContainer = document.getElementById(ID_FILE_SYSTEM_PANEL);
|
||||
fileSystemContainer.style.visibility = "visible";
|
||||
if (!showButtons || is_local_access()) {
|
||||
document.getElementById(ID_FILE_SYSTEM_DOWNLOAD_FILE_BUTTON).style.display = "none";
|
||||
document.getElementById(ID_FILE_SYSTEM_UPLOAD_FILE_BUTTON).style.display = "none";
|
||||
document.getElementById(ID_FILE_SYSTEM_TOOLBAR_BUTTONS_CONTAINER).style.width = "auto";
|
||||
}
|
||||
if (!showButtons) {
|
||||
document.getElementById(ID_FILE_SYSTEM_CREATE_DIR_BUTTON).style.display = "none";
|
||||
document.getElementById(ID_FILE_SYSTEM_REMOVE_FILE_BUTTON).style.display = "none";
|
||||
}
|
||||
// List root directory.
|
||||
listDirectory(ROOT_DIRECTORY, filters=filters);
|
||||
}
|
||||
|
||||
// Returns whether the file system window is open or not.
|
||||
function isFileSystemShowing() {
|
||||
// Sanity checks.
|
||||
if (!isDashboardShowing() && !isManagementShowing())
|
||||
return false;
|
||||
// Initialize variables.
|
||||
var fileSystemContainer = document.getElementById(ID_FILE_SYSTEM_PANEL);
|
||||
// Return visibility.
|
||||
return fileSystemContainer.style.visibility == "visible";
|
||||
}
|
||||
|
||||
// Closes the file system panel.
|
||||
function closeFileSystem() {
|
||||
// Check if the file system is showing.
|
||||
if (!isFileSystemShowing())
|
||||
return;
|
||||
// Hide the loading panel.
|
||||
showFileSystemLoading(false);
|
||||
// Hide the file system panel.
|
||||
var fileSystemContainer = document.getElementById(ID_FILE_SYSTEM_PANEL);
|
||||
fileSystemContainer.style.visibility = "collapse";
|
||||
}
|
||||
|
||||
// Resizes the file system elements.
|
||||
function resizeFileSystemElements() {
|
||||
// If file system is not showing just return.
|
||||
if (!isFileSystemShowing())
|
||||
return;
|
||||
// Initialize variables.
|
||||
var filesystemContainer = document.getElementById(ID_FILE_SYSTEM_CONTAINER);
|
||||
var filesystemHeader = document.getElementById(ID_FILE_SYSTEM_HEADER);
|
||||
var filesystemToolbar = document.getElementById(ID_FILE_SYSTEM_TOOLBAR);
|
||||
var filesystemHoverBackground = document.getElementById(ID_FILE_SYSTEM_HOVER_BACKGROUND);
|
||||
var filesystemItemsHeader = document.getElementById(ID_FILE_SYSTEM_ITEMS_HEADER);
|
||||
var filesystemItemsContainer = document.getElementById(ID_FILE_SYSTEM_ITEMS_CONTAINER);
|
||||
var containerHeight = filesystemContainer.clientHeight;
|
||||
var headerHeight = filesystemHeader.clientHeight;
|
||||
var toolbarHeight = filesystemToolbar.clientHeight;
|
||||
var itemsHeaderHeight = filesystemItemsHeader.clientHeight;
|
||||
// Set correct heights.
|
||||
filesystemHoverBackground.style.height = (containerHeight - headerHeight).toString() + "px";
|
||||
filesystemItemsContainer.style.height = (containerHeight - headerHeight - toolbarHeight - itemsHeaderHeight).toString() + "px";
|
||||
}
|
||||
|
||||
// Shows/hides the file system loading panel.
|
||||
function showFileSystemLoading(visible) {
|
||||
// Initialize variables.
|
||||
var fileSystemHoverBackground = document.getElementById(ID_FILE_SYSTEM_HOVER_BACKGROUND);
|
||||
var fileSystemLoading = document.getElementById(ID_FILE_SYSTEM_LOADING);
|
||||
// Apply visibility.
|
||||
if (visible && isFileSystemShowing()) {
|
||||
fileSystemHoverBackground.style.visibility = "visible";
|
||||
fileSystemLoading.style.visibility = "visible";
|
||||
} else {
|
||||
fileSystemHoverBackground.style.visibility = "hidden";
|
||||
fileSystemLoading.style.visibility = "hidden";
|
||||
}
|
||||
}
|
||||
|
||||
// Clears all the file system entries.
|
||||
function clearFileSystemEntries() {
|
||||
// Initialize variables.
|
||||
var fileSystemEntriesDiv = document.getElementById(ID_FILE_SYSTEM_ITEMS_CONTAINER);
|
||||
// Clear all file system HTML entries.
|
||||
while (fileSystemEntriesDiv.firstChild)
|
||||
fileSystemEntriesDiv.removeChild(fileSystemEntriesDiv.lastChild);
|
||||
}
|
||||
|
||||
// Enables/disabled the file system buttons.
|
||||
function enableFileSystemButtons(enable, filters="") {
|
||||
// Initialize variables.
|
||||
var downloadButton = document.getElementById(ID_FILE_SYSTEM_DOWNLOAD_FILE_BUTTON);
|
||||
var removeButton = document.getElementById(ID_FILE_SYSTEM_REMOVE_FILE_BUTTON);
|
||||
var selectFwButton = document.getElementById(ID_FILE_SYSTEM_SELECT_FILE_BUTTON);
|
||||
// Apply enable state.
|
||||
if (!enable) {
|
||||
if (removeButton) {
|
||||
removeButton.disabled = true;
|
||||
removeButton.classList.add(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||
}
|
||||
if (downloadButton) {
|
||||
downloadButton.disabled = true;
|
||||
downloadButton.classList.add(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||
}
|
||||
if (selectFwButton) {
|
||||
selectFwButton.disabled = true;
|
||||
selectFwButton.classList.add(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||
}
|
||||
} else {
|
||||
if (removeButton) {
|
||||
removeButton.disabled = false;
|
||||
removeButton.classList.remove(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||
}
|
||||
if (downloadButton) {
|
||||
downloadButton.disabled = false;
|
||||
downloadButton.classList.remove(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||
}
|
||||
if (selectFwButton) {
|
||||
enable = false;
|
||||
if (filters) {
|
||||
var filePath = selectedFileSystemEntry.substring(PREFIX_FS.length);
|
||||
var filter_list = filters.split(",");
|
||||
for (var i = 0; i < filter_list.length; i++) {
|
||||
if (filePath.endsWith(filter_list[i])) {
|
||||
enable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!filters || enable) {
|
||||
selectFwButton.disabled = false;
|
||||
selectFwButton.classList.remove(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Downloads the selected file.
|
||||
function selectFirmwareFile() {
|
||||
// Build file path.
|
||||
var filePath = selectedFileSystemEntry.substring(PREFIX_FS.length);
|
||||
firmwareFileChanged(filePath);
|
||||
}
|
||||
|
||||
// Selects the given file system entry.
|
||||
function selectFileSystemEntry(entryID, filters="") {
|
||||
// Unselect all entries.
|
||||
unselectFileSystemEntries();
|
||||
// Set selected style to the selected device div.
|
||||
var entryElement = document.getElementById(entryID)
|
||||
if (entryElement != null)
|
||||
entryElement.classList.add(CLASS_FILE_SYSTEM_ENTRY_SELECTED);
|
||||
// Save selected entry.
|
||||
selectedFileSystemEntry = entryID;
|
||||
// Enable buttons.
|
||||
enableFileSystemButtons(true, filters=filters);
|
||||
}
|
||||
|
||||
// Unselects all the file system entries.
|
||||
function unselectFileSystemEntries() {
|
||||
// Initialize variables.
|
||||
var fileSystemEntriesDiv = document.getElementById(ID_FILE_SYSTEM_ITEMS_CONTAINER);
|
||||
var children = fileSystemEntriesDiv.children;
|
||||
// Remove selected class from all entries.
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var entry = children[i].children[0];
|
||||
entry.classList.remove(CLASS_FILE_SYSTEM_ENTRY_SELECTED);
|
||||
}
|
||||
// Reset selected entry.
|
||||
selectedFileSystemEntry = null;
|
||||
// Disable buttons.
|
||||
enableFileSystemButtons(false);
|
||||
}
|
||||
|
||||
// Lists the contents of the given directory.
|
||||
function listDirectory(directory, filters="") {
|
||||
// Build path.
|
||||
var path = currentDirectory;
|
||||
if (path == null || currentDirectory == directory)
|
||||
path = directory;
|
||||
else {
|
||||
if (directory.endsWith("..")) {
|
||||
// Check if last slash must be removed.
|
||||
if (path.endsWith("/") && path.length > ROOT_DIRECTORY.length)
|
||||
path = path.substring(0, path.lastIndexOf("/"));
|
||||
// Move one directory up.
|
||||
path = path.substring(0, path.lastIndexOf("/"));
|
||||
if (path == "")
|
||||
path = ROOT_DIRECTORY;
|
||||
} else {
|
||||
if (!path.endsWith("/"))
|
||||
path = path + "/"
|
||||
path = path + directory;
|
||||
}
|
||||
}
|
||||
// Show loading panel.
|
||||
showFileSystemLoading(true);
|
||||
// Send request.
|
||||
$.post(
|
||||
"http://" + getServerAddress() + "/ajax/fs_list_directory",
|
||||
JSON.stringify({
|
||||
"directory": path,
|
||||
"filters": filters,
|
||||
}),
|
||||
function(data) {
|
||||
// Process only if the file system window is showing.
|
||||
if (!isFileSystemShowing())
|
||||
return;
|
||||
// Process answer.
|
||||
processListDirectoryResponse(data, filters=filters);
|
||||
}
|
||||
).fail(function(response) {
|
||||
// Process only if the file system window is showing.
|
||||
if (!isFileSystemShowing())
|
||||
return;
|
||||
// Process error.
|
||||
processAjaxErrorResponse(response);
|
||||
// Hide the loading status.
|
||||
showFileSystemLoading(false);
|
||||
});
|
||||
}
|
||||
|
||||
// Processes the list directory response.
|
||||
function processListDirectoryResponse(response, filters="") {
|
||||
// Check if there was any error in the request.
|
||||
if (checkErrorResponse(response, false)) {
|
||||
// Hide the loading status.
|
||||
showFileSystemLoading(false);
|
||||
// Do not continue.
|
||||
return;
|
||||
}
|
||||
// Unselect all entries.
|
||||
unselectFileSystemEntries();
|
||||
// Clear all file system entries.
|
||||
clearFileSystemEntries();
|
||||
// Set current directory.
|
||||
currentDirectory = response[ID_CURRENT_DIR];
|
||||
if (!currentDirectory.endsWith("/"))
|
||||
currentDirectory = currentDirectory + "/";
|
||||
$("#" + ID_CURRENT_DIRECTORY).text(currentDirectory);
|
||||
// Iterate over all the file system received entries.
|
||||
if (response[ID_FILES] != null && response[ID_FILES] != "undefined") {
|
||||
var fileSystemEntriesDiv = document.getElementById(ID_FILE_SYSTEM_ITEMS_CONTAINER);
|
||||
// Process response entries and create HTML elements.
|
||||
for (var entry of response[ID_FILES]) {
|
||||
var name = entry[ID_NAME].substring(currentDirectory.length);
|
||||
var lastModified = entry[ID_LAST_MODIFIED];
|
||||
if (lastModified == null || lastModified == "undefined" || lastModified == 0 || name == "..") {
|
||||
lastModified = "";
|
||||
} else {
|
||||
var date = new Date(0); // The 0 there is the key, which sets the date to the epoch
|
||||
date.setUTCSeconds(lastModified);
|
||||
lastModified = date.toLocaleString("en-US", { hour12:false });
|
||||
}
|
||||
var entryDiv = document.createElement("div");
|
||||
if (entry[ID_TYPE] == FS_TYPE_FILE)
|
||||
entryDiv.innerHTML = TEMPLATE_FILE.format(name, name, name, filters, name, name,
|
||||
sizeToHumanRead(entry[ID_SIZE]), lastModified);
|
||||
else if (entry[ID_TYPE] == FS_TYPE_DIRECTORY)
|
||||
entryDiv.innerHTML = TEMPLATE_DIRECTORY.format(name, name, name, filters, name, lastModified);
|
||||
if (entryDiv.innerHTML != null && entryDiv.innerHTML != "")
|
||||
fileSystemEntriesDiv.appendChild(entryDiv);
|
||||
}
|
||||
}
|
||||
// Hide the loading status.
|
||||
showFileSystemLoading(false);
|
||||
}
|
||||
|
||||
// Downloads the selected file.
|
||||
function downloadSelectedFile() {
|
||||
// Build file path.
|
||||
var filePath = selectedFileSystemEntry.substring(PREFIX_FS.length);
|
||||
// Execute the download action.
|
||||
downloadFile(filePath);
|
||||
}
|
||||
|
||||
// Attempts to download the given file name.
|
||||
function downloadFile(fileName) {
|
||||
// Build file path.
|
||||
var path = currentDirectory + fileName;
|
||||
// Show loading panel.
|
||||
showFileSystemLoading(true);
|
||||
// Prepare data.
|
||||
var data = JSON.stringify({
|
||||
"path": path
|
||||
});
|
||||
// Send request
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: "http://" + getServerAddress() + "/ajax/fs_download_file",
|
||||
data: data,
|
||||
cache: false,
|
||||
async: true,
|
||||
xhr: function() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 2) {
|
||||
if (xhr.status == 200)
|
||||
xhr.responseType = "blob";
|
||||
else
|
||||
xhr.responseType = "text";
|
||||
}
|
||||
};
|
||||
return xhr;
|
||||
},
|
||||
success: function(response) {
|
||||
// Process only if the file system window is showing.
|
||||
if (!isFileSystemShowing())
|
||||
return;
|
||||
// Process answer.
|
||||
processDownloadFileResponse(response);
|
||||
},
|
||||
error: function(response) {
|
||||
// Process only if the file system window is showing.
|
||||
if (!isFileSystemShowing())
|
||||
return;
|
||||
// Process error.
|
||||
processAjaxErrorResponse(response);
|
||||
// Hide the loading status.
|
||||
showFileSystemLoading(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Processes the download file response.
|
||||
function processDownloadFileResponse(response) {
|
||||
// Check if there was any error in the request.
|
||||
if (checkErrorResponse(response, false)) {
|
||||
// Hide the loading status.
|
||||
showFileSystemLoading(false);
|
||||
// Do not continue.
|
||||
return;
|
||||
}
|
||||
// Obtain file name.
|
||||
var fileName = selectedFileSystemEntry.substring(PREFIX_FS.length)
|
||||
// Convert the Byte Data to BLOB object.
|
||||
var blob = new Blob([response], { type: "application/octetstream" });
|
||||
// Check the Browser type and download the File.
|
||||
var isIE = false || !!document.documentMode;
|
||||
if (isIE) {
|
||||
window.navigator.msSaveBlob(blob, fileName);
|
||||
} else {
|
||||
var url = window.URL || window.webkitURL;
|
||||
link = url.createObjectURL(blob);
|
||||
var a = $("<a />");
|
||||
a.attr("download", fileName);
|
||||
a.attr("href", link);
|
||||
$("body").append(a);
|
||||
a[0].click();
|
||||
$("body").remove(a);
|
||||
}
|
||||
// Hide the loading status.
|
||||
showFileSystemLoading(false);
|
||||
}
|
||||
|
||||
// Asks user to confirm file removal.
|
||||
function askRemoveFile() {
|
||||
showConfirmDialog(TITLE_CONFIRM_REMOVE, MESSAGE_CONFIRM_REMOVE,
|
||||
function() {
|
||||
// Remove the file.
|
||||
removeSelectedFile();
|
||||
},
|
||||
function() {
|
||||
// Do nothing.
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Removes the selected file.
|
||||
function removeSelectedFile() {
|
||||
// Sanity checks.
|
||||
if (selectedFileSystemEntry == null)
|
||||
return;
|
||||
// Initialize variables.
|
||||
var isFile = false;
|
||||
var entryElement = document.getElementById(selectedFileSystemEntry);
|
||||
var iconElement = entryElement.children[0];
|
||||
// Check if it is a file.
|
||||
if (iconElement.classList.contains(CLASS_FA_FILE))
|
||||
isFile = true;
|
||||
// Execute action.
|
||||
removeFile(selectedFileSystemEntry.substring(PREFIX_FS.length), isFile);
|
||||
}
|
||||
|
||||
// Attempts to remove the given file name.
|
||||
function removeFile(fileName, isFile) {
|
||||
// Build file path.
|
||||
var path = currentDirectory + fileName;
|
||||
// Show loading panel.
|
||||
showFileSystemLoading(true);
|
||||
// Send request.
|
||||
$.post(
|
||||
"http://" + getServerAddress() + "/ajax/fs_remove_file",
|
||||
JSON.stringify({
|
||||
"path": path,
|
||||
"is_file": isFile
|
||||
}),
|
||||
function(data) {
|
||||
// Process only if the file system window is showing.
|
||||
if (!isFileSystemShowing())
|
||||
return;
|
||||
// Process answer.
|
||||
processRemoveFileResponse(data);
|
||||
}
|
||||
).fail(function(response) {
|
||||
// Process only if the file system window is showing.
|
||||
if (!isFileSystemShowing())
|
||||
return;
|
||||
// Process error.
|
||||
processAjaxErrorResponse(response);
|
||||
// Hide the loading status.
|
||||
showFileSystemLoading(false);
|
||||
});
|
||||
}
|
||||
|
||||
// Processes the remove file response.
|
||||
function processRemoveFileResponse(response) {
|
||||
// Check if there was any error in the request.
|
||||
if (checkErrorResponse(response, false)) {
|
||||
// Hide the loading status.
|
||||
showFileSystemLoading(false);
|
||||
} else {
|
||||
// List directory contents again.
|
||||
listDirectory(currentDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
// Opens the file browser.
|
||||
function openFileBrowser() {
|
||||
document.getElementById(ID_FILE_TO_UPLOAD).click();
|
||||
}
|
||||
|
||||
// Attempts to upload the given file.
|
||||
function uploadFile(file) {
|
||||
// Build file path.
|
||||
var path = currentDirectory + file.name;
|
||||
// Show loading panel.
|
||||
showFileSystemLoading(true);
|
||||
// Prepare data.
|
||||
var formData = new FormData();
|
||||
formData.append("path", path);
|
||||
formData.append("file", file);
|
||||
// Send request.
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: "http://" + getServerAddress() + "/ajax/fs_upload_file",
|
||||
data: formData,
|
||||
cache: false,
|
||||
async: true,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
enctype: 'multipart/form-data',
|
||||
success: function(response) {
|
||||
// Process only if the file system window is showing.
|
||||
if (!isFileSystemShowing())
|
||||
return;
|
||||
// Process answer.
|
||||
processUploadFileResponse(response);
|
||||
},
|
||||
error: function(response) {
|
||||
// Process only if the file system window is showing.
|
||||
if (!isFileSystemShowing())
|
||||
return;
|
||||
// Process error.
|
||||
processAjaxErrorResponse(response);
|
||||
// Hide the loading status.
|
||||
showFileSystemLoading(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Processes the upload file response.
|
||||
function processUploadFileResponse(response) {
|
||||
// Check if there was any error in the request.
|
||||
if (checkErrorResponse(response, false)) {
|
||||
// Hide the loading status.
|
||||
showFileSystemLoading(false);
|
||||
} else {
|
||||
// List directory contents again.
|
||||
listDirectory(currentDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
// Opens the directory name panel.
|
||||
function openDirectoryNamePanel() {
|
||||
// Initialize variables.
|
||||
var fileSystemDirName = document.getElementById(ID_FILE_SYSTEM_DIR_NAME);
|
||||
var fileSystemDirNameButton = document.getElementById(ID_FILE_SYSTEM_DIR_NAME_BUTTON);
|
||||
var fileSystemDirNameError = document.getElementById(ID_FILE_SYSTEM_DIR_NAME_ERROR);
|
||||
// Reset panel state.
|
||||
fileSystemDirName.value = "";
|
||||
fileSystemDirNameError.innerHTML = " ";
|
||||
fileSystemDirNameError.style.visibility = "hidden";
|
||||
if (!fileSystemDirNameButton.classList.contains(CLASS_FILE_SYSTEM_DIR_NAME_BUTTON_DISABLED))
|
||||
fileSystemDirNameButton.classList.add(CLASS_FILE_SYSTEM_DIR_NAME_BUTTON_DISABLED);
|
||||
if (fileSystemDirName.classList.contains(CLASS_FILE_SYSTEM_DIR_NAME_INPUT_ERROR))
|
||||
fileSystemDirName.classList.remove(CLASS_FILE_SYSTEM_DIR_NAME_INPUT_ERROR);
|
||||
// Show panel.
|
||||
showDirectoryNamePanel(true);
|
||||
}
|
||||
|
||||
// Closes the directory name panel.
|
||||
function closeDirectoryNamePanel() {
|
||||
showDirectoryNamePanel(false);
|
||||
}
|
||||
|
||||
// Opens the directory name panel.
|
||||
function showDirectoryNamePanel(visible) {
|
||||
// Initialize variables.
|
||||
var fileSystemDirNamePanel = document.getElementById(ID_FILE_SYSTEM_DIR_NAME_PANEL);
|
||||
var fileSystemDirNameError = document.getElementById(ID_FILE_SYSTEM_DIR_NAME_ERROR);
|
||||
// Apply visible state.
|
||||
if (visible && isFileSystemShowing())
|
||||
fileSystemDirNamePanel.style.visibility = "visible";
|
||||
else {
|
||||
fileSystemDirNamePanel.style.visibility = "hidden";
|
||||
fileSystemDirNameError.style.visibility = "hidden";
|
||||
}
|
||||
}
|
||||
|
||||
// Handles what happens when the "Create directory" button is pressed.
|
||||
function onCreateDirectory() {
|
||||
var fileSystemDirName = document.getElementById(ID_FILE_SYSTEM_DIR_NAME);
|
||||
var dirName = fileSystemDirName.value;
|
||||
createDirectory(dirName);
|
||||
}
|
||||
|
||||
// Validates the directory name.
|
||||
function validateDirectoryName(dirName) {
|
||||
// Initialize variables.
|
||||
var fileSystemDirName = document.getElementById(ID_FILE_SYSTEM_DIR_NAME);
|
||||
var fileSystemDirNameButton = document.getElementById(ID_FILE_SYSTEM_DIR_NAME_BUTTON);
|
||||
var fileSystemDirNameError = document.getElementById(ID_FILE_SYSTEM_DIR_NAME_ERROR);
|
||||
var isValid = true;
|
||||
var error = ERROR_DIR_NAME_INVALID;
|
||||
// Check if the directory name is valid.
|
||||
if (dirName == null || dirName == "") {
|
||||
isValid = false;
|
||||
error = ERROR_DIR_NAME_EMPTY;
|
||||
} else
|
||||
isValid = dirName.match(REGEX_DIRECTORY_NAME);
|
||||
// Update controls.
|
||||
if (isValid) {
|
||||
if (fileSystemDirNameButton.classList.contains(CLASS_FILE_SYSTEM_DIR_NAME_BUTTON_DISABLED))
|
||||
fileSystemDirNameButton.classList.remove(CLASS_FILE_SYSTEM_DIR_NAME_BUTTON_DISABLED);
|
||||
if (fileSystemDirName.classList.contains(CLASS_FILE_SYSTEM_DIR_NAME_INPUT_ERROR))
|
||||
fileSystemDirName.classList.remove(CLASS_FILE_SYSTEM_DIR_NAME_INPUT_ERROR);
|
||||
fileSystemDirNameError.innerHTML = " ";
|
||||
fileSystemDirNameError.style.visibility = "hidden";
|
||||
} else {
|
||||
if (!fileSystemDirNameButton.classList.contains(CLASS_FILE_SYSTEM_DIR_NAME_BUTTON_DISABLED))
|
||||
fileSystemDirNameButton.classList.add(CLASS_FILE_SYSTEM_DIR_NAME_BUTTON_DISABLED);
|
||||
if (!fileSystemDirName.classList.contains(CLASS_FILE_SYSTEM_DIR_NAME_INPUT_ERROR))
|
||||
fileSystemDirName.classList.add(CLASS_FILE_SYSTEM_DIR_NAME_INPUT_ERROR);
|
||||
fileSystemDirNameError.innerHTML = error;
|
||||
fileSystemDirNameError.style.visibility = "visible";
|
||||
}
|
||||
}
|
||||
|
||||
// Attempts to create the given directory.
|
||||
function createDirectory(directoryName) {
|
||||
// Build file path.
|
||||
var path = currentDirectory + directoryName;
|
||||
// Close the directory name panel.
|
||||
closeDirectoryNamePanel();
|
||||
// Show loading panel.
|
||||
showFileSystemLoading(true);
|
||||
// Send request.
|
||||
$.post(
|
||||
"http://" + getServerAddress() + "/ajax/fs_create_dir",
|
||||
JSON.stringify({
|
||||
"path": path
|
||||
}),
|
||||
function(data) {
|
||||
// Process only if the file system window is showing.
|
||||
if (!isFileSystemShowing())
|
||||
return;
|
||||
// Process answer.
|
||||
processCreateDirectoryResponse(data);
|
||||
}
|
||||
).fail(function(response) {
|
||||
// Process only if the file system window is showing.
|
||||
if (!isFileSystemShowing())
|
||||
return;
|
||||
// Process error.
|
||||
processAjaxErrorResponse(response);
|
||||
// Hide the loading status.
|
||||
showFileSystemLoading(false);
|
||||
});
|
||||
}
|
||||
|
||||
// Processes the create directory response.
|
||||
function processCreateDirectoryResponse(response) {
|
||||
// Check if there was any error in the request.
|
||||
if (checkErrorResponse(response, false)) {
|
||||
// Hide the loading status.
|
||||
showFileSystemLoading(false);
|
||||
} else {
|
||||
// List directory contents again.
|
||||
listDirectory(currentDirectory);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* jquery-match-height 0.7.2 by @liabru
|
||||
* http://brm.io/jquery-match-height/
|
||||
* License MIT
|
||||
*/
|
||||
!function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):"undefined"!=typeof module&&module.exports?module.exports=t(require("jquery")):t(jQuery)}(function(t){var e=-1,o=-1,n=function(t){return parseFloat(t)||0},a=function(e){var o=1,a=t(e),i=null,r=[];return a.each(function(){var e=t(this),a=e.offset().top-n(e.css("margin-top")),s=r.length>0?r[r.length-1]:null;null===s?r.push(e):Math.floor(Math.abs(i-a))<=o?r[r.length-1]=s.add(e):r.push(e),i=a}),r},i=function(e){var o={
|
||||
byRow:!0,property:"height",target:null,remove:!1};return"object"==typeof e?t.extend(o,e):("boolean"==typeof e?o.byRow=e:"remove"===e&&(o.remove=!0),o)},r=t.fn.matchHeight=function(e){var o=i(e);if(o.remove){var n=this;return this.css(o.property,""),t.each(r._groups,function(t,e){e.elements=e.elements.not(n)}),this}return this.length<=1&&!o.target?this:(r._groups.push({elements:this,options:o}),r._apply(this,o),this)};r.version="0.7.2",r._groups=[],r._throttle=80,r._maintainScroll=!1,r._beforeUpdate=null,
|
||||
r._afterUpdate=null,r._rows=a,r._parse=n,r._parseOptions=i,r._apply=function(e,o){var s=i(o),h=t(e),l=[h],c=t(window).scrollTop(),p=t("html").outerHeight(!0),u=h.parents().filter(":hidden");return u.each(function(){var e=t(this);e.data("style-cache",e.attr("style"))}),u.css("display","block"),s.byRow&&!s.target&&(h.each(function(){var e=t(this),o=e.css("display");"inline-block"!==o&&"flex"!==o&&"inline-flex"!==o&&(o="block"),e.data("style-cache",e.attr("style")),e.css({display:o,"padding-top":"0",
|
||||
"padding-bottom":"0","margin-top":"0","margin-bottom":"0","border-top-width":"0","border-bottom-width":"0",height:"100px",overflow:"hidden"})}),l=a(h),h.each(function(){var e=t(this);e.attr("style",e.data("style-cache")||"")})),t.each(l,function(e,o){var a=t(o),i=0;if(s.target)i=s.target.outerHeight(!1);else{if(s.byRow&&a.length<=1)return void a.css(s.property,"");a.each(function(){var e=t(this),o=e.attr("style"),n=e.css("display");"inline-block"!==n&&"flex"!==n&&"inline-flex"!==n&&(n="block");var a={
|
||||
display:n};a[s.property]="",e.css(a),e.outerHeight(!1)>i&&(i=e.outerHeight(!1)),o?e.attr("style",o):e.css("display","")})}a.each(function(){var e=t(this),o=0;s.target&&e.is(s.target)||("border-box"!==e.css("box-sizing")&&(o+=n(e.css("border-top-width"))+n(e.css("border-bottom-width")),o+=n(e.css("padding-top"))+n(e.css("padding-bottom"))),e.css(s.property,i-o+"px"))})}),u.each(function(){var e=t(this);e.attr("style",e.data("style-cache")||null)}),r._maintainScroll&&t(window).scrollTop(c/p*t("html").outerHeight(!0)),
|
||||
this},r._applyDataApi=function(){var e={};t("[data-match-height], [data-mh]").each(function(){var o=t(this),n=o.attr("data-mh")||o.attr("data-match-height");n in e?e[n]=e[n].add(o):e[n]=o}),t.each(e,function(){this.matchHeight(!0)})};var s=function(e){r._beforeUpdate&&r._beforeUpdate(e,r._groups),t.each(r._groups,function(){r._apply(this.elements,this.options)}),r._afterUpdate&&r._afterUpdate(e,r._groups)};r._update=function(n,a){if(a&&"resize"===a.type){var i=t(window).width();if(i===e)return;e=i;
|
||||
}n?o===-1&&(o=setTimeout(function(){s(a),o=-1},r._throttle)):s(a)},t(r._applyDataApi);var h=t.fn.on?"on":"bind";t(window)[h]("load",function(t){r._update(!1,t)}),t(window)[h]("resize orientationchange",function(t){r._update(!0,t)})});
|
||||
|
|
@ -0,0 +1,903 @@
|
|||
/*!
|
||||
* Copyright 2012, Chris Wanstrath
|
||||
* Released under the MIT License
|
||||
* https://github.com/defunkt/jquery-pjax
|
||||
*/
|
||||
|
||||
(function($){
|
||||
|
||||
// When called on a container with a selector, fetches the href with
|
||||
// ajax into the container or with the data-pjax attribute on the link
|
||||
// itself.
|
||||
//
|
||||
// Tries to make sure the back button and ctrl+click work the way
|
||||
// you'd expect.
|
||||
//
|
||||
// Exported as $.fn.pjax
|
||||
//
|
||||
// Accepts a jQuery ajax options object that may include these
|
||||
// pjax specific options:
|
||||
//
|
||||
//
|
||||
// container - String selector for the element where to place the response body.
|
||||
// push - Whether to pushState the URL. Defaults to true (of course).
|
||||
// replace - Want to use replaceState instead? That's cool.
|
||||
//
|
||||
// For convenience the second parameter can be either the container or
|
||||
// the options object.
|
||||
//
|
||||
// Returns the jQuery object
|
||||
function fnPjax(selector, container, options) {
|
||||
options = optionsFor(container, options)
|
||||
return this.on('click.pjax', selector, function(event) {
|
||||
var opts = options
|
||||
if (!opts.container) {
|
||||
opts = $.extend({}, options)
|
||||
opts.container = $(this).attr('data-pjax')
|
||||
}
|
||||
handleClick(event, opts)
|
||||
})
|
||||
}
|
||||
|
||||
// Public: pjax on click handler
|
||||
//
|
||||
// Exported as $.pjax.click.
|
||||
//
|
||||
// event - "click" jQuery.Event
|
||||
// options - pjax options
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// $(document).on('click', 'a', $.pjax.click)
|
||||
// // is the same as
|
||||
// $(document).pjax('a')
|
||||
//
|
||||
// Returns nothing.
|
||||
function handleClick(event, container, options) {
|
||||
options = optionsFor(container, options)
|
||||
|
||||
var link = event.currentTarget
|
||||
var $link = $(link)
|
||||
|
||||
if (link.tagName.toUpperCase() !== 'A')
|
||||
throw "$.fn.pjax or $.pjax.click requires an anchor element"
|
||||
|
||||
// Middle click, cmd click, and ctrl click should open
|
||||
// links in a new tab as normal.
|
||||
if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey )
|
||||
return
|
||||
|
||||
// Ignore cross origin links
|
||||
if ( location.protocol !== link.protocol || location.hostname !== link.hostname )
|
||||
return
|
||||
|
||||
// Ignore case when a hash is being tacked on the current URL
|
||||
if ( link.href.indexOf('#') > -1 && stripHash(link) == stripHash(location) )
|
||||
return
|
||||
|
||||
// Ignore event with default prevented
|
||||
if (event.isDefaultPrevented())
|
||||
return
|
||||
|
||||
var defaults = {
|
||||
url: link.href,
|
||||
container: $link.attr('data-pjax'),
|
||||
target: link
|
||||
}
|
||||
|
||||
var opts = $.extend({}, defaults, options)
|
||||
var clickEvent = $.Event('pjax:click')
|
||||
$link.trigger(clickEvent, [opts])
|
||||
|
||||
if (!clickEvent.isDefaultPrevented()) {
|
||||
pjax(opts)
|
||||
event.preventDefault()
|
||||
$link.trigger('pjax:clicked', [opts])
|
||||
}
|
||||
}
|
||||
|
||||
// Public: pjax on form submit handler
|
||||
//
|
||||
// Exported as $.pjax.submit
|
||||
//
|
||||
// event - "click" jQuery.Event
|
||||
// options - pjax options
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// $(document).on('submit', 'form', function(event) {
|
||||
// $.pjax.submit(event, '[data-pjax-container]')
|
||||
// })
|
||||
//
|
||||
// Returns nothing.
|
||||
function handleSubmit(event, container, options) {
|
||||
options = optionsFor(container, options)
|
||||
|
||||
var form = event.currentTarget
|
||||
var $form = $(form)
|
||||
|
||||
if (form.tagName.toUpperCase() !== 'FORM')
|
||||
throw "$.pjax.submit requires a form element"
|
||||
|
||||
var defaults = {
|
||||
type: ($form.attr('method') || 'GET').toUpperCase(),
|
||||
url: $form.attr('action'),
|
||||
container: $form.attr('data-pjax'),
|
||||
target: form
|
||||
}
|
||||
|
||||
if (defaults.type !== 'GET' && window.FormData !== undefined) {
|
||||
defaults.data = new FormData(form)
|
||||
defaults.processData = false
|
||||
defaults.contentType = false
|
||||
} else {
|
||||
// Can't handle file uploads, exit
|
||||
if ($form.find(':file').length) {
|
||||
return
|
||||
}
|
||||
|
||||
// Fallback to manually serializing the fields
|
||||
defaults.data = $form.serializeArray()
|
||||
}
|
||||
|
||||
pjax($.extend({}, defaults, options))
|
||||
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
// Loads a URL with ajax, puts the response body inside a container,
|
||||
// then pushState()'s the loaded URL.
|
||||
//
|
||||
// Works just like $.ajax in that it accepts a jQuery ajax
|
||||
// settings object (with keys like url, type, data, etc).
|
||||
//
|
||||
// Accepts these extra keys:
|
||||
//
|
||||
// container - String selector for where to stick the response body.
|
||||
// push - Whether to pushState the URL. Defaults to true (of course).
|
||||
// replace - Want to use replaceState instead? That's cool.
|
||||
//
|
||||
// Use it just like $.ajax:
|
||||
//
|
||||
// var xhr = $.pjax({ url: this.href, container: '#main' })
|
||||
// console.log( xhr.readyState )
|
||||
//
|
||||
// Returns whatever $.ajax returns.
|
||||
function pjax(options) {
|
||||
options = $.extend(true, {}, $.ajaxSettings, pjax.defaults, options)
|
||||
|
||||
if ($.isFunction(options.url)) {
|
||||
options.url = options.url()
|
||||
}
|
||||
|
||||
var hash = parseURL(options.url).hash
|
||||
|
||||
var containerType = $.type(options.container)
|
||||
if (containerType !== 'string') {
|
||||
throw "expected string value for 'container' option; got " + containerType
|
||||
}
|
||||
var context = options.context = $(options.container)
|
||||
if (!context.length) {
|
||||
throw "the container selector '" + options.container + "' did not match anything"
|
||||
}
|
||||
|
||||
// We want the browser to maintain two separate internal caches: one
|
||||
// for pjax'd partial page loads and one for normal page loads.
|
||||
// Without adding this secret parameter, some browsers will often
|
||||
// confuse the two.
|
||||
if (!options.data) options.data = {}
|
||||
if ($.isArray(options.data)) {
|
||||
options.data.push({name: '_pjax', value: options.container})
|
||||
} else {
|
||||
options.data._pjax = options.container
|
||||
}
|
||||
|
||||
function fire(type, args, props) {
|
||||
if (!props) props = {}
|
||||
props.relatedTarget = options.target
|
||||
var event = $.Event(type, props)
|
||||
context.trigger(event, args)
|
||||
return !event.isDefaultPrevented()
|
||||
}
|
||||
|
||||
var timeoutTimer
|
||||
|
||||
options.beforeSend = function(xhr, settings) {
|
||||
// No timeout for non-GET requests
|
||||
// Its not safe to request the resource again with a fallback method.
|
||||
if (settings.type !== 'GET') {
|
||||
settings.timeout = 0
|
||||
}
|
||||
|
||||
xhr.setRequestHeader('X-PJAX', 'true')
|
||||
xhr.setRequestHeader('X-PJAX-Container', options.container)
|
||||
|
||||
if (!fire('pjax:beforeSend', [xhr, settings]))
|
||||
return false
|
||||
|
||||
if (settings.timeout > 0) {
|
||||
timeoutTimer = setTimeout(function() {
|
||||
if (fire('pjax:timeout', [xhr, options]))
|
||||
xhr.abort('timeout')
|
||||
}, settings.timeout)
|
||||
|
||||
// Clear timeout setting so jquerys internal timeout isn't invoked
|
||||
settings.timeout = 0
|
||||
}
|
||||
|
||||
var url = parseURL(settings.url)
|
||||
if (hash) url.hash = hash
|
||||
options.requestUrl = stripInternalParams(url)
|
||||
}
|
||||
|
||||
options.complete = function(xhr, textStatus) {
|
||||
if (timeoutTimer)
|
||||
clearTimeout(timeoutTimer)
|
||||
|
||||
fire('pjax:complete', [xhr, textStatus, options])
|
||||
|
||||
fire('pjax:end', [xhr, options])
|
||||
}
|
||||
|
||||
options.error = function(xhr, textStatus, errorThrown) {
|
||||
var container = extractContainer("", xhr, options)
|
||||
|
||||
var allowed = fire('pjax:error', [xhr, textStatus, errorThrown, options])
|
||||
if (options.type == 'GET' && textStatus !== 'abort' && allowed) {
|
||||
locationReplace(container.url)
|
||||
}
|
||||
}
|
||||
|
||||
options.success = function(data, status, xhr) {
|
||||
var previousState = pjax.state
|
||||
|
||||
// If $.pjax.defaults.version is a function, invoke it first.
|
||||
// Otherwise it can be a static string.
|
||||
var currentVersion = typeof $.pjax.defaults.version === 'function' ?
|
||||
$.pjax.defaults.version() :
|
||||
$.pjax.defaults.version
|
||||
|
||||
var latestVersion = xhr.getResponseHeader('X-PJAX-Version')
|
||||
|
||||
var container = extractContainer(data, xhr, options)
|
||||
|
||||
var url = parseURL(container.url)
|
||||
if (hash) {
|
||||
url.hash = hash
|
||||
container.url = url.href
|
||||
}
|
||||
|
||||
// If there is a layout version mismatch, hard load the new url
|
||||
if (currentVersion && latestVersion && currentVersion !== latestVersion) {
|
||||
locationReplace(container.url)
|
||||
return
|
||||
}
|
||||
|
||||
// If the new response is missing a body, hard load the page
|
||||
if (!container.contents) {
|
||||
locationReplace(container.url)
|
||||
return
|
||||
}
|
||||
|
||||
pjax.state = {
|
||||
id: options.id || uniqueId(),
|
||||
url: container.url,
|
||||
title: container.title,
|
||||
container: options.container,
|
||||
fragment: options.fragment,
|
||||
timeout: options.timeout
|
||||
}
|
||||
|
||||
if (options.push || options.replace) {
|
||||
window.history.replaceState(pjax.state, container.title, container.url)
|
||||
}
|
||||
|
||||
// Only blur the focus if the focused element is within the container.
|
||||
var blurFocus = $.contains(context, document.activeElement)
|
||||
|
||||
// Clear out any focused controls before inserting new page contents.
|
||||
if (blurFocus) {
|
||||
try {
|
||||
document.activeElement.blur()
|
||||
} catch (e) { /* ignore */ }
|
||||
}
|
||||
|
||||
if (container.title) document.title = container.title
|
||||
|
||||
fire('pjax:beforeReplace', [container.contents, options], {
|
||||
state: pjax.state,
|
||||
previousState: previousState
|
||||
})
|
||||
context.html(container.contents)
|
||||
|
||||
// FF bug: Won't autofocus fields that are inserted via JS.
|
||||
// This behavior is incorrect. So if theres no current focus, autofocus
|
||||
// the last field.
|
||||
//
|
||||
// http://www.w3.org/html/wg/drafts/html/master/forms.html
|
||||
var autofocusEl = context.find('input[autofocus], textarea[autofocus]').last()[0]
|
||||
if (autofocusEl && document.activeElement !== autofocusEl) {
|
||||
autofocusEl.focus()
|
||||
}
|
||||
|
||||
executeScriptTags(container.scripts)
|
||||
|
||||
var scrollTo = options.scrollTo
|
||||
|
||||
// Ensure browser scrolls to the element referenced by the URL anchor
|
||||
if (hash) {
|
||||
var name = decodeURIComponent(hash.slice(1))
|
||||
var target = document.getElementById(name) || document.getElementsByName(name)[0]
|
||||
if (target) scrollTo = $(target).offset().top
|
||||
}
|
||||
|
||||
if (typeof scrollTo == 'number') $(window).scrollTop(scrollTo)
|
||||
|
||||
fire('pjax:success', [data, status, xhr, options])
|
||||
}
|
||||
|
||||
|
||||
// Initialize pjax.state for the initial page load. Assume we're
|
||||
// using the container and options of the link we're loading for the
|
||||
// back button to the initial page. This ensures good back button
|
||||
// behavior.
|
||||
if (!pjax.state) {
|
||||
pjax.state = {
|
||||
id: uniqueId(),
|
||||
url: window.location.href,
|
||||
title: document.title,
|
||||
container: options.container,
|
||||
fragment: options.fragment,
|
||||
timeout: options.timeout
|
||||
}
|
||||
window.history.replaceState(pjax.state, document.title)
|
||||
}
|
||||
|
||||
// Cancel the current request if we're already pjaxing
|
||||
abortXHR(pjax.xhr)
|
||||
|
||||
pjax.options = options
|
||||
var xhr = pjax.xhr = $.ajax(options)
|
||||
|
||||
if (xhr.readyState > 0) {
|
||||
if (options.push && !options.replace) {
|
||||
// Cache current container element before replacing it
|
||||
cachePush(pjax.state.id, [options.container, cloneContents(context)])
|
||||
|
||||
window.history.pushState(null, "", options.requestUrl)
|
||||
}
|
||||
|
||||
fire('pjax:start', [xhr, options])
|
||||
fire('pjax:send', [xhr, options])
|
||||
}
|
||||
|
||||
return pjax.xhr
|
||||
}
|
||||
|
||||
// Public: Reload current page with pjax.
|
||||
//
|
||||
// Returns whatever $.pjax returns.
|
||||
function pjaxReload(container, options) {
|
||||
var defaults = {
|
||||
url: window.location.href,
|
||||
push: false,
|
||||
replace: true,
|
||||
scrollTo: false
|
||||
}
|
||||
|
||||
return pjax($.extend(defaults, optionsFor(container, options)))
|
||||
}
|
||||
|
||||
// Internal: Hard replace current state with url.
|
||||
//
|
||||
// Work for around WebKit
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=93506
|
||||
//
|
||||
// Returns nothing.
|
||||
function locationReplace(url) {
|
||||
window.history.replaceState(null, "", pjax.state.url)
|
||||
window.location.replace(url)
|
||||
}
|
||||
|
||||
|
||||
var initialPop = true
|
||||
var initialURL = window.location.href
|
||||
var initialState = window.history.state
|
||||
|
||||
// Initialize $.pjax.state if possible
|
||||
// Happens when reloading a page and coming forward from a different
|
||||
// session history.
|
||||
if (initialState && initialState.container) {
|
||||
pjax.state = initialState
|
||||
}
|
||||
|
||||
// Non-webkit browsers don't fire an initial popstate event
|
||||
if ('state' in window.history) {
|
||||
initialPop = false
|
||||
}
|
||||
|
||||
// popstate handler takes care of the back and forward buttons
|
||||
//
|
||||
// You probably shouldn't use pjax on pages with other pushState
|
||||
// stuff yet.
|
||||
function onPjaxPopstate(event) {
|
||||
|
||||
// Hitting back or forward should override any pending PJAX request.
|
||||
if (!initialPop) {
|
||||
abortXHR(pjax.xhr)
|
||||
}
|
||||
|
||||
var previousState = pjax.state
|
||||
var state = event.state
|
||||
var direction
|
||||
|
||||
if (state && state.container) {
|
||||
// When coming forward from a separate history session, will get an
|
||||
// initial pop with a state we are already at. Skip reloading the current
|
||||
// page.
|
||||
if (initialPop && initialURL == state.url) return
|
||||
|
||||
if (previousState) {
|
||||
// If popping back to the same state, just skip.
|
||||
// Could be clicking back from hashchange rather than a pushState.
|
||||
if (previousState.id === state.id) return
|
||||
|
||||
// Since state IDs always increase, we can deduce the navigation direction
|
||||
direction = previousState.id < state.id ? 'forward' : 'back'
|
||||
}
|
||||
|
||||
var cache = cacheMapping[state.id] || []
|
||||
var containerSelector = cache[0] || state.container
|
||||
var container = $(containerSelector), contents = cache[1]
|
||||
|
||||
if (container.length) {
|
||||
if (previousState) {
|
||||
// Cache current container before replacement and inform the
|
||||
// cache which direction the history shifted.
|
||||
cachePop(direction, previousState.id, [containerSelector, cloneContents(container)])
|
||||
}
|
||||
|
||||
var popstateEvent = $.Event('pjax:popstate', {
|
||||
state: state,
|
||||
direction: direction
|
||||
})
|
||||
container.trigger(popstateEvent)
|
||||
|
||||
var options = {
|
||||
id: state.id,
|
||||
url: state.url,
|
||||
container: containerSelector,
|
||||
push: false,
|
||||
fragment: state.fragment,
|
||||
timeout: state.timeout,
|
||||
scrollTo: false
|
||||
}
|
||||
|
||||
if (contents) {
|
||||
container.trigger('pjax:start', [null, options])
|
||||
|
||||
pjax.state = state
|
||||
if (state.title) document.title = state.title
|
||||
var beforeReplaceEvent = $.Event('pjax:beforeReplace', {
|
||||
state: state,
|
||||
previousState: previousState
|
||||
})
|
||||
container.trigger(beforeReplaceEvent, [contents, options])
|
||||
container.html(contents)
|
||||
|
||||
container.trigger('pjax:end', [null, options])
|
||||
} else {
|
||||
pjax(options)
|
||||
}
|
||||
|
||||
// Force reflow/relayout before the browser tries to restore the
|
||||
// scroll position.
|
||||
container[0].offsetHeight // eslint-disable-line no-unused-expressions
|
||||
} else {
|
||||
locationReplace(location.href)
|
||||
}
|
||||
}
|
||||
initialPop = false
|
||||
}
|
||||
|
||||
// Fallback version of main pjax function for browsers that don't
|
||||
// support pushState.
|
||||
//
|
||||
// Returns nothing since it retriggers a hard form submission.
|
||||
function fallbackPjax(options) {
|
||||
var url = $.isFunction(options.url) ? options.url() : options.url,
|
||||
method = options.type ? options.type.toUpperCase() : 'GET'
|
||||
|
||||
var form = $('<form>', {
|
||||
method: method === 'GET' ? 'GET' : 'POST',
|
||||
action: url,
|
||||
style: 'display:none'
|
||||
})
|
||||
|
||||
if (method !== 'GET' && method !== 'POST') {
|
||||
form.append($('<input>', {
|
||||
type: 'hidden',
|
||||
name: '_method',
|
||||
value: method.toLowerCase()
|
||||
}))
|
||||
}
|
||||
|
||||
var data = options.data
|
||||
if (typeof data === 'string') {
|
||||
$.each(data.split('&'), function(index, value) {
|
||||
var pair = value.split('=')
|
||||
form.append($('<input>', {type: 'hidden', name: pair[0], value: pair[1]}))
|
||||
})
|
||||
} else if ($.isArray(data)) {
|
||||
$.each(data, function(index, value) {
|
||||
form.append($('<input>', {type: 'hidden', name: value.name, value: value.value}))
|
||||
})
|
||||
} else if (typeof data === 'object') {
|
||||
var key
|
||||
for (key in data)
|
||||
form.append($('<input>', {type: 'hidden', name: key, value: data[key]}))
|
||||
}
|
||||
|
||||
$(document.body).append(form)
|
||||
form.submit()
|
||||
}
|
||||
|
||||
// Internal: Abort an XmlHttpRequest if it hasn't been completed,
|
||||
// also removing its event handlers.
|
||||
function abortXHR(xhr) {
|
||||
if ( xhr && xhr.readyState < 4) {
|
||||
xhr.onreadystatechange = $.noop
|
||||
xhr.abort()
|
||||
}
|
||||
}
|
||||
|
||||
// Internal: Generate unique id for state object.
|
||||
//
|
||||
// Use a timestamp instead of a counter since ids should still be
|
||||
// unique across page loads.
|
||||
//
|
||||
// Returns Number.
|
||||
function uniqueId() {
|
||||
return (new Date).getTime()
|
||||
}
|
||||
|
||||
function cloneContents(container) {
|
||||
var cloned = container.clone()
|
||||
// Unmark script tags as already being eval'd so they can get executed again
|
||||
// when restored from cache. HAXX: Uses jQuery internal method.
|
||||
cloned.find('script').each(function(){
|
||||
if (!this.src) $._data(this, 'globalEval', false)
|
||||
})
|
||||
return cloned.contents()
|
||||
}
|
||||
|
||||
// Internal: Strip internal query params from parsed URL.
|
||||
//
|
||||
// Returns sanitized url.href String.
|
||||
function stripInternalParams(url) {
|
||||
url.search = url.search.replace(/([?&])(_pjax|_)=[^&]*/g, '').replace(/^&/, '')
|
||||
return url.href.replace(/\?($|#)/, '$1')
|
||||
}
|
||||
|
||||
// Internal: Parse URL components and returns a Locationish object.
|
||||
//
|
||||
// url - String URL
|
||||
//
|
||||
// Returns HTMLAnchorElement that acts like Location.
|
||||
function parseURL(url) {
|
||||
var a = document.createElement('a')
|
||||
a.href = url
|
||||
return a
|
||||
}
|
||||
|
||||
// Internal: Return the `href` component of given URL object with the hash
|
||||
// portion removed.
|
||||
//
|
||||
// location - Location or HTMLAnchorElement
|
||||
//
|
||||
// Returns String
|
||||
function stripHash(location) {
|
||||
return location.href.replace(/#.*/, '')
|
||||
}
|
||||
|
||||
// Internal: Build options Object for arguments.
|
||||
//
|
||||
// For convenience the first parameter can be either the container or
|
||||
// the options object.
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// optionsFor('#container')
|
||||
// // => {container: '#container'}
|
||||
//
|
||||
// optionsFor('#container', {push: true})
|
||||
// // => {container: '#container', push: true}
|
||||
//
|
||||
// optionsFor({container: '#container', push: true})
|
||||
// // => {container: '#container', push: true}
|
||||
//
|
||||
// Returns options Object.
|
||||
function optionsFor(container, options) {
|
||||
if (container && options) {
|
||||
options = $.extend({}, options)
|
||||
options.container = container
|
||||
return options
|
||||
} else if ($.isPlainObject(container)) {
|
||||
return container
|
||||
} else {
|
||||
return {container: container}
|
||||
}
|
||||
}
|
||||
|
||||
// Internal: Filter and find all elements matching the selector.
|
||||
//
|
||||
// Where $.fn.find only matches descendants, findAll will test all the
|
||||
// top level elements in the jQuery object as well.
|
||||
//
|
||||
// elems - jQuery object of Elements
|
||||
// selector - String selector to match
|
||||
//
|
||||
// Returns a jQuery object.
|
||||
function findAll(elems, selector) {
|
||||
return elems.filter(selector).add(elems.find(selector))
|
||||
}
|
||||
|
||||
function parseHTML(html) {
|
||||
return $.parseHTML(html, document, true)
|
||||
}
|
||||
|
||||
// Internal: Extracts container and metadata from response.
|
||||
//
|
||||
// 1. Extracts X-PJAX-URL header if set
|
||||
// 2. Extracts inline <title> tags
|
||||
// 3. Builds response Element and extracts fragment if set
|
||||
//
|
||||
// data - String response data
|
||||
// xhr - XHR response
|
||||
// options - pjax options Object
|
||||
//
|
||||
// Returns an Object with url, title, and contents keys.
|
||||
function extractContainer(data, xhr, options) {
|
||||
var obj = {}, fullDocument = /<html/i.test(data)
|
||||
|
||||
// Prefer X-PJAX-URL header if it was set, otherwise fallback to
|
||||
// using the original requested url.
|
||||
var serverUrl = xhr.getResponseHeader('X-PJAX-URL')
|
||||
obj.url = serverUrl ? stripInternalParams(parseURL(serverUrl)) : options.requestUrl
|
||||
|
||||
var $head, $body
|
||||
// Attempt to parse response html into elements
|
||||
if (fullDocument) {
|
||||
$body = $(parseHTML(data.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0]))
|
||||
var head = data.match(/<head[^>]*>([\s\S.]*)<\/head>/i)
|
||||
$head = head != null ? $(parseHTML(head[0])) : $body
|
||||
} else {
|
||||
$head = $body = $(parseHTML(data))
|
||||
}
|
||||
|
||||
// If response data is empty, return fast
|
||||
if ($body.length === 0)
|
||||
return obj
|
||||
|
||||
// If there's a <title> tag in the header, use it as
|
||||
// the page's title.
|
||||
obj.title = findAll($head, 'title').last().text()
|
||||
|
||||
if (options.fragment) {
|
||||
var $fragment = $body
|
||||
// If they specified a fragment, look for it in the response
|
||||
// and pull it out.
|
||||
if (options.fragment !== 'body') {
|
||||
$fragment = findAll($fragment, options.fragment).first()
|
||||
}
|
||||
|
||||
if ($fragment.length) {
|
||||
obj.contents = options.fragment === 'body' ? $fragment : $fragment.contents()
|
||||
|
||||
// If there's no title, look for data-title and title attributes
|
||||
// on the fragment
|
||||
if (!obj.title)
|
||||
obj.title = $fragment.attr('title') || $fragment.data('title')
|
||||
}
|
||||
|
||||
} else if (!fullDocument) {
|
||||
obj.contents = $body
|
||||
}
|
||||
|
||||
// Clean up any <title> tags
|
||||
if (obj.contents) {
|
||||
// Remove any parent title elements
|
||||
obj.contents = obj.contents.not(function() { return $(this).is('title') })
|
||||
|
||||
// Then scrub any titles from their descendants
|
||||
obj.contents.find('title').remove()
|
||||
|
||||
// Gather all script[src] elements
|
||||
obj.scripts = findAll(obj.contents, 'script[src]').remove()
|
||||
obj.contents = obj.contents.not(obj.scripts)
|
||||
}
|
||||
|
||||
// Trim any whitespace off the title
|
||||
if (obj.title) obj.title = $.trim(obj.title)
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
// Load an execute scripts using standard script request.
|
||||
//
|
||||
// Avoids jQuery's traditional $.getScript which does a XHR request and
|
||||
// globalEval.
|
||||
//
|
||||
// scripts - jQuery object of script Elements
|
||||
//
|
||||
// Returns nothing.
|
||||
function executeScriptTags(scripts) {
|
||||
if (!scripts) return
|
||||
|
||||
var existingScripts = $('script[src]')
|
||||
|
||||
scripts.each(function() {
|
||||
var src = this.src
|
||||
var matchedScripts = existingScripts.filter(function() {
|
||||
return this.src === src
|
||||
})
|
||||
if (matchedScripts.length) return
|
||||
|
||||
var script = document.createElement('script')
|
||||
var type = $(this).attr('type')
|
||||
if (type) script.type = type
|
||||
script.src = $(this).attr('src')
|
||||
document.head.appendChild(script)
|
||||
})
|
||||
}
|
||||
|
||||
// Internal: History DOM caching class.
|
||||
var cacheMapping = {}
|
||||
var cacheForwardStack = []
|
||||
var cacheBackStack = []
|
||||
|
||||
// Push previous state id and container contents into the history
|
||||
// cache. Should be called in conjunction with `pushState` to save the
|
||||
// previous container contents.
|
||||
//
|
||||
// id - State ID Number
|
||||
// value - DOM Element to cache
|
||||
//
|
||||
// Returns nothing.
|
||||
function cachePush(id, value) {
|
||||
cacheMapping[id] = value
|
||||
cacheBackStack.push(id)
|
||||
|
||||
// Remove all entries in forward history stack after pushing a new page.
|
||||
trimCacheStack(cacheForwardStack, 0)
|
||||
|
||||
// Trim back history stack to max cache length.
|
||||
trimCacheStack(cacheBackStack, pjax.defaults.maxCacheLength)
|
||||
}
|
||||
|
||||
// Shifts cache from directional history cache. Should be
|
||||
// called on `popstate` with the previous state id and container
|
||||
// contents.
|
||||
//
|
||||
// direction - "forward" or "back" String
|
||||
// id - State ID Number
|
||||
// value - DOM Element to cache
|
||||
//
|
||||
// Returns nothing.
|
||||
function cachePop(direction, id, value) {
|
||||
var pushStack, popStack
|
||||
cacheMapping[id] = value
|
||||
|
||||
if (direction === 'forward') {
|
||||
pushStack = cacheBackStack
|
||||
popStack = cacheForwardStack
|
||||
} else {
|
||||
pushStack = cacheForwardStack
|
||||
popStack = cacheBackStack
|
||||
}
|
||||
|
||||
pushStack.push(id)
|
||||
id = popStack.pop()
|
||||
if (id) delete cacheMapping[id]
|
||||
|
||||
// Trim whichever stack we just pushed to to max cache length.
|
||||
trimCacheStack(pushStack, pjax.defaults.maxCacheLength)
|
||||
}
|
||||
|
||||
// Trim a cache stack (either cacheBackStack or cacheForwardStack) to be no
|
||||
// longer than the specified length, deleting cached DOM elements as necessary.
|
||||
//
|
||||
// stack - Array of state IDs
|
||||
// length - Maximum length to trim to
|
||||
//
|
||||
// Returns nothing.
|
||||
function trimCacheStack(stack, length) {
|
||||
while (stack.length > length)
|
||||
delete cacheMapping[stack.shift()]
|
||||
}
|
||||
|
||||
// Public: Find version identifier for the initial page load.
|
||||
//
|
||||
// Returns String version or undefined.
|
||||
function findVersion() {
|
||||
return $('meta').filter(function() {
|
||||
var name = $(this).attr('http-equiv')
|
||||
return name && name.toUpperCase() === 'X-PJAX-VERSION'
|
||||
}).attr('content')
|
||||
}
|
||||
|
||||
// Install pjax functions on $.pjax to enable pushState behavior.
|
||||
//
|
||||
// Does nothing if already enabled.
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// $.pjax.enable()
|
||||
//
|
||||
// Returns nothing.
|
||||
function enable() {
|
||||
$.fn.pjax = fnPjax
|
||||
$.pjax = pjax
|
||||
$.pjax.enable = $.noop
|
||||
$.pjax.disable = disable
|
||||
$.pjax.click = handleClick
|
||||
$.pjax.submit = handleSubmit
|
||||
$.pjax.reload = pjaxReload
|
||||
$.pjax.defaults = {
|
||||
timeout: 650,
|
||||
push: true,
|
||||
replace: false,
|
||||
type: 'GET',
|
||||
dataType: 'html',
|
||||
scrollTo: 0,
|
||||
maxCacheLength: 20,
|
||||
version: findVersion
|
||||
}
|
||||
$(window).on('popstate.pjax', onPjaxPopstate)
|
||||
}
|
||||
|
||||
// Disable pushState behavior.
|
||||
//
|
||||
// This is the case when a browser doesn't support pushState. It is
|
||||
// sometimes useful to disable pushState for debugging on a modern
|
||||
// browser.
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// $.pjax.disable()
|
||||
//
|
||||
// Returns nothing.
|
||||
function disable() {
|
||||
$.fn.pjax = function() { return this }
|
||||
$.pjax = fallbackPjax
|
||||
$.pjax.enable = enable
|
||||
$.pjax.disable = $.noop
|
||||
$.pjax.click = $.noop
|
||||
$.pjax.submit = $.noop
|
||||
$.pjax.reload = function() { window.location.reload() }
|
||||
|
||||
$(window).off('popstate.pjax', onPjaxPopstate)
|
||||
}
|
||||
|
||||
|
||||
// Add the state property to jQuery's event object so we can use it in
|
||||
// $(window).bind('popstate')
|
||||
if ($.event.props && $.inArray('state', $.event.props) < 0) {
|
||||
$.event.props.push('state')
|
||||
} else if (!('state' in $.Event.prototype)) {
|
||||
$.event.addProp('state')
|
||||
}
|
||||
|
||||
// Is pjax supported by this browser?
|
||||
$.support.pjax =
|
||||
window.history && window.history.pushState && window.history.replaceState &&
|
||||
// pushState isn't reliable on iOS until 5.
|
||||
!navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/)
|
||||
|
||||
if ($.support.pjax) {
|
||||
enable()
|
||||
} else {
|
||||
disable()
|
||||
}
|
||||
|
||||
})(jQuery)
|
||||
|
|
@ -0,0 +1,778 @@
|
|||
/*
|
||||
* Copyright 2022, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
// Constants.
|
||||
const ID_REBOOT_BUTTON = "reboot_button";
|
||||
const ID_FIRMWARE_TAB_UPLOAD = "firmware_tab_upload";
|
||||
const ID_FIRMWARE_TAB_UPLOAD_HEADER = "firmware_tab_upload_header";
|
||||
const ID_SELECT_FIRMWARE_BUTTON = "select_firmware_button";
|
||||
const ID_UPDATE_FIRMWARE_BUTTON = "update_firmware_button";
|
||||
const ID_UPDATE_FIRMWARE_FILE = "firmware_file";
|
||||
const ID_UPDATE_FIRMWARE_FILE_LABEL = "firmware_file_label";
|
||||
const ID_UPDATE_FIRMWARE_PROGRESS = "update_firmware_progress";
|
||||
const ID_UPDATE_FIRMWARE_PROGRESS_BAR = "update_firmware_progress_bar";
|
||||
const ID_UPDATE_FIRMWARE_PROGRESS_MESSAGE = "update_firmware_progress_message";
|
||||
const ID_UPDATE_FIRMWARE_PROGRESS_TITLE = "update_firmware_progress_title";
|
||||
const ID_UPDATE_RUNNING = "update_running";
|
||||
|
||||
const CLASS_FIRMWARE_TAB = "firmware-tab";
|
||||
const CLASS_FIRMWARE_TAB_HEADER = "firmware-tab-header";
|
||||
const CLASS_FIRMWARE_TAB_HEADER_ACTIVE = "firmware-tab-header-active";
|
||||
const CLASS_MANAGEMENT_BUTTON_DISABLED = "management-button-disabled";
|
||||
const CLASS_PROGRESS_BAR_ERROR = "update-firmware-progress-bar-error";
|
||||
const CLASS_PROGRESS_BAR_INFO = "update-firmware-progress-bar-info";
|
||||
const CLASS_PROGRESS_BAR_SUCCESS = "update-firmware-progress-bar-success";
|
||||
|
||||
const TITLE_CONFIRM_FIRMWARE_UPDATE = "Confirm firmware update";
|
||||
const TITLE_CONFIRM_REBOOT = "Confirm reboot";
|
||||
const TITLE_DEVICE_REBOOTING = "Device Rebooting";
|
||||
const TITLE_FIRMWARE_UPDATE_ERROR = "Firmware update failed!";
|
||||
const TITLE_FIRMWARE_UPDATE_IN_PROGRESS = "Firmware update in progress...";
|
||||
const TITLE_FIRMWARE_UPDATE_SUCCESS = "Firmware update succeeded!";
|
||||
|
||||
const MESSAGE_CHECKING_FIRMWARE_UPDATE_STATUS = "Checking firmware update...";
|
||||
const MESSAGE_CONFIRM_FIRMWARE_UPDATE = "This action will update the device firmware. Do you want to continue?";
|
||||
const MESSAGE_CONFIRM_REBOOT = "This action will reboot the device and connection will be lost. Do you want to continue?";
|
||||
const MESSAGE_DEVICE_REBOOTING = "The device is rebooting. Please wait...";
|
||||
const MESSAGE_LOADING_INFORMATION = "Loading device information...";
|
||||
const MESSAGE_LOADING_FILES = "Loading files...";
|
||||
const MESSAGE_NO_FILE_SELECTED = "No file selected";
|
||||
const MESSAGE_SENDING_FIRMWARE_UPDATE_REQUEST = "Sending firmware update request...";
|
||||
const MESSAGE_SENDING_REBOOT = "Sending reboot request...";
|
||||
const MESSAGE_SENDING_UPLOAD_REQUEST = "Sending firmware upload request...";
|
||||
const MESSAGE_UPLOAD_COMPLETE = "Firmware file upload complete";
|
||||
const MESSAGE_UPDATING_FIRMWARE = "Updating firmware...";
|
||||
const MESSAGE_UPLOADING_FIRMWARE = "Uploading firmware file...";
|
||||
|
||||
const UPDATE_ERROR = "error";
|
||||
const UPDATE_INFO = "info";
|
||||
const UPDATE_SUCCESS = "success";
|
||||
|
||||
const FIRMWARE_UPDATE_CHECK_INTERVAL = 10000;
|
||||
|
||||
// Variables.
|
||||
var readingManagementInfo = false;
|
||||
var managementInfoRead = false;
|
||||
var deviceRebooting = false;
|
||||
var updatingFirmware = false;
|
||||
var firmwareUpdateTimer = null;
|
||||
var uploadFirmwareAjaxRequest = null;
|
||||
var fwStorageDir = "/home/root/";
|
||||
|
||||
// Initializes the management page.
|
||||
function initializeManagementPage() {
|
||||
// Sanity checks.
|
||||
if (!isManagementShowing() || managementInfoRead)
|
||||
return;
|
||||
// Read management information.
|
||||
readDeviceInfoManagement();
|
||||
}
|
||||
|
||||
// Gets the information of the device.
|
||||
function readDeviceInfoManagement() {
|
||||
// Execute only in the management page.
|
||||
if (!isManagementShowing() || readingManagementInfo)
|
||||
return;
|
||||
// Unset device rebooting variable.
|
||||
deviceRebooting = false;
|
||||
// Flag reading variable.
|
||||
readingManagementInfo = true;
|
||||
// Hide the info popup.
|
||||
showInfoPopup(false);
|
||||
// Hide the firmware progress.
|
||||
showFirmwareUpdateProgress(false);
|
||||
// Show the loading popup.
|
||||
showLoadingPopup(true, MESSAGE_LOADING_INFORMATION);
|
||||
// Send request to retrieve device information.
|
||||
$.post(
|
||||
"http://" + getServerAddress() + "/ajax/get_device_info",
|
||||
function(data) {
|
||||
readingManagementInfo = false;
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Hide the loading panel.
|
||||
showLoadingPopup(false);
|
||||
// Process device information answer.
|
||||
processDeviceInfoManagementResponse(data);
|
||||
}
|
||||
).fail(function(response) {
|
||||
// Flag reading variable.
|
||||
readingManagementInfo = false;
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Hide the loading panel.
|
||||
showLoadingPopup(false);
|
||||
// Process error.
|
||||
processAjaxErrorResponse(response);
|
||||
});
|
||||
}
|
||||
|
||||
// Processes the response of the device info request.
|
||||
function processDeviceInfoManagementResponse(response) {
|
||||
// Check if there was any error in the request.
|
||||
if (!checkErrorResponse(response, false)) {
|
||||
// Fill device info.
|
||||
fillDeviceInfo(response);
|
||||
fwStorageDir = response[ID_FW_STORE_PATH];
|
||||
// Flag device info read.
|
||||
managementInfoRead = true;
|
||||
// Check if there is a firmware update running.
|
||||
checkFirmwareUpdateRunning();
|
||||
}
|
||||
}
|
||||
|
||||
// Fills device information.
|
||||
function fillDeviceInfo(deviceData) {
|
||||
// Set the device type.
|
||||
updateFieldValue(ID_DEVICE_NAME, deviceData[ID_DEVICE_TYPE].toUpperCase());
|
||||
// Set DEY version.
|
||||
updateFieldValue(ID_DEY_VERSION, deviceData[ID_DEY_VERSION]);
|
||||
// Set Kernel version.
|
||||
updateFieldValue(ID_KERNEL_VERSION, deviceData[ID_KERNEL_VERSION]);
|
||||
// Set U-Boot version.
|
||||
updateFieldValue(ID_UBOOT_VERSION, deviceData[ID_UBOOT_VERSION]);
|
||||
}
|
||||
|
||||
// Asks the user to confirm the reboot action.
|
||||
function askReboot() {
|
||||
showConfirmDialog(TITLE_CONFIRM_REBOOT, MESSAGE_CONFIRM_REBOOT,
|
||||
function() {
|
||||
// Execute the reboot.
|
||||
rebootDevice();
|
||||
},
|
||||
function() {
|
||||
// Do nothing.
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Reboots the device.
|
||||
function rebootDevice() {
|
||||
// Hide the info popup.
|
||||
showInfoPopup(false);
|
||||
// Show the loading popup.
|
||||
showLoadingPopup(true, MESSAGE_SENDING_REBOOT);
|
||||
// Send request to reboot the device.
|
||||
$.post(
|
||||
"http://" + getServerAddress() + "/ajax/reboot_device",
|
||||
function(data) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Hide the loading panel.
|
||||
showLoadingPopup(false);
|
||||
// Process reboot device answer.
|
||||
processRebootDeviceResponse(data);
|
||||
}
|
||||
).fail(function(response) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Hide the loading panel.
|
||||
showLoadingPopup(false);
|
||||
// Process error.
|
||||
processAjaxErrorResponse(response);
|
||||
});
|
||||
}
|
||||
|
||||
function onConnectivity(cb) {
|
||||
$.get("http://" + getServerAddress() + "/ping", function() {
|
||||
cb();
|
||||
}).fail(function() {
|
||||
onConnectivity(cb);
|
||||
});
|
||||
}
|
||||
|
||||
function showRebootInfo() {
|
||||
// Show info dialog.
|
||||
showInfoPopup(true, TITLE_DEVICE_REBOOTING, "Waiting for connectivity after reboot <span class=\"dots\"></span>");
|
||||
deviceRebooting = true;
|
||||
managementInfoRead = false;
|
||||
prevDeviceConnectionStatus = false;
|
||||
|
||||
var dotsInterval = setInterval(function() {
|
||||
var dots = $("#info_popup .dots");
|
||||
dots.text(dots.text() === "..." ? "" : dots.text() + ".");
|
||||
}, 2000);
|
||||
|
||||
setTimeout(function() {
|
||||
onConnectivity(function() {
|
||||
clearInterval(dotsInterval);
|
||||
showInfoPopup(false);
|
||||
showPopup(ID_LOADING_WRAPPER, "rebooted_dialog", true);
|
||||
});
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// Processes the response of the reboot device request.
|
||||
function processRebootDeviceResponse(response) {
|
||||
// Check if there was any error in the request.
|
||||
if (!checkErrorResponse(response, false))
|
||||
showRebootInfo();
|
||||
}
|
||||
|
||||
// Opens the firmware file browser.
|
||||
function openFirmwareBrowser() {
|
||||
if (is_local_access())
|
||||
openFileSystem(showButtons=false, filters=".swu");
|
||||
else
|
||||
document.getElementById(ID_UPDATE_FIRMWARE_FILE).click();
|
||||
}
|
||||
|
||||
// Reads the device status.
|
||||
function firmwareFileChanged(fileName="") {
|
||||
// Execute only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
closeFileSystem();
|
||||
// Initialize variables.
|
||||
var firmwareFileElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE);
|
||||
var firmwareFileLabelElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE_LABEL);
|
||||
// Hide progress bar.
|
||||
showFirmwareUpdateProgress(false);
|
||||
if (fileName == "" && firmwareFileElement.files.length == 0) {
|
||||
// No file selected.
|
||||
firmwareFileLabelElement.innerHTML = MESSAGE_NO_FILE_SELECTED;
|
||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, false);
|
||||
return;
|
||||
}
|
||||
var firmwareFile = "";
|
||||
// Build file path.
|
||||
if (is_local_access()) {
|
||||
firmwareFile = currentDirectory + fileName;
|
||||
// Hide the loading status.
|
||||
showFileSystemLoading(false);
|
||||
} else {
|
||||
firmwareFile = firmwareFileElement.files[0].name;
|
||||
}
|
||||
// Update firmware file name.
|
||||
firmwareFileLabelElement.innerHTML = firmwareFile;
|
||||
// Enable button.
|
||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, true);
|
||||
}
|
||||
|
||||
// Asks the user to confirm the firmware update action.
|
||||
function askUpdateFirmware() {
|
||||
showConfirmDialog(TITLE_CONFIRM_FIRMWARE_UPDATE, MESSAGE_CONFIRM_FIRMWARE_UPDATE,
|
||||
function() {
|
||||
// Sanity checks.
|
||||
var activeTab = getActiveFirmwareUpdateTab();
|
||||
if (activeTab == null)
|
||||
return;
|
||||
// Flag updating variable.
|
||||
updatingFirmware = true;
|
||||
// Hide the info popup.
|
||||
showInfoPopup(false);
|
||||
// Hide the loading popup.
|
||||
showLoadingPopup(false);
|
||||
// Disable firmware update button.
|
||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, false);
|
||||
// Show progress bar.
|
||||
showFirmwareUpdateProgress(true);
|
||||
// Disable management page controls.
|
||||
enableManagementPageControls(false);
|
||||
// Check active tab.
|
||||
if (activeTab == ID_FIRMWARE_TAB_UPLOAD) {
|
||||
if (!is_local_access())
|
||||
// Upload firmware.
|
||||
uploadFirmwareFile();
|
||||
else
|
||||
updateFirmware(document.getElementById(ID_UPDATE_FIRMWARE_FILE_LABEL).innerHTML);
|
||||
}
|
||||
},
|
||||
function() {
|
||||
// Do nothing.
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Attempts to upload the given firmware file.
|
||||
function uploadFirmwareFile() {
|
||||
// Initialize variables.
|
||||
var firmwareFileElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE);
|
||||
var firmwareFile = firmwareFileElement.files[0];
|
||||
// Update upload status.
|
||||
setFirmwareUpdateProgressInfo(0, MESSAGE_UPLOADING_FIRMWARE);
|
||||
// Prepare data.
|
||||
var formData = new FormData();
|
||||
formData.append("path", fwStorageDir + firmwareFile.name);
|
||||
formData.append("file", firmwareFile);
|
||||
formData.append("overwrite", true);
|
||||
// Send request.
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: "http://" + getServerAddress() + "/ajax/fs_upload_file",
|
||||
data: formData,
|
||||
cache: false,
|
||||
async: true,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
enctype: 'multipart/form-data',
|
||||
success: function(response) {
|
||||
// Reset request variable.
|
||||
uploadFirmwareAjaxRequest = null;
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Process answer.
|
||||
processUploadFirmwareFileResponse(response);
|
||||
},
|
||||
error: function(response) {
|
||||
// Reset request variable.
|
||||
uploadFirmwareAjaxRequest = null;
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Process error.
|
||||
error = processAjaxErrorResponse(response);
|
||||
// Update upload status.
|
||||
setFirmwareUpdateProgressError(error);
|
||||
// Flag updating variable.
|
||||
updatingFirmware = false;
|
||||
// Enable the management page controls.
|
||||
enableManagementPageControls(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Processes the upload firmware file response.
|
||||
function processUploadFirmwareFileResponse(response) {
|
||||
// Check if there was any error in the request.
|
||||
if (checkErrorResponse(response, false)) {
|
||||
error = getErrorFromResponse(response);
|
||||
// Update upload status.
|
||||
setFirmwareUpdateProgressError(error);
|
||||
// Flag updating variable.
|
||||
updatingFirmware = false;
|
||||
// Enable the management page controls.
|
||||
enableManagementPageControls(true);
|
||||
} else {
|
||||
// Update upload status.
|
||||
setFirmwareUpdateProgressInfo(100, MESSAGE_UPLOAD_COMPLETE);
|
||||
// Build file path.
|
||||
var firmwareFileElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE);
|
||||
var firmwareFile = firmwareFileElement.files[0];
|
||||
// Send the update request.
|
||||
updateFirmware(fwStorageDir + firmwareFile.name);
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the firmware of the device.
|
||||
function updateFirmware(filePath) {
|
||||
// Update status.
|
||||
setFirmwareUpdateProgressInfo(0, MESSAGE_SENDING_UPLOAD_REQUEST);
|
||||
// Send request to update the firmware.
|
||||
$.post(
|
||||
"http://" + getServerAddress() + "/ajax/update_firmware",
|
||||
JSON.stringify({
|
||||
"file": filePath
|
||||
}),
|
||||
function(data) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Process update firmware answer.
|
||||
processUpdateFirmwareResponse(data);
|
||||
}
|
||||
).fail(function(response) {
|
||||
// Flag updating variable.
|
||||
updatingFirmware = false;
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Process error.
|
||||
error = processAjaxErrorResponse(response);
|
||||
// Update upload status.
|
||||
setFirmwareUpdateProgressError(error);
|
||||
// Enable the management page controls.
|
||||
enableManagementPageControls(true);
|
||||
});
|
||||
}
|
||||
|
||||
// Processes the response of the update firmware request.
|
||||
function processUpdateFirmwareResponse(response) {
|
||||
// Check if there was any error in the request.
|
||||
if (checkErrorResponse(response, false)) {
|
||||
error = getErrorFromResponse(response);
|
||||
// Update upload status.
|
||||
setFirmwareUpdateProgressError(error);
|
||||
// Flag updating variable.
|
||||
updatingFirmware = false;
|
||||
// Enable the page controls.
|
||||
enableManagementPageControls(true);
|
||||
} else {
|
||||
// Update progress status.
|
||||
setFirmwareUpdateProgressInfo(100, MESSAGE_SENDING_FIRMWARE_UPDATE_REQUEST);
|
||||
// Start timer to check firmware update status periodically.
|
||||
startFirmwareUpdateTimer();
|
||||
// Check first firmware update status in 2 seconds.
|
||||
window.setTimeout(function () {
|
||||
checkFirmwareUpdateStatus();
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
// Starts a timer to check the firmware update status.
|
||||
function startFirmwareUpdateTimer() {
|
||||
// Sanity checks
|
||||
if (!isManagementShowing() || firmwareUpdateTimer != null)
|
||||
return;
|
||||
// Start timer to check firmware update status.
|
||||
firmwareUpdateTimer = setInterval(checkFirmwareUpdateStatus, FIRMWARE_UPDATE_CHECK_INTERVAL);
|
||||
}
|
||||
|
||||
// Stops the timer to check the firmware update status.
|
||||
function stopFirmwareUpdateTimer() {
|
||||
// Stop timer.
|
||||
if (firmwareUpdateTimer != null && firmwareUpdateTimer != "undefined") {
|
||||
clearInterval(firmwareUpdateTimer);
|
||||
firmwareUpdateTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Checks the firmware update status.
|
||||
function checkFirmwareUpdateStatus() {
|
||||
// Sanity checks
|
||||
if (!isManagementShowing()) {
|
||||
// Stop timer.
|
||||
stopFirmwareUpdateTimer();
|
||||
return;
|
||||
}
|
||||
// Send request to check firmware update status.
|
||||
$.post(
|
||||
"http://" + getServerAddress() + "/ajax/check_firmware_update_status",
|
||||
function(data) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Process check firmware update status answer.
|
||||
processCheckFirmwareUpdateStatusResponse(data);
|
||||
}
|
||||
).fail(function(response) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
$.get("http://" + getServerAddress() + "/ping", function() {
|
||||
// Process error.
|
||||
processAjaxErrorResponse(response);
|
||||
}).fail(function() {
|
||||
if (!deviceRebooting)
|
||||
showRebootInfo();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Processes the response of the check firmware update status request.
|
||||
function processCheckFirmwareUpdateStatusResponse(response) {
|
||||
// Check if there was any error in the request.
|
||||
if (!checkErrorResponse(response, false)) {
|
||||
// Check if the firmware update is running.
|
||||
if (response[ID_STATUS] == VALUE_ACTIVE) {
|
||||
// Check the firmware update progress.
|
||||
checkFirmwareUpdateProgress();
|
||||
} else if (response[ID_STATUS] == VALUE_FAILED || response[ID_STATUS] == VALUE_SUCCESSFUL || response[ID_STATUS] == VALUE_CANCELED) {
|
||||
// Stop timer.
|
||||
stopFirmwareUpdateTimer();
|
||||
// Flag the update variable.
|
||||
updatingFirmware = false;
|
||||
// Enable page controls.
|
||||
enableManagementPageControls(true);
|
||||
// Update the firmware update progress.
|
||||
if (response[ID_STATUS] == VALUE_FAILED || response[ID_STATUS] == VALUE_CANCELED)
|
||||
setFirmwareUpdateProgressError(ERROR_TITLE + ": " + response[ID_MESSAGE]);
|
||||
else {
|
||||
// Reset read info variable so info is read again after device reboots.
|
||||
managementInfoRead = false;
|
||||
// Set update as successful.
|
||||
setFirmwareUpdateProgressSuccess(response[ID_MESSAGE]);
|
||||
showRebootInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if there is a firmware update running.
|
||||
function checkFirmwareUpdateRunning() {
|
||||
// Sanity checks
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Hide the info popup.
|
||||
showInfoPopup(false);
|
||||
// Show the loading popup.
|
||||
showLoadingPopup(true, MESSAGE_CHECKING_FIRMWARE_UPDATE_STATUS);
|
||||
// Send request to check firmware update running.
|
||||
$.post(
|
||||
"http://" + getServerAddress() + "/ajax/check_firmware_update_running",
|
||||
function(data) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Hide the loading popup.
|
||||
showLoadingPopup(false);
|
||||
// Process check firmware update status answer.
|
||||
processCheckFirmwareUpdateRunningResponse(data);
|
||||
}
|
||||
).fail(function(response) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Hide the loading popup.
|
||||
showLoadingPopup(false);
|
||||
// Process error.
|
||||
processAjaxErrorResponse(response);
|
||||
});
|
||||
}
|
||||
|
||||
// Processes the response of the check firmware update running request.
|
||||
function processCheckFirmwareUpdateRunningResponse(response) {
|
||||
// Check if the firmware update is running.
|
||||
if (response[ID_UPDATE_RUNNING] == true) {
|
||||
// Flag the update variable.
|
||||
updatingFirmware = true;
|
||||
// Disable page controls.
|
||||
enableManagementPageControls(false);
|
||||
// Show firmware update progress.
|
||||
showFirmwareUpdateProgress(true);
|
||||
// Update the firmware update progress.
|
||||
setFirmwareUpdateProgressInfo(0, "");
|
||||
// Check the firmware update progress.
|
||||
checkFirmwareUpdateProgress();
|
||||
// Subscribe timer.
|
||||
startFirmwareUpdateTimer();
|
||||
}
|
||||
}
|
||||
|
||||
// Checks the firmware update progress.
|
||||
function checkFirmwareUpdateProgress() {
|
||||
// Sanity checks
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Hide the info popup.
|
||||
showInfoPopup(false);
|
||||
// Hide the loading popup.
|
||||
showLoadingPopup(false);
|
||||
// Send request to check firmware update progress.
|
||||
$.post(
|
||||
"http://" + getServerAddress() + "/ajax/check_firmware_update_progress",
|
||||
function(data) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Process check firmware update progress answer.
|
||||
processCheckFirmwareUpdateProgressResponse(data);
|
||||
}
|
||||
).fail(function(response) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Process error.
|
||||
processAjaxErrorResponse(response);
|
||||
});
|
||||
}
|
||||
|
||||
// Processes the response of the firmware update progress.
|
||||
function processCheckFirmwareUpdateProgressResponse(response) {
|
||||
// Check if there was any error in the request.
|
||||
if (!checkErrorResponse(response, false)) {
|
||||
// Update the firmware update progress.
|
||||
setFirmwareUpdateProgressInfo(response[ID_PROGRESS], response[ID_MESSAGE]);
|
||||
}
|
||||
}
|
||||
|
||||
// Enables/disables the management page controls.
|
||||
function enableManagementPageControls(enable) {
|
||||
// Reboot button.
|
||||
enableManagementButton(ID_REBOOT_BUTTON, enable);
|
||||
// Update firmware button.
|
||||
var activeTab = getActiveFirmwareUpdateTab();
|
||||
if (activeTab == ID_FIRMWARE_TAB_UPLOAD) {
|
||||
var firmwareFileElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE);
|
||||
if (firmwareFileElement.files.length == 0)
|
||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, false);
|
||||
else
|
||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, enable);
|
||||
}
|
||||
// Tabs.
|
||||
var tabUploadElement = document.getElementById(ID_FIRMWARE_TAB_UPLOAD);
|
||||
var tabUploadHeaderElement = document.getElementById(ID_FIRMWARE_TAB_UPLOAD_HEADER);
|
||||
if (enable) {
|
||||
tabUploadElement.classList.remove((CLASS_DISABLED_DIV));
|
||||
tabUploadHeaderElement.classList.remove((CLASS_DISABLED_DIV));
|
||||
} else {
|
||||
tabUploadElement.classList.add((CLASS_DISABLED_DIV));
|
||||
tabUploadHeaderElement.classList.add((CLASS_DISABLED_DIV));
|
||||
}
|
||||
}
|
||||
|
||||
// Enables/disables the given button ID
|
||||
function enableManagementButton(buttonID, enable) {
|
||||
// Initialize variables.
|
||||
var buttonElement = document.getElementById(buttonID);
|
||||
if (buttonElement != null) {
|
||||
if (enable) {
|
||||
if (buttonElement.classList.contains(CLASS_MANAGEMENT_BUTTON_DISABLED))
|
||||
buttonElement.classList.remove(CLASS_MANAGEMENT_BUTTON_DISABLED);
|
||||
} else
|
||||
buttonElement.classList.add(CLASS_MANAGEMENT_BUTTON_DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the active firmware update tab.
|
||||
function getActiveFirmwareUpdateTab() {
|
||||
// Initialize variables.
|
||||
var tabUploadHeaderElement = document.getElementById(ID_FIRMWARE_TAB_UPLOAD_HEADER);
|
||||
// Check the active tab.
|
||||
if (tabUploadHeaderElement.classList.contains(CLASS_FIRMWARE_TAB_HEADER_ACTIVE))
|
||||
return ID_FIRMWARE_TAB_UPLOAD;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
// Returns whether the device is rebooting or not.
|
||||
function isDeviceRebooting() {
|
||||
return deviceRebooting;
|
||||
}
|
||||
|
||||
// Returns whether firmware update is running or not.
|
||||
function isFirmwareUpdateRunning() {
|
||||
return updatingFirmware;
|
||||
}
|
||||
|
||||
// Shows the given firmware tab
|
||||
function showFirmwareTab(tabID) {
|
||||
// Initialize variables.
|
||||
var tabElement = document.getElementById(tabID);
|
||||
var tabHeaderElement = document.getElementById(tabID + "_header");
|
||||
if (tabElement != null && tabHeaderElement != null) {
|
||||
// Deselect all tab headers.
|
||||
var tabHeaders = document.getElementsByClassName(CLASS_FIRMWARE_TAB_HEADER);
|
||||
for (var i = 0; i < tabHeaders.length; i++) {
|
||||
var tabHeader = tabHeaders[i];
|
||||
if (tabHeader.classList.contains(CLASS_FIRMWARE_TAB_HEADER_ACTIVE))
|
||||
tabHeader.classList.remove(CLASS_FIRMWARE_TAB_HEADER_ACTIVE);
|
||||
}
|
||||
// Hide all the tabs.
|
||||
var tabs = document.getElementsByClassName(CLASS_FIRMWARE_TAB);
|
||||
for (var i = 0; i < tabs.length; i++) {
|
||||
var tab = tabs[i];
|
||||
tab.style.display = "none";
|
||||
}
|
||||
// Show the selected tab.
|
||||
tabHeaderElement.classList.add(CLASS_FIRMWARE_TAB_HEADER_ACTIVE);
|
||||
tabElement.style.display = "block";
|
||||
// Disable firmware update button.
|
||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, false);
|
||||
// Hide firmware update progress.
|
||||
showFirmwareUpdateProgress(false);
|
||||
// Perform additional actions on each tab.
|
||||
switch(tabID) {
|
||||
case ID_FIRMWARE_TAB_UPLOAD:
|
||||
// Check if there is a file in the file input.
|
||||
var firmwareFileElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE);
|
||||
if (firmwareFileElement.files.length > 0) {
|
||||
// Enable firmware update button.
|
||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shows/hides the firmware update progress section.
|
||||
function showFirmwareUpdateProgress(visible) {
|
||||
// Initialize variables.
|
||||
var firmwareUpdateProgressElement = document.getElementById(ID_UPDATE_FIRMWARE_PROGRESS);
|
||||
if (firmwareUpdateProgressElement != null) {
|
||||
if (visible)
|
||||
firmwareUpdateProgressElement.style.display = "block";
|
||||
else
|
||||
firmwareUpdateProgressElement.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
// Sets the firmware update progress.
|
||||
function setFirmwareUpdateProgressInfo(progress, message=null) {
|
||||
updateFirmwareUpdateProgress(UPDATE_INFO, progress, TITLE_FIRMWARE_UPDATE_IN_PROGRESS, message);
|
||||
}
|
||||
|
||||
// Sets the firmware update progress error.
|
||||
function setFirmwareUpdateProgressError(message=null) {
|
||||
updateFirmwareUpdateProgress(UPDATE_ERROR, 100, TITLE_FIRMWARE_UPDATE_ERROR, message);
|
||||
}
|
||||
|
||||
// Sets the firmware update progress success.
|
||||
function setFirmwareUpdateProgressSuccess(message=null) {
|
||||
updateFirmwareUpdateProgress(UPDATE_SUCCESS, 100, TITLE_FIRMWARE_UPDATE_SUCCESS, message);
|
||||
}
|
||||
|
||||
// Updates the firmware update progress.
|
||||
function updateFirmwareUpdateProgress(status, progress, title=null, message=null) {
|
||||
// Initialize variables.
|
||||
var firmwareUpdateProgressElement = document.getElementById(ID_UPDATE_FIRMWARE_PROGRESS);
|
||||
if (firmwareUpdateProgressElement != null) {
|
||||
// Update the progress bar.
|
||||
var progressBarElement = document.getElementById(ID_UPDATE_FIRMWARE_PROGRESS_BAR);
|
||||
if (progressBarElement != null) {
|
||||
// Update the progress bar status type.
|
||||
if (progressBarElement.classList.contains(CLASS_PROGRESS_BAR_INFO))
|
||||
progressBarElement.classList.remove(CLASS_PROGRESS_BAR_INFO);
|
||||
if (progressBarElement.classList.contains(CLASS_PROGRESS_BAR_ERROR))
|
||||
progressBarElement.classList.remove(CLASS_PROGRESS_BAR_ERROR);
|
||||
if (progressBarElement.classList.contains(CLASS_PROGRESS_BAR_SUCCESS))
|
||||
progressBarElement.classList.remove(CLASS_PROGRESS_BAR_SUCCESS);
|
||||
switch (status) {
|
||||
case UPDATE_INFO:
|
||||
progressBarElement.classList.add(CLASS_PROGRESS_BAR_INFO);
|
||||
break;
|
||||
case UPDATE_ERROR:
|
||||
progressBarElement.classList.add(CLASS_PROGRESS_BAR_ERROR);
|
||||
break;
|
||||
case UPDATE_SUCCESS:
|
||||
progressBarElement.classList.add(CLASS_PROGRESS_BAR_SUCCESS);
|
||||
break;
|
||||
}
|
||||
// Update the progress bar percent.
|
||||
if (progress != "?") {
|
||||
progressBarElement.style.width = progress + "%";
|
||||
progressBarElement.innerHTML = progress + "%";
|
||||
} else {
|
||||
let html = progressBarElement.innerHTML;
|
||||
if (html.startsWith("."))
|
||||
progressBarElement.innerHTML = html + ".";
|
||||
else
|
||||
progressBarElement.innerHTML = ".";
|
||||
}
|
||||
}
|
||||
// Update the progress title.
|
||||
var progressTitleElement = document.getElementById(ID_UPDATE_FIRMWARE_PROGRESS_TITLE);
|
||||
if (progressTitleElement != null) {
|
||||
if (title != null)
|
||||
progressTitleElement.innerHTML = title;
|
||||
else
|
||||
progressTitleElement.innerHTML = "";
|
||||
}
|
||||
// Update the progress message.
|
||||
var progressMessageElement = document.getElementById(ID_UPDATE_FIRMWARE_PROGRESS_MESSAGE);
|
||||
if (progressMessageElement != null) {
|
||||
if (message != null)
|
||||
progressMessageElement.innerHTML = message;
|
||||
else
|
||||
progressMessageElement.innerHTML = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright 2022, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
// Constants.
|
||||
|
||||
// Variables.
|
||||
var readingMultimediaInfo = false;
|
||||
var multimediaInfoRead = false;
|
||||
|
||||
// Initializes the multimedia page.
|
||||
function initializeMultimediaPage() {
|
||||
// Sanity checks.
|
||||
if (!isMultimediaShowing() || multimediaInfoRead)
|
||||
return;
|
||||
// Read multimedia information.
|
||||
readDeviceInfoMultimedia();
|
||||
}
|
||||
|
||||
// Gets the information of the device.
|
||||
function readDeviceInfoMultimedia() {
|
||||
// Execute only in the multimedia page.
|
||||
if (!isMultimediaShowing() || readingMultimediaInfo)
|
||||
return;
|
||||
// Flag reading variable.
|
||||
readingMultimediaInfo = true;
|
||||
// Hide the info popup.
|
||||
showInfoPopup(false);
|
||||
// Show the loading popup.
|
||||
showLoadingPopup(true, MESSAGE_LOADING_INFORMATION);
|
||||
// Send request to retrieve device information.
|
||||
$.post(
|
||||
"http://" + getServerAddress() + "/ajax/get_device_info",
|
||||
function(data) {
|
||||
readingMultimediaInfo = false;
|
||||
// Process only in the management page.
|
||||
if (!isMultimediaShowing())
|
||||
return;
|
||||
// Hide the loading panel.
|
||||
showLoadingPopup(false);
|
||||
// Process device information answer.
|
||||
processDeviceInfoMultimediaResponse(data);
|
||||
}
|
||||
).fail(function(response) {
|
||||
// Flag reading variable.
|
||||
readingMultimediaInfo = false;
|
||||
// Process only in the management page.
|
||||
if (!isMultimediaShowing())
|
||||
return;
|
||||
// Hide the loading panel.
|
||||
showLoadingPopup(false);
|
||||
// Process error.
|
||||
processAjaxErrorResponse(response);
|
||||
});
|
||||
}
|
||||
|
||||
// Processes the response of the device info request.
|
||||
function processDeviceInfoMultimediaResponse(response) {
|
||||
// Check if there was any error in the request.
|
||||
if (!checkErrorResponse(response, false)) {
|
||||
// Set the device type.
|
||||
updateFieldValue(ID_DEVICE_NAME, response[ID_DEVICE_TYPE].toUpperCase());
|
||||
// Flag device info read.
|
||||
multimediatInfoRead = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright 2022, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
// Hide submenus
|
||||
$("#body-row .collapse").collapse("hide");
|
||||
|
||||
// Collapse/Expand icon.
|
||||
$("#collapse-icon").addClass("fa-angle-double-left");
|
||||
|
||||
// Select click.
|
||||
$("#sections > a").click(function() {
|
||||
selectSection($(this));
|
||||
});
|
||||
|
||||
// Collapse click.
|
||||
$("[data-toggle=sidebar-collapse]").click(function() {
|
||||
sidebarCollapse();
|
||||
});
|
||||
|
||||
$(".element-grayed").click(function(){return false;});
|
||||
|
||||
// Selects the given item in the sidebar.
|
||||
function selectSection(selectedItem) {
|
||||
// Remove decorations of previously selected element.
|
||||
$("#sections .selected").removeClass(CLASS_SELECTED);
|
||||
|
||||
// Decorate the selected element.
|
||||
selectedItem.toggleClass(CLASS_SELECTED);
|
||||
}
|
||||
|
||||
// Collapses the sidebar to the left.
|
||||
function sidebarCollapse() {
|
||||
$(".menu-collapsed").toggleClass("d-none");
|
||||
$(".sidebar-submenu").toggleClass("d-none");
|
||||
$(".submenu-icon").toggleClass("d-none");
|
||||
|
||||
// Add/Remove right margin.
|
||||
$(".digi-menu-icon").toggleClass("mr-3 mr-0");
|
||||
|
||||
$("#sidebar-container").toggleClass("sidebar-expanded sidebar-collapsed");
|
||||
|
||||
// Treating d-flex/d-none on separators with title.
|
||||
var separatorTitle = $(".sidebar-separator-title");
|
||||
if (separatorTitle.hasClass("d-flex"))
|
||||
separatorTitle.removeClass("d-flex");
|
||||
else
|
||||
separatorTitle.addClass("d-flex");
|
||||
|
||||
// Collapse/Expand icon.
|
||||
$("#collapse-icon").toggleClass("fa-angle-double-left fa-angle-double-right");
|
||||
|
||||
// Make the cards the same height. Wait some time so size is
|
||||
// calculated after the content of the cards expands or collapses.
|
||||
window.setTimeout(function () {
|
||||
$(".adjust-card-height .card").matchHeight();
|
||||
}, 100);
|
||||
|
||||
if (isDashboardShowing()) {
|
||||
let refreshPanelsInterval = window.setInterval(adjustImageSize, 10);
|
||||
window.setTimeout(function () {
|
||||
window.clearInterval(refreshPanelsInterval);
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
|
||||
// Sets the selected section.
|
||||
function setSelectedSection(element=null) {
|
||||
// First, unselect all the sections.
|
||||
$("#sections li").each(function(i, n) {
|
||||
n.children[0].classList.remove(CLASS_SELECTED);
|
||||
});
|
||||
// Select the corresponding section.
|
||||
if (element != null) {
|
||||
element.classList.add(CLASS_SELECTED);
|
||||
} else {
|
||||
$("#sections li").each(function(i, n) {
|
||||
if (window.location.pathname == n.children[0].pathname) {
|
||||
n.children[0].classList.add(CLASS_SELECTED);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright 2020, Digi International Inc.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
const SEPARATOR = "@@@"
|
||||
|
||||
var currentTime;
|
||||
var timer;
|
||||
|
||||
function updateTime() {
|
||||
currentTime += 1;
|
||||
postMessage(new Date(1000 * currentTime).toISOString().substr(11, 8));
|
||||
}
|
||||
|
||||
onmessage = function (event) {
|
||||
var parts = event.data.split(SEPARATOR);
|
||||
currentTime = parseInt(parts[0]);
|
||||
var factor = parseInt(parts[1]);
|
||||
setInterval(updateTime, 1000 / factor);
|
||||
};
|
||||