You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
812 lines
35 KiB
812 lines
35 KiB
<html>
|
|
<head>
|
|
<!-- Materialze style -->
|
|
<link rel="stylesheet" type="text/css" href="../../css/adapter.css"/>
|
|
<link rel="stylesheet" type="text/css" href="../../lib/css/materialize.css">
|
|
|
|
<script type="text/javascript" src="../../lib/js/jquery-3.2.1.min.js"></script>
|
|
<script type="text/javascript" src="../../socket.io/socket.io.js"></script>
|
|
|
|
<script type="text/javascript" src="engines.js"></script>
|
|
<script type="text/javascript" src="../../js/translate.js"></script>
|
|
<script type="text/javascript" src="../../lib/js/materialize.js"></script>
|
|
<script type="text/javascript" src="../../js/adapter-settings.js"></script>
|
|
<script type="text/javascript" src="words.js"></script>
|
|
<style>
|
|
#drop_zone {
|
|
border: 2px dashed #bbb;
|
|
-moz-border-radius: 5px;
|
|
-webkit-border-radius: 5px;
|
|
border-radius: 5px;
|
|
padding: 25px;
|
|
text-align: center;
|
|
font-size: 20pt;
|
|
font-weight: bold;
|
|
font-family: 'Arial';
|
|
color: #bbb;
|
|
width: 90%;
|
|
height: 60px;
|
|
}
|
|
|
|
.error {
|
|
border: 2px solid red;
|
|
}
|
|
</style>
|
|
<script type="text/javascript">
|
|
var webServers = null;
|
|
var gOnChange;
|
|
|
|
function showHideSettings() {
|
|
$('.variable').hide();
|
|
var type = $('#type').val();
|
|
for (var j = 0; j < sayitOptions[type].params.length; j++) {
|
|
$('#tr_' + sayitOptions[type].params[j]).show();
|
|
}
|
|
|
|
if (type === 'googleHome') {
|
|
$('.announceValue').hide();
|
|
$('.announce').hide();
|
|
$('.system').hide();
|
|
$('.googleHome').show();
|
|
|
|
getIsAdapterAlive(function (isAlive) {
|
|
if (isAlive || common.enabled) {
|
|
$('#search').removeClass('disabled');
|
|
fillGoogleHome();
|
|
}
|
|
});
|
|
} else {
|
|
$('.googleHome').hide();
|
|
$('.announceValue').show();
|
|
$('.announce').show();
|
|
}
|
|
|
|
$('.engine').hide();
|
|
var engine = $('#engine').val();
|
|
|
|
if (!sayitEngines[engine] || sayitOptions[type].params.indexOf('engine') === -1) return;
|
|
|
|
for (var i = 0; i < sayitEngines[engine].params.length; i++) {
|
|
$('#tr_' + sayitEngines[engine].params[i]).show();
|
|
if (sayitEngines[engine][sayitEngines[engine].params[i]]) {
|
|
var arr = sayitEngines[engine][sayitEngines[engine].params[i]];
|
|
var param = sayitEngines[engine].params[i];
|
|
|
|
var $val = $('#' + param);
|
|
if (arr.length) {
|
|
var val = $val.val();
|
|
var text = '';
|
|
for (var p = 0; p < arr.length; p++) {
|
|
text += '<option value="' + arr[p] + '">' + arr[p] + '</option>';
|
|
}
|
|
$val.html(text);
|
|
if (val) {
|
|
$val.val(val);
|
|
} else {
|
|
$val.val(arr[0]);
|
|
}
|
|
} else {
|
|
$val.html('');
|
|
}
|
|
}
|
|
}
|
|
if (type !== 'system') {
|
|
$('.system').hide();
|
|
} else {
|
|
$('.system').show();
|
|
}
|
|
|
|
if (!$('#announce').val()) {
|
|
$('.announce').hide();
|
|
$('#play').addClass('disabled');
|
|
} else {
|
|
$('.announce').show();
|
|
$('#play').removeClass('disabled');
|
|
}
|
|
}
|
|
|
|
function fillSonosDevices(elem, current) {
|
|
socket.emit('getObjectView', 'system', 'channel', {startkey: 'sonos.', endkey: 'sonos.\u9999'}, function (err, res) {
|
|
if (!err && res) {
|
|
for (var i = 0; i < res.rows.length; i++) {
|
|
$(elem).append('<option value="' + res.rows[i].id + '">' + res.rows[i].id + '</option>');
|
|
}
|
|
$(elem).select();
|
|
}
|
|
$(elem).val(current);
|
|
});
|
|
}
|
|
|
|
function fillMpdDevice(elem, current) {
|
|
socket.emit('getObjectView', 'system', 'instance', {startkey: 'system.adapter.mpd.', endkey: 'system.adapter.mpd.\u9999'}, function (err, res) {
|
|
if (!err && res) {
|
|
for (var i = 0; i < res.rows.length; i++) {
|
|
var n = res.rows[i].id.replace('system.adapter.', '');
|
|
$(elem).append('<option value="' + n + '">' + n + '</option>');
|
|
}
|
|
$(elem).select();
|
|
}
|
|
$(elem).val(current);
|
|
});
|
|
}
|
|
|
|
function fillChromecastDevices(elem, current) {
|
|
socket.emit('getObjectView', 'system', 'device', {startkey: 'chromecast.', endkey: 'chromecast.\u9999'}, function (err, res) {
|
|
if (!err && res) {
|
|
for (var i = 0; i < res.rows.length; i++) {
|
|
$(elem).append('<option value="' + res.rows[i].id + '">' + res.rows[i].id + '</option>');
|
|
}
|
|
}
|
|
$(elem).select();
|
|
$(elem).val(current);
|
|
});
|
|
}
|
|
|
|
function fillGoogleHome() {
|
|
$('#search').addClass('disabled');
|
|
sendTo(null, 'browseChromecast', null, function (list) {
|
|
var text = '<option value="">' + _('select') + '</option>';
|
|
if (list) {
|
|
for (var i = 0; i < list.length; i++) {
|
|
text += '<option value="' + list[i].ip + '">' + list[i].name + '[' + list[i].ip + ']</option>';
|
|
}
|
|
$('#googleHome').html(text).prop('disabled', false).off('change').on('change', function () {
|
|
$('#server').val($(this).val()).trigger('change');
|
|
});
|
|
} else {
|
|
$('#googleHome').html('<option value="">' + _('error') + '</option>').prop('disabled', true);
|
|
}
|
|
$('#search').removeClass('disabled');
|
|
$('#googleHome').select();
|
|
});
|
|
}
|
|
|
|
function ip2hex(ip) {
|
|
var octets = ip.split('.');
|
|
if (octets.length !== 4) {
|
|
return 0;
|
|
}
|
|
var result = 0;
|
|
for (var i = 0; i < octets.length; ++i) {
|
|
var octet = parseInt(octets[i], 10);
|
|
if (Number.isNaN(octet) || octet < 0 || octet > 255) {
|
|
throw new Error("Each octet must be between 0 and 255");
|
|
}
|
|
result |= octet << ((octets.length - i) * 8);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function checkWeb(elem, current) {
|
|
var web = $('#web').val();
|
|
for (var i = 0; i < webServers.length; i++) {
|
|
if (webServers[i].id === 'system.adapter.' + web) {
|
|
if (webServers[i].value.native.auth) {
|
|
showMessage(_('Cannot use web server with authentication'), null, 'info');
|
|
}
|
|
if (webServers[i].value.native.bind === 'localhost' || webServers[i].value.native.bind === '127.0.0.1' || webServers[i].value.native.bind === '::1') {
|
|
showMessage(_('Cannot use web server only on localhost'), null, 'info');
|
|
}
|
|
|
|
if (webServers[i].value.native.bind === '0.0.0.0') {
|
|
$('#tr_webServer').show();
|
|
var $webServer = $('#webServer');
|
|
$webServer.html('');
|
|
// read all ipv4 addresses of host
|
|
socket.emit('getObject', 'system.host.' + webServers[i].value.common.host, function (err, obj) {
|
|
var text = '';
|
|
if (!err && obj && obj.native) {
|
|
for (var iface in obj.native.hardware.networkInterfaces) {
|
|
if (obj.native.hardware.networkInterfaces.hasOwnProperty(iface)) {
|
|
for (var i = 0; i < obj.native.hardware.networkInterfaces[iface].length; i++) {
|
|
if (obj.native.hardware.networkInterfaces[iface][i].family === 'IPv4' && !obj.native.hardware.networkInterfaces[iface][i].internal) {
|
|
text += '<option value="' + obj.native.hardware.networkInterfaces[iface][i].address + '" data-mask="' + obj.native.hardware.networkInterfaces[iface][i].netmask + '">[IPv4] ' + obj.native.hardware.networkInterfaces[iface][i].address + ' - ' + iface + '</option>';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$webServer.html(text);
|
|
if (current) {
|
|
$webServer.val(current);
|
|
}
|
|
$webServer.select();
|
|
|
|
$webServer.off('change').on('change', function () {
|
|
gOnChange();
|
|
var ip = $(this).val();
|
|
var netmask = $(this).find('option[value="' + ip + '"]').data('mask');
|
|
var server;
|
|
var type = $('#type').val();
|
|
if (type === 'googleHome') {
|
|
server = $('#server').val();
|
|
} else if (type === 'sonos') {
|
|
server = $('#device').val().split('.')[3].replace('_', '.').replace('_', '.').replace('_', '.');
|
|
} else if (type === 'chromecast') {
|
|
server = $('#cDevice').val();
|
|
} else if (type === 'mpd') {
|
|
server = $('#mpd_device').val();
|
|
}
|
|
if (server && ip && netmask && server.indexOf(':') === -1 && ip.indexOf(':') === -1) {
|
|
ip = ip2hex(ip);
|
|
netmask = ip2hex(netmask);
|
|
server = ip2hex(server);
|
|
if ((ip & netmask) !== (server & netmask)) {
|
|
$webServer.addClass('error').attr('title', _('IP not accessible for server'));
|
|
} else {
|
|
$webServer.removeClass('error').attr('title', '');
|
|
}
|
|
} else {
|
|
$webServer.removeClass('error');
|
|
}
|
|
});
|
|
});
|
|
} else if (webServers[i].value.native.bind === '::') {
|
|
// read all ipv6 addresses of host
|
|
socket.emit('getObject', 'system.host.' + webServers[i].value.common.host, function (err, obj) {
|
|
if (!err && obj && obj.native) {
|
|
for (var iface in obj.native.hardware.networkInterfaces) {
|
|
if (obj.native.hardware.networkInterfaces.hasOwnProperty(iface)) {
|
|
for (var i = 0; i < obj.native.hardware.networkInterfaces[iface].length; i++) {
|
|
if (obj.native.hardware.networkInterfaces[iface][i].family === 'IPv6' && !obj.native.hardware.networkInterfaces[iface][i].internal) {
|
|
$('#webServer').append('<option value="' + obj.native.hardware.networkInterfaces[iface][i].address + '">[IPv6] ' + obj.native.hardware.networkInterfaces[iface][i].address + ' - ' + iface + '</option>');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (current) {
|
|
$('#webServer').val(current);
|
|
}
|
|
});
|
|
$('#webServer').select();
|
|
} else {
|
|
$('#tr_webServer').hide();
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
function fillWebServices(elem, current, type, webServer) {
|
|
socket.emit('getObjectView', 'system', 'instance', {startkey: 'system.adapter.web.', endkey: 'system.adapter.web.\u9999'}, function (err, res) {
|
|
if (!err && res) {
|
|
webServers = res.rows;
|
|
for (var i = 0; i < res.rows.length; i++) {
|
|
var n = res.rows[i].id.replace('system.adapter.', '');
|
|
var auth = res.rows[i].value.native.auth ? 'data-auth="true"' : '';
|
|
$(elem).append('<option value="' + n + '" ' + auth + '>' + n + '</option>');
|
|
}
|
|
}
|
|
$(elem).val(current);
|
|
if ((type === 'sonos') ||
|
|
(type === 'chromecast') ||
|
|
(type === 'googleHome')) {
|
|
checkWeb('#web', webServer);
|
|
}
|
|
|
|
$(elem).select();
|
|
});
|
|
}
|
|
|
|
function uploadFile(file, callback) {
|
|
var reader = new FileReader();
|
|
|
|
// Closure to capture the file information.
|
|
reader.onload = function(e) {
|
|
socket.emit('writeFile', 'sayit.' + instance, 'tts.userfiles/' + file.name, e.target.result, function () {
|
|
if (callback) callback(file.name);
|
|
});
|
|
};
|
|
|
|
// Read in the image file as a data URL.
|
|
reader.readAsArrayBuffer(file);
|
|
}
|
|
|
|
function handleFileSelect(evt) {
|
|
var files = evt.target.files; // FileList object
|
|
$('#drop_indcator').hide();
|
|
|
|
// files is a FileList of File objects. List some properties.
|
|
var count = 0;
|
|
for (var i = 0, f; f = files[i]; i++) {
|
|
if (f.size > 1024 * 1024) {
|
|
showMessage(_('File %s is too big. Maximum 1MB', escape(f.name)));
|
|
$('#files').val('');
|
|
return;
|
|
}
|
|
if (f.name === 'say.mp3') {
|
|
showMessage(_('Name say.mp3 is reserved'));
|
|
$('#files').val('');
|
|
return;
|
|
}
|
|
count++;
|
|
uploadFile(f, function (name) {
|
|
count--;
|
|
if (!count) {
|
|
// Read names of files for gong
|
|
socket.emit('readDir', 'sayit.' + instance, 'tts.userfiles', function (err, dir) {
|
|
var text = '<option value="">' + _('none') + '</option>';
|
|
if (dir) {
|
|
for (var i = 0; i < dir.length; i++) {
|
|
if (dir[i].isDir) continue;
|
|
text += '<option value="' + dir[i].file + '">' + dir[i].file + '</option>';
|
|
}
|
|
}
|
|
$('#announce').html(text).val(name).trigger('change');
|
|
$('#announce').select();
|
|
$('#files').val('');
|
|
});
|
|
}
|
|
});
|
|
|
|
}
|
|
}
|
|
|
|
function handleFileSelectDrop(evt) {
|
|
$('#drop_indcator').hide();
|
|
evt.stopPropagation();
|
|
evt.preventDefault();
|
|
|
|
var files = evt.dataTransfer.files; // FileList object.
|
|
|
|
// files is a FileList of File objects. List some properties.
|
|
var output = [];
|
|
for (var i = 0, f; f = files[i]; i++) {
|
|
if (f.size > 1024 * 1024) {
|
|
showMessage(_('File %s is too big. Maximum 1MB', escape(f.name)));
|
|
return;
|
|
}
|
|
console.log(escape(f.name));
|
|
}
|
|
}
|
|
|
|
function handleDragOver(evt) {
|
|
evt.stopPropagation();
|
|
evt.preventDefault();
|
|
evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
|
|
$('#drop_indcator').show();
|
|
}
|
|
|
|
// the function loadSettings has to exist ...
|
|
function load(settings, onChange) {
|
|
if (!settings) return;
|
|
|
|
if (!settings.player) {
|
|
settings.player = 'mpg321';
|
|
}
|
|
gOnChange = onChange;
|
|
|
|
$('#play').on('click', function () {
|
|
socket.emit('readFile', 'sayit.' + instance, 'tts.userfiles/' + $('#announce').val(), function (err, data) {
|
|
if (typeof AudioContext !== 'undefined') {
|
|
context = new AudioContext();
|
|
context.decodeAudioData(data, function(buffer) {
|
|
//console.log(buffer);
|
|
var source = context.createBufferSource(); // creates a sound source
|
|
source.buffer = buffer; // tell the source which sound to play
|
|
source.connect(context.destination); // connect the source to the context's destination (the speakers)
|
|
source.start(0);
|
|
}, function(err) {
|
|
console.log(err);
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
var $t = $('#type');
|
|
for (name in sayitOptions) {
|
|
if (sayitOptions.hasOwnProperty(name)) {
|
|
$t.append('<option value="' + name + '">' + sayitOptions[name].name + '</option>');
|
|
}
|
|
}
|
|
|
|
$('#search').on('click', function () {
|
|
fillGoogleHome();
|
|
});
|
|
|
|
getIsAdapterAlive(function (isAlive) {
|
|
if (isAlive || common.enabled) {
|
|
$('#search').removeClass('disabled');
|
|
if (settings.type === 'googleHome') {
|
|
fillGoogleHome();
|
|
}
|
|
} else {
|
|
$('#search').addClass('disabled').attr('title', _('Adapter must be enabled'));
|
|
}
|
|
});
|
|
|
|
var $e = $('#engine');
|
|
for (var name in sayitEngines) {
|
|
if (sayitEngines.hasOwnProperty(name)) {
|
|
$e.append('<option value="' + name + '">' + sayitEngines[name].name + '</option>');
|
|
}
|
|
}
|
|
for (var key in settings) {
|
|
if (settings.hasOwnProperty(key)) {
|
|
var $val = $('#' + key + '.value');
|
|
if ($val.attr('type') === 'checkbox') {
|
|
$val.prop('checked', settings[key]);
|
|
} else {
|
|
$val.val(settings[key]);
|
|
}
|
|
}
|
|
}
|
|
|
|
$('.value').on('change', function () {
|
|
var key = $(this).attr('id');
|
|
|
|
if (key === 'auth') {
|
|
if ($('#auth').prop('checked')) {
|
|
$('#secure').prop('checked', true);
|
|
}
|
|
} else
|
|
if (key === 'type' || key === 'engine') {
|
|
showHideSettings();
|
|
var type = $('#type').val();
|
|
if ((type === 'sonos') ||
|
|
(type === 'chromecast') ||
|
|
(type === 'mpd') ||
|
|
(type === 'googleHome')) {
|
|
checkWeb('#web');
|
|
$('#announce').val('').trigger('change');
|
|
showHideSettings();
|
|
} else {
|
|
showHideSettings();
|
|
}
|
|
} else
|
|
if (key === 'announce') {
|
|
showHideSettings();
|
|
if ($(this).val()) {
|
|
socket.emit('readFile', 'sayit.' + instance, 'tts.userfiles/' + $('#announce').val(), function (err, data) {
|
|
if (typeof AudioContext !== 'undefined') {
|
|
context = new AudioContext();
|
|
context.decodeAudioData(data, function (buffer) {
|
|
$('#annoDuration').val(Math.ceil(buffer.duration));
|
|
}, function (err) {
|
|
console.log(err);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
if (key === 'web') {
|
|
checkWeb('#web');
|
|
}
|
|
onChange();
|
|
}).keyup(function() {
|
|
$(this).trigger('change');
|
|
});
|
|
|
|
if (!settings.engine) {
|
|
settings.engine = systemLang;
|
|
$('#engine').val(systemLang).trigger('change');
|
|
}
|
|
if (!settings.instance) {
|
|
settings.instance = 'FFFFFFFF';
|
|
$('#instance').val(settings.instance).trigger('change');
|
|
}
|
|
|
|
fillSonosDevices('#device', settings.device);
|
|
fillChromecastDevices('#cDevice', settings.cDevice);
|
|
fillWebServices('#web', settings.web, settings.type, settings.webServer);
|
|
fillMpdDevice('#mpd_device', settings.mpd_device);
|
|
|
|
if ((settings.type === 'sonos') ||
|
|
(settings.type === 'chromecast') ||
|
|
(settings.type === 'mpd') ||
|
|
(settings.type === 'googleHome')){
|
|
$('.announce').hide();
|
|
if (settings.announce) {
|
|
$('#announce').val('').trigger('change');
|
|
}
|
|
}
|
|
// Read names of files for gong
|
|
socket.emit('readDir', 'sayit.' + instance, 'tts.userfiles', function (err, dir) {
|
|
var text = '<option value="">' + _('none') + '</option>';
|
|
if (dir) {
|
|
for (var i = 0; i < dir.length; i++) {
|
|
if (dir[i].isDir) continue;
|
|
text += '<option value="' + dir[i].file + '">' + dir[i].file + '</option>';
|
|
}
|
|
}
|
|
$('#announce').html(text).val(settings.announce);
|
|
showHideSettings();
|
|
});
|
|
|
|
getAdapterInstances('cloud', function (list) {
|
|
if (list) {
|
|
var text = '';
|
|
for (var i = 0; i < list.length; i++) {
|
|
var id = list[i]._id.substring('system.adapter.'.length);
|
|
text += '<option value="' + id + '" ' + (id === settings.cloud ? 'selected' : '') + '>' + id + '</option>';
|
|
}
|
|
if (text) $('#cloud').html(text);
|
|
}
|
|
});
|
|
|
|
$('#voice').val(settings.voice);
|
|
var w = $('#engine').width();
|
|
$('#announce').css({width: w});
|
|
$('#type').css({width: w});
|
|
|
|
|
|
document.getElementById('files').addEventListener('change', handleFileSelect, false);
|
|
showHideSettings();
|
|
|
|
if (!$('#announce').val()) $('#play').addClass('disabled');
|
|
if (typeof AudioContext === 'undefined') $('#play').hide();
|
|
|
|
var dropZone = document.getElementById('drop_zone');
|
|
if (dropZone) {
|
|
dropZone.addEventListener('dragover', handleDragOver, false);
|
|
dropZone.addEventListener('drop', handleFileSelect, false);
|
|
/*dropZone.addEventListener('dragend', function () {
|
|
$(this).css({background: 'white'});
|
|
console.log('dragend');
|
|
return false;
|
|
}, false);
|
|
dropZone.addEventListener('dragstart', function () {
|
|
console.log('dragstart');
|
|
}, false);
|
|
dropZone.addEventListener('dragleave', function () {
|
|
$(this).css({background: 'white'});
|
|
}, false);
|
|
dropZone.addEventListener('dragenter', function () {
|
|
$(this).css({background: 'gray'});
|
|
}, false);*/
|
|
}
|
|
|
|
onChange(false);
|
|
}
|
|
|
|
function save(callback) {
|
|
var obj = {};
|
|
$('.value').each(function () {
|
|
var $this = $(this);
|
|
if ($this.attr('type') === 'checkbox') {
|
|
obj[$this.attr('id')] = $this.prop('checked');
|
|
} else {
|
|
obj[$this.attr('id')] = $this.val();
|
|
}
|
|
});
|
|
|
|
if (obj.engine && sayitEngines[obj.engine].engine === 'yandex') {
|
|
if (!obj.key) {
|
|
showMessage(_('API Key is not set!'));
|
|
return;
|
|
}
|
|
} else
|
|
if (obj.engine && sayitEngines[obj.engine].engine === 'polly') {
|
|
if (!obj.accessKey || !obj.secretKey) {
|
|
showMessage(_('API Key is not set!'));
|
|
return;
|
|
}
|
|
if (!obj.region) {
|
|
showMessage(_('AWS Region is not set!'));
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (obj.type === 'googleHome') {
|
|
obj.cache = false;
|
|
}
|
|
|
|
callback(obj);
|
|
}
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div class="m adapter-container" ondragover="return false" ondrop="return false">
|
|
<div class="row">
|
|
<div class="col s12">
|
|
<div class="row">
|
|
<div class="col s6">
|
|
<img src="sayit.png" class="logo">
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="input-field col s6 m4">
|
|
<select class="value" id="type"></select>
|
|
<label class="translate" for="type">Type:</label>
|
|
</div>
|
|
<div class="input-field col s6 m4" id="tr_engine" >
|
|
<select class="value" id="engine"></select>
|
|
<label class="translate" for="engine">Language:</label>
|
|
</div>
|
|
</div>
|
|
<div class="row system">
|
|
<div class="input-field col s6 m4">
|
|
<select class="value" id="player" >
|
|
<option value="mpg321">mpg321</option>
|
|
<option value="omxplayer">omxplayer</option>
|
|
</select>
|
|
<label for="player"><span class="translate">Linux player:</span><span class="translate" style="padding-left: 10px; font-size: 10px">Ignore for non linux OS</span></label>
|
|
</div>
|
|
<div class="input-field col s6 m4 l2">
|
|
<input class="value" id="command"/>
|
|
<label class="translate" for="command">System command:</label>
|
|
</div>
|
|
</div>
|
|
<div class="row announceValue">
|
|
<div class="input-field col s6 m4">
|
|
<select class="value" id="announce"></select>
|
|
<label class="translate" for="announce">Announce:</label>
|
|
<a class="waves-effect waves-light btn translate" id="play">play</a>
|
|
</div>
|
|
<div class="file-field input-field col s6 m4">
|
|
<div class="btn">
|
|
<span class="translate">File</span>
|
|
<input type="file" accept=".mp3,audio/*" id="files" name="files[]" multiple />
|
|
</div>
|
|
<div class="file-path-wrapper">
|
|
<input class="file-path validate" type="text">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row announce">
|
|
<div class="input-field col s4 m4 l2">
|
|
<input class="value" id="annoTimeout" type="number" min="0" max="1000" />
|
|
<label class="translate" for="annoTimeout">Announce timeout (sec):</label>
|
|
</div>
|
|
<div class="input-field col s4 m4 l2">
|
|
<input class="value" id="annoDuration" type="number" min="0" max="99"/>
|
|
<label class="translate" for="annoDuration">Announce length (sec):</label>
|
|
</div>
|
|
<div class="input-field col s4 m4 l2">
|
|
<input class="value" id="annoVolume" type="number" min="0" max="100"/>
|
|
<label class="translate" for="annoVolume">Announce volume (%):</label>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
|
|
</div>
|
|
|
|
<div class="row variable">
|
|
<div class="input-field col s6 m4" id="tr_cache">
|
|
<input class="value" id="cache" type="checkbox" />
|
|
<label class="translate" for="cache">Cache:</label>
|
|
</div>
|
|
<div class="input-field col s6 m4" id="tr_cacheExpiryDays" >
|
|
<input class="value" id="cacheExpiryDays" size="5" />
|
|
<label class="translate" for="tr_cacheExpiryDays">Cache-Expiry:</label>
|
|
</div>
|
|
</div>
|
|
<div id="tr_server" class="row variable">
|
|
<div class="input-field col s6 m4 l2">
|
|
<input class="value" id="server"/>
|
|
<label class="translate" for="server">Server:</label>
|
|
<select class="value googleHome" id="googleHome">
|
|
<option value="" class="translate">none</option>
|
|
</select>
|
|
<a class="waves-effect waves-light btn translate googleHome" style="font-size: 10px; margin-left: 10px;" id="search">Browse</a>
|
|
</div>
|
|
</div>
|
|
<div id="tr_port" class="row variable">
|
|
<div class="input-field col s6 m4 l2">
|
|
<input class="value" id="port" size="5" maxlength="5"/>
|
|
<label class="translate" for="port">Port:</label>
|
|
</div>
|
|
</div>
|
|
<div class="row variable">
|
|
<div id="tr_user" class="input-field col s6 m4 l2">
|
|
<input class="value" id="user" />
|
|
<label class="translate" for="user">User:</label>
|
|
</div>
|
|
<div id="tr_pass"class="input-field col s6 m4 l2">
|
|
<input class="value" id="pass" />
|
|
<label class="translate" for="pass">Password:</label>
|
|
</div>
|
|
</div>
|
|
<div id="tr_instance" class="row variable">
|
|
<div class="input-field col s6 m4 l2">
|
|
<label class="translate" for="instance">Browser instance:</label>
|
|
<input class="value" id="instance" />
|
|
</div>
|
|
</div>
|
|
<div id="tr_device" class="row variable">
|
|
<div class="input-field col s6 m4 l2">
|
|
<select class="value" id="device">
|
|
<option value="" class="translate">All</option>
|
|
</select>
|
|
<label class="translate" for="device">Device:</label>
|
|
</div>
|
|
</div>
|
|
<div id="tr_cDevice" class="row variable">
|
|
<div class="input-field col s6 m4 l2">
|
|
<select class="value" id="cDevice">
|
|
<option value="" class="translate">All</option>
|
|
</select>
|
|
<label class="translate" for="cDevice">Device:</label>
|
|
</div>
|
|
</div>
|
|
<div id="tr_mpd_device" class="row variable">
|
|
<div class="input-field col s6 m4 l2">
|
|
<select class="value" id="mpd_device">
|
|
<option value="" class="translate">All</option>
|
|
</select>
|
|
<label class="translate" for="mpd_device">Device:</label>
|
|
</div>
|
|
</div>
|
|
<div id="tr_web" class="row variable">
|
|
<div class="input-field col s6 m4 l2">
|
|
<select class="value" id="web"></select>
|
|
<label class="translate" for="web">Web instance:</label>
|
|
</div>
|
|
</div>
|
|
<div id="tr_webServer" class="row variable">
|
|
<div class="input-field col s6 m4 l2">
|
|
<select class="value" id="webServer"></select>
|
|
<label class="translate" for="webServer">Web server IP:</label>
|
|
</div>
|
|
</div>
|
|
<div id="tr_voice" class="row engine" >
|
|
<div class="input-field col s6 m4 l2">
|
|
<select class="value" id="voice"></select>
|
|
<label class="translate" for="voice">Voice:</label>
|
|
</div>
|
|
</div>
|
|
<div id="tr_key" class="row engine" >
|
|
<div class="input-field col s6 m4 l2">
|
|
<input class="value" id="key" type="text"/>
|
|
<label class="translate" for="key">API Key:</label>
|
|
</div>
|
|
</div>
|
|
<div id="tr_emotion" class="row engine" >
|
|
<div class="input-field col s6 m4 l2">
|
|
<select class="value" id="emotion"></select>
|
|
<label class="translate" for="emotion">Emotion:</label>
|
|
</div>
|
|
</div>
|
|
<div id="tr_drunk" class="row engine" >
|
|
<div class="input-field col s6 m4 l2">
|
|
<input type="checkbox" class="value" id="drunk"/>
|
|
<label class="translate" for="drunk">Drunk:</label>
|
|
</div>
|
|
</div>
|
|
<div id="tr_ill" class="row engine" >
|
|
<div class="input-field col s6 m4 l2">
|
|
<input type="checkbox" class="value" id="ill"/>
|
|
<label class="translate" for="ill">Ill:</label>
|
|
</div>
|
|
</div>
|
|
<div id="tr_robot" class="row engine" >
|
|
<div class="input-field col s6 m4 l2">
|
|
<input type="checkbox" class="value" id="robot"/>
|
|
<label class="translate" for="robot">Robot:</label>
|
|
</div>
|
|
</div>
|
|
<div id="tr_accessKey" class="row engine" >
|
|
<div class="input-field col s6 m4 l2">
|
|
<label class="translate" for="accessKey">Access Key:</label>
|
|
<input class="value" id="accessKey" type="text"/>
|
|
</div>
|
|
</div>
|
|
<div id="tr_secretKey" class="row engine" >
|
|
<div class="input-field col s6 m4 l2">
|
|
<label class="translate" for="secretKey">Secret Key:</label>
|
|
<input class="value" id="secretKey" type="password"/>
|
|
</div>
|
|
</div>
|
|
<div id="tr_region" class="row engine" >
|
|
<div class="input-field col s6 m4 l2">
|
|
<input class="value" id="region" type="text"/>
|
|
<label class="translate" for="region">AWS Region:</label>
|
|
</div>
|
|
</div>
|
|
<div id="tr_cloud" class="row engine" >
|
|
<div class="input-field col s6 m4 l2">
|
|
<select class="value" id="cloud">
|
|
<option value="" class="translate">Install first cloud adapter</option>
|
|
</select>
|
|
<label class="translate" for="cloud">Cloud instance:</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="drop_zone" style="display: none" class="translate">place here</div>
|
|
</div>
|
|
</body>
|
|
</html>
|