Merge branch 'main' of git.kaiyuancloud.cn:yumoqing/bricks
2
3parties/xterm-addon-fit.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.FitAddon=t():e.FitAddon=t()}(window,function(){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=0)}([function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(){}return e.prototype.activate=function(e){this._terminal=e},e.prototype.dispose=function(){},e.prototype.fit=function(){var e=this.proposeDimensions();if(e&&this._terminal){var t=this._terminal._core;this._terminal.rows===e.rows&&this._terminal.cols===e.cols||(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}},e.prototype.proposeDimensions=function(){if(this._terminal&&this._terminal.element&&this._terminal.element.parentElement){var e=this._terminal._core,t=window.getComputedStyle(this._terminal.element.parentElement),r=parseInt(t.getPropertyValue("height")),n=Math.max(0,parseInt(t.getPropertyValue("width"))),o=window.getComputedStyle(this._terminal.element),i=r-(parseInt(o.getPropertyValue("padding-top"))+parseInt(o.getPropertyValue("padding-bottom"))),a=n-(parseInt(o.getPropertyValue("padding-right"))+parseInt(o.getPropertyValue("padding-left")))-e.viewport.scrollBarWidth;return{cols:Math.max(2,Math.floor(a/e._renderService.dimensions.actualCellWidth)),rows:Math.max(1,Math.floor(i/e._renderService.dimensions.actualCellHeight))}}},e}();t.FitAddon=n}])});
|
||||||
|
//# sourceMappingURL=xterm-addon-fit.js.map
|
75
bricks/asr.js
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
var bricks = window.bricks || {};
|
||||||
|
bricks.ASRClient = class extends bricks.VBox {
|
||||||
|
/*
|
||||||
|
options:
|
||||||
|
{
|
||||||
|
start_icon:record.png,
|
||||||
|
stop_icon:stop.png
|
||||||
|
ws_url:
|
||||||
|
icon_options
|
||||||
|
ws_params:
|
||||||
|
}
|
||||||
|
event:
|
||||||
|
start: start recording, no params
|
||||||
|
stop: stop recording, no params
|
||||||
|
transtext: recognised text, params={
|
||||||
|
"content":
|
||||||
|
"speaker":
|
||||||
|
"start":
|
||||||
|
"end":
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
constructor(opts){
|
||||||
|
super(opts);
|
||||||
|
var icon_options = this.icon_options || {};
|
||||||
|
icon_options.url = this.start_icon || bricks_resource('imgs/start_recording.png');
|
||||||
|
this.icon = new bricks.Icon(icon_options);
|
||||||
|
this.status = 'stop';
|
||||||
|
this.icon.bind('click', this.toggle_button.bind(this));
|
||||||
|
this.add_widget(this.icon);
|
||||||
|
this.socket = new WebSocket(this.ws_url);
|
||||||
|
this.socket.onmessage = this.response_data.bind(this);
|
||||||
|
this.bind('transtext', this.response_log.bind(this));
|
||||||
|
}
|
||||||
|
response_log(event){
|
||||||
|
console.log('response data=', event.params);
|
||||||
|
}
|
||||||
|
toggle_button(){
|
||||||
|
if (this.status == 'stop'){
|
||||||
|
this.icon.set_url(this.start_icon||bricks_resource('imgs/stop_recording.png'));
|
||||||
|
this.status = 'start';
|
||||||
|
this.start_recording();
|
||||||
|
} else {
|
||||||
|
this.icon.set_url(this.stop_icon||bricks_resource('imgs/start_recording.png'));
|
||||||
|
this.status = 'stop';
|
||||||
|
this.stop_recording();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async start_recording() {
|
||||||
|
this.stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||||
|
this.mediaRecorder = new MediaRecorder(this.stream);
|
||||||
|
this.mediaRecorder.ondataavailable = (event) => {
|
||||||
|
if (event.data.size > 0) {
|
||||||
|
// 将音频数据通过 WebSocket 发送到服务器
|
||||||
|
blobToBase64(event.data).then((b64str) => {
|
||||||
|
var d = objcopy(this.ws_params);
|
||||||
|
d.type = 'audiobuffer';
|
||||||
|
d.data = b64str;
|
||||||
|
this.socket.send(JSON.stringify(d));
|
||||||
|
}).catch((error) => {
|
||||||
|
console.log('Error', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.mediaRecorder.start(1000); // 每 1 秒发送一次数据
|
||||||
|
}
|
||||||
|
stop_recording(){
|
||||||
|
this.mediaRecorder.stop();
|
||||||
|
}
|
||||||
|
response_data(event){
|
||||||
|
var d = JSON.parse(event.data);
|
||||||
|
this.dispatch('transtext', d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.Factory.register('ASRClient', bricks.ASRClient);
|
71
bricks/audio.js
Executable file → Normal file
@ -26,7 +26,7 @@ bricks.AudioPlayer = class extends bricks.JsWidget {
|
|||||||
this.audio = this._create('audio');
|
this.audio = this._create('audio');
|
||||||
this.audio.controls = true;
|
this.audio.controls = true;
|
||||||
if (this.opts.autoplay){
|
if (this.opts.autoplay){
|
||||||
this.audio.addEventListener('canplay', this.play_audio.bind(this));
|
this.audio.addEventListener('canplay', this.play.bind(this));
|
||||||
}
|
}
|
||||||
this.audio.style.width = "100%"
|
this.audio.style.width = "100%"
|
||||||
this.dom_element.appendChild(this.audio);
|
this.dom_element.appendChild(this.audio);
|
||||||
@ -34,6 +34,58 @@ bricks.AudioPlayer = class extends bricks.JsWidget {
|
|||||||
this.set_source(this.url);
|
this.set_source(this.url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_stream_urls(response){
|
||||||
|
async function* dyn_urls(response) {
|
||||||
|
const reader = response.body.getReader();
|
||||||
|
var value;
|
||||||
|
var done;
|
||||||
|
while (true){
|
||||||
|
done, value = await reader.read();
|
||||||
|
if (value.done){
|
||||||
|
console.log('done=', done, 'value=', value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let result = '';
|
||||||
|
for (let i = 0; i < value.value.length; i++) {
|
||||||
|
result += String.fromCharCode(value.value[i]);
|
||||||
|
}
|
||||||
|
console.log('audio set url=', result);
|
||||||
|
yield result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.url_generator = dyn_urls(response);
|
||||||
|
this.srcList = [];
|
||||||
|
schedule_once(this.load_queue_url.bind(this), 0.1);
|
||||||
|
}
|
||||||
|
async load_queue_url(){
|
||||||
|
while (true){
|
||||||
|
var d = await this.url_generator.next();
|
||||||
|
if (d.done){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.srcList.push({played:false, url:d.value});
|
||||||
|
if (this.srcList.length < 2 ){
|
||||||
|
await this.play_srclist();
|
||||||
|
this.audio.addEventListener('ended',
|
||||||
|
this.play_srclist.bind(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async play_srclist(evnet){
|
||||||
|
if (event && ! this.audio.ended){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (var i=0;i<this.srcList.length;i++){
|
||||||
|
if (!this.srcList[i].played){
|
||||||
|
console.log('playit', i, this.srcList[i]);
|
||||||
|
this.set_url(this.srcList[i].url);
|
||||||
|
this.srcList[i].played = true;
|
||||||
|
await this.play();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
set_source(url){
|
set_source(url){
|
||||||
if (! this.source){
|
if (! this.source){
|
||||||
this.source = this._create('source');
|
this.source = this._create('source');
|
||||||
@ -49,14 +101,14 @@ bricks.AudioPlayer = class extends bricks.JsWidget {
|
|||||||
// 播放音频
|
// 播放音频
|
||||||
this.audio.play();
|
this.audio.play();
|
||||||
}
|
}
|
||||||
play(){
|
async play(){
|
||||||
this.audio.play();
|
await this.audio.play();
|
||||||
}
|
}
|
||||||
toggle_play(){
|
async toggle_play(){
|
||||||
if (this.audio.paused){
|
if (this.audio.paused){
|
||||||
this.audio.play();
|
await this.audio.play();
|
||||||
} else {
|
} else {
|
||||||
this.audio.pause();
|
await this.audio.pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_url(url){
|
set_url(url){
|
||||||
@ -81,6 +133,7 @@ bricks.AudioRecorder = class extends bricks.HBox {
|
|||||||
*/
|
*/
|
||||||
constructor(opts){
|
constructor(opts){
|
||||||
super(opts);
|
super(opts);
|
||||||
|
this.set_css('clickable');
|
||||||
this.start_icon = opts.start_icon || bricks_resource('imgs/start_recording.png');
|
this.start_icon = opts.start_icon || bricks_resource('imgs/start_recording.png');
|
||||||
this.stop_icon = opts.stop_icon || bricks_resource('imgs/stop_recording.png');
|
this.stop_icon = opts.stop_icon || bricks_resource('imgs/stop_recording.png');
|
||||||
this.rec_btn = new bricks.Icon({
|
this.rec_btn = new bricks.Icon({
|
||||||
@ -97,7 +150,7 @@ bricks.AudioRecorder = class extends bricks.HBox {
|
|||||||
width:'120px'
|
width:'120px'
|
||||||
});
|
});
|
||||||
this.upload_url = opts.upload_url;
|
this.upload_url = opts.upload_url;
|
||||||
this.rec_btn.bind('click', this.rec_btn_pressed.bind(this))
|
this.bind('click', this.rec_btn_pressed.bind(this))
|
||||||
this.URL = window.URL||webkitURL;
|
this.URL = window.URL||webkitURL;
|
||||||
this.rec = null;
|
this.rec = null;
|
||||||
this.wave = null;
|
this.wave = null;
|
||||||
@ -105,7 +158,9 @@ bricks.AudioRecorder = class extends bricks.HBox {
|
|||||||
this.add_widget(this.rec_btn);
|
this.add_widget(this.rec_btn);
|
||||||
this.add_widget(this.rec_time);
|
this.add_widget(this.rec_time);
|
||||||
this.recordData = null;
|
this.recordData = null;
|
||||||
this.bind('record_ended', this.upload.bind(this));
|
if (this.upload_url){
|
||||||
|
this.bind('record_ended', this.upload.bind(this));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rec_btn_pressed(){
|
rec_btn_pressed(){
|
||||||
bricks.debug(this.rec_btn.url, ':url:', this.start_icon, this.stop_icon);
|
bricks.debug(this.rec_btn.url, ':url:', this.start_icon, this.stop_icon);
|
||||||
|
@ -7,10 +7,8 @@ bricks.ChartBar = class extends bricks.EchartsExt {
|
|||||||
data_params,
|
data_params,
|
||||||
method,
|
method,
|
||||||
data,
|
data,
|
||||||
line_options,
|
|
||||||
nameField,
|
nameField,
|
||||||
valueField
|
valueFields
|
||||||
serieField:
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
values_from_data(data, name){
|
values_from_data(data, name){
|
||||||
|
0
bricks/baseKnowledge.txt
Executable file → Normal file
@ -32,3 +32,25 @@ bricks.UpStreaming = class extends bricks.JsWidget {
|
|||||||
this.stream_ctlr = controller;
|
this.stream_ctlr = controller;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bricks.down_streaming = async function*(response) {
|
||||||
|
if (! response){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const reader = response.body.getReader();
|
||||||
|
var value;
|
||||||
|
var t = 0;
|
||||||
|
while (true){
|
||||||
|
done, value = await reader.read();
|
||||||
|
if (value.done){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let result = '';
|
||||||
|
for (let i = 0; i < value.value.length; i++) {
|
||||||
|
result += String.fromCharCode(value.value[i]);
|
||||||
|
}
|
||||||
|
console.log('audio set url=', result);
|
||||||
|
yield result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
230
bricks/bricks.js
Executable file → Normal file
@ -48,9 +48,20 @@ params:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
bricks.uuid = function(){
|
bricks.uuid = function(){
|
||||||
var d = crypto.randomUUID();
|
try{
|
||||||
var lst = d.split('-');
|
var d = crypto.randomUUID();
|
||||||
return lst.join('');
|
var lst = d.split('-');
|
||||||
|
return lst.join('');
|
||||||
|
} catch(e) {
|
||||||
|
const vv = '1234567890qwertyuiopasdfghjklzxcvbnm';
|
||||||
|
var ret = '';
|
||||||
|
for (var i=0;i<30;i++){
|
||||||
|
var j = parseInt(Math.random() * vv.length);
|
||||||
|
ret = ret + vv[j];
|
||||||
|
}
|
||||||
|
console.log('uuid() return', ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bricks.deviceid = function(appname){
|
bricks.deviceid = function(appname){
|
||||||
@ -124,26 +135,40 @@ bricks.widgetBuild = async function(desc, widget, data){
|
|||||||
var klassname = desc.widgettype;
|
var klassname = desc.widgettype;
|
||||||
var base_url = widget.baseURI;
|
var base_url = widget.baseURI;
|
||||||
while (klassname == 'urlwidget'){
|
while (klassname == 'urlwidget'){
|
||||||
|
if (data){
|
||||||
|
desc = bricks.apply_data(desc, data);
|
||||||
|
}
|
||||||
let url = bricks.absurl(desc.options.url, widget);
|
let url = bricks.absurl(desc.options.url, widget);
|
||||||
base_url = url;
|
base_url = url;
|
||||||
let method = desc.options.method || 'GET';
|
let method = desc.options.method || 'GET';
|
||||||
let opts = desc.options.params || {};
|
let opts = desc.options.params || {};
|
||||||
var jc = new bricks.HttpJson();
|
var jc = new bricks.HttpJson();
|
||||||
var desc1 = await jc.httpcall(url, { "method":method, "params":opts});
|
var desc1 = await jc.httpcall(url, { "method":method, "params":opts});
|
||||||
|
if (!desc1) return;
|
||||||
desc = desc1;
|
desc = desc1;
|
||||||
klassname = desc.widgettype;
|
klassname = desc.widgettype;
|
||||||
}
|
}
|
||||||
if (data){
|
if (data){
|
||||||
desc = bricks.apply_data(desc, data);
|
desc = bricks.apply_data(desc, data);
|
||||||
}
|
}
|
||||||
|
if (!desc.widgettype){
|
||||||
|
console.log('widgettype is null', desc);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
let klass = bricks.Factory.get(desc.widgettype);
|
let klass = bricks.Factory.get(desc.widgettype);
|
||||||
if (! klass){
|
if (! klass){
|
||||||
bricks.debug('widgetBuild():',desc.widgettype, 'not registered', bricks.Factory.widgets_kw);
|
console.log('widgetBuild():',
|
||||||
|
desc.widgettype,
|
||||||
|
'not registered',
|
||||||
|
bricks.Factory.widgets_kw);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var options = desc.options || {};
|
var options = desc.options || {};
|
||||||
options.baseURI = base_url;
|
options.baseURI = base_url;
|
||||||
let w = new klass(options);
|
let w = new klass(options);
|
||||||
|
if (! w){
|
||||||
|
console.log('w is null');
|
||||||
|
}
|
||||||
if (desc.id){
|
if (desc.id){
|
||||||
w.set_id(desc.id);
|
w.set_id(desc.id);
|
||||||
}
|
}
|
||||||
@ -203,14 +228,34 @@ bricks.universal_handler = async function(from_widget, widget, desc, event){
|
|||||||
'desc=', desc,
|
'desc=', desc,
|
||||||
event);
|
event);
|
||||||
}
|
}
|
||||||
|
bricks.default_popup = function(opts){
|
||||||
|
var popts = bricks.get_popup_default_options();
|
||||||
|
bricks.extend(popts, opts);
|
||||||
|
return new bricks.Popup(popts);
|
||||||
|
}
|
||||||
|
bricks.default_popupwindow = function(opts){
|
||||||
|
var popts = bricks.get_popupwindow_default_options();
|
||||||
|
bricks.extend(popts, opts);
|
||||||
|
return new bricks.PopupWindow(popts);
|
||||||
|
}
|
||||||
bricks.buildEventHandler = async function(w, desc, event){
|
bricks.buildEventHandler = async function(w, desc, event){
|
||||||
var target = bricks.getWidgetById(desc.target, w);
|
var target;
|
||||||
|
if (desc.target == 'Popup'){
|
||||||
|
target = bricks.default_popup(desc.popup_options || {});
|
||||||
|
} else if (desc.target == 'PopupWindow') {
|
||||||
|
target = bricks.default_popupwindow(desc.popup_options || {});
|
||||||
|
} else if ( desc.target instanceof bricks.JsWidget ) {
|
||||||
|
target = desc.target;
|
||||||
|
} else {
|
||||||
|
target = bricks.getWidgetById(desc.target, w);
|
||||||
|
}
|
||||||
if (! target){
|
if (! target){
|
||||||
bricks.debug('target miss desc=', desc, 'w=', w);
|
bricks.debug('target miss desc=', desc, 'w=', w);
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
var rtdata = {};
|
var rtdata = {};
|
||||||
|
desc.event_params = event.params || {} ;
|
||||||
|
desc.event = event;
|
||||||
if (desc.rtdata) rtdata = desc.rtdata;
|
if (desc.rtdata) rtdata = desc.rtdata;
|
||||||
else if (desc.datawidget){
|
else if (desc.datawidget){
|
||||||
var data_desc = {
|
var data_desc = {
|
||||||
@ -221,9 +266,6 @@ bricks.buildEventHandler = async function(w, desc, event){
|
|||||||
}
|
}
|
||||||
rtdata = await bricks.getRealtimeData(w, data_desc);
|
rtdata = await bricks.getRealtimeData(w, data_desc);
|
||||||
}
|
}
|
||||||
if (typeof event.params == typeof {}){
|
|
||||||
rtdata = bricks.extend(rtdata, event.params);
|
|
||||||
}
|
|
||||||
switch (desc.actiontype){
|
switch (desc.actiontype){
|
||||||
case 'urlwidget':
|
case 'urlwidget':
|
||||||
return bricks.buildUrlwidgetHandler(w, target, rtdata, desc);
|
return bricks.buildUrlwidgetHandler(w, target, rtdata, desc);
|
||||||
@ -269,70 +311,80 @@ bricks.getRealtimeData = async function(w, desc){
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var _buildWidget = async function(from_widget, target, mode, options){
|
var _buildWidget = async function(from_widget, target, mode, options, desc){
|
||||||
bricks.debug('target=', target, 'mode=', mode, 'options=', options);
|
bricks.debug('target=', target, 'mode=', mode, 'options=', options);
|
||||||
var w = await (bricks.widgetBuild(options, from_widget));
|
var w = await (bricks.widgetBuild(options, from_widget));
|
||||||
if (!w){
|
if (!w){
|
||||||
bricks.debug('options=', options, 'widgetBuild() failed');
|
bricks.debug('options=', options, 'widgetBuild() failed');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w.parent) return;
|
if (w.parent) {
|
||||||
|
if (target instanceof bricks.Popup || target instanceof bricks.PopupWindow){
|
||||||
if (mode == 'replace'){
|
target.destroy();
|
||||||
target.clear_widgets();
|
|
||||||
target.add_widget(w);
|
|
||||||
} else if (mode == 'insert'){
|
|
||||||
target.add_widget(w, 0);
|
|
||||||
} else {
|
|
||||||
target.add_widget(w);
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (target instanceof bricks.Popup || target instanceof bricks.PopupWindow) {
|
||||||
|
if (! target.parent){
|
||||||
|
bricks.app.add_widget(target);
|
||||||
|
}
|
||||||
|
console.log('target=', target);
|
||||||
|
if (desc.popup_options.eventpos){
|
||||||
|
target.bind('opened', bricks.relocate_by_eventpos.bind(null, desc.event, target));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == 'replace'){
|
||||||
|
target.clear_widgets();
|
||||||
|
target.add_widget(w);
|
||||||
|
} else if (mode == 'insert'){
|
||||||
|
target.add_widget(w, 0);
|
||||||
|
} else {
|
||||||
|
target.add_widget(w);
|
||||||
|
}
|
||||||
|
if (target instanceof bricks.Popup || target instanceof bricks.PopupWindow) {
|
||||||
|
target.open();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bricks.buildUrlwidgetHandler = function(w, target, rtdata, desc){
|
bricks.buildUrlwidgetHandler = function(w, target, rtdata, desc){
|
||||||
var f = async function(target, mode, options){
|
|
||||||
bricks.debug('target=', target, 'mode=', mode, 'options=', options);
|
|
||||||
var w = await (bricks.widgetBuild(options, w));
|
|
||||||
if (!w){
|
|
||||||
bricks.debug('options=', options, 'widgetBuild() failed');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mode == 'replace'){
|
|
||||||
target.clear_widgets();
|
|
||||||
target.add_widget(w);
|
|
||||||
} else if (mode == 'insert'){
|
|
||||||
target.add_widget(w, 0);
|
|
||||||
} else {
|
|
||||||
target.add_widget(w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var options = objcopy(desc.options||{});
|
var options = objcopy(desc.options||{});
|
||||||
var params = options.params || {};
|
var params = options.params || {};
|
||||||
options = bricks.apply_data(options, rtdata);
|
if (desc.event_params instanceof FormData){
|
||||||
options.params = bricks.extend(params, rtdata);
|
var params = desc.event_params;
|
||||||
|
for ( const [key, value] of Object.entries(rtdata)){
|
||||||
|
params.append(key, value);
|
||||||
|
}
|
||||||
|
options = bricks.apply_data(options, rtdata);
|
||||||
|
for ( const [key, value] of Object.entries(options.params||{})){
|
||||||
|
params.append(key, value);
|
||||||
|
}
|
||||||
|
options.params = params;
|
||||||
|
options.method = "POST";
|
||||||
|
} else {
|
||||||
|
rtdata = bricks.extend(rtdata, desc.event_params);
|
||||||
|
options = bricks.apply_data(options, rtdata);
|
||||||
|
if (desc.params_mapping){
|
||||||
|
rtdata = bricks.map(rtdata, desc.params_mapping.mapping, desc.params_mapping.need_others);
|
||||||
|
}
|
||||||
|
options.params = bricks.extend(params, rtdata);
|
||||||
|
}
|
||||||
|
|
||||||
var opts = {
|
var opts = {
|
||||||
"widgettype":"urlwidget",
|
"widgettype":"urlwidget",
|
||||||
"options":options
|
"options":options
|
||||||
}
|
}
|
||||||
return _buildWidget.bind(w, target, target, desc.mode || 'replace', opts);
|
return _buildWidget.bind(null, w, target, desc.mode || 'replace', opts, desc);
|
||||||
}
|
}
|
||||||
bricks.buildBricksHandler = function(w, target, rtdata, desc){
|
bricks.buildBricksHandler = function(w, target, rtdata, desc){
|
||||||
var f = async function(target, mode, options){
|
|
||||||
bricks.debug('target=', target, 'mode=', mode, 'options=', options);
|
|
||||||
var w = await (bricks.widgetBuild(options, wa));
|
|
||||||
if (!w){
|
|
||||||
bricks.debug('options=', options, 'widgetBuild() failed');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mode == 'replace'){
|
|
||||||
target.clear_widgets();
|
|
||||||
}
|
|
||||||
target.add_widget(w);
|
|
||||||
}
|
|
||||||
var options = objcopy(desc.options||{});
|
var options = objcopy(desc.options||{});
|
||||||
|
rtdata = bricks.extend(rtdata, inputdata2dic(desc.event_params));
|
||||||
|
if (desc.params_mapping){
|
||||||
|
rtdata = bricks.map(rtdata, desc.params_mapping.mapping, desc.params_mapping.need_others);
|
||||||
|
}
|
||||||
options = bricks.apply_data(options, rtdata);
|
options = bricks.apply_data(options, rtdata);
|
||||||
return _buildWidget.bind(w, target, target, desc.mode || 'replace', options);
|
return _buildWidget.bind(w, target, target, desc.mode || 'replace', options, desc);
|
||||||
}
|
}
|
||||||
bricks.buildRegisterFunctionHandler = function(w, target, rtdata, desc){
|
bricks.buildRegisterFunctionHandler = function(w, target, rtdata, desc){
|
||||||
var f = bricks.RF.get(desc.rfname);
|
var f = bricks.RF.get(desc.rfname);
|
||||||
@ -340,6 +392,9 @@ bricks.buildRegisterFunctionHandler = function(w, target, rtdata, desc){
|
|||||||
bricks.debug('rfname:', desc.rfname, 'not registed', desc);
|
bricks.debug('rfname:', desc.rfname, 'not registed', desc);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (desc.params_mapping){
|
||||||
|
rtdata = bricks.map(rtdata, desc.params_mapping.mapping, desc.params_mapping.need_others);
|
||||||
|
}
|
||||||
var params = {};
|
var params = {};
|
||||||
if (desc.params){
|
if (desc.params){
|
||||||
bricks.extend(params, desc.params);
|
bricks.extend(params, desc.params);
|
||||||
@ -347,6 +402,7 @@ bricks.buildRegisterFunctionHandler = function(w, target, rtdata, desc){
|
|||||||
if (rtdata){
|
if (rtdata){
|
||||||
bricks.extend(params, rtdata);
|
bricks.extend(params, rtdata);
|
||||||
}
|
}
|
||||||
|
bricks.extend(params, inputdata2dic(desc.event_params));
|
||||||
params = bricks.apply_data(params, rtdata);
|
params = bricks.apply_data(params, rtdata);
|
||||||
return f.bind(target, params);
|
return f.bind(target, params);
|
||||||
}
|
}
|
||||||
@ -359,6 +415,10 @@ bricks.buildMethodHandler = function(w, target, rtdata, desc){
|
|||||||
var params = {};
|
var params = {};
|
||||||
bricks.extend(params, desc.params)
|
bricks.extend(params, desc.params)
|
||||||
bricks.extend(params, rtdata);
|
bricks.extend(params, rtdata);
|
||||||
|
bricks.extend(params, inputdata2dic(desc.event_params));
|
||||||
|
if (desc.params_mapping){
|
||||||
|
rtdata = bricks.map(rtdata, desc.params_mapping.mapping, desc.params_mapping.need_others);
|
||||||
|
}
|
||||||
params = bricks.apply_data(params, rtdata);
|
params = bricks.apply_data(params, rtdata);
|
||||||
return f.bind(target, params);
|
return f.bind(target, params);
|
||||||
}
|
}
|
||||||
@ -366,6 +426,10 @@ bricks.buildScriptHandler = function(w, target, rtdata, desc){
|
|||||||
var params = {};
|
var params = {};
|
||||||
bricks.extend(params, desc.params)
|
bricks.extend(params, desc.params)
|
||||||
bricks.extend(params, rtdata);
|
bricks.extend(params, rtdata);
|
||||||
|
bricks.extend(params, inputdata2dic(desc.event_params));
|
||||||
|
if (desc.params_mapping){
|
||||||
|
rtdata = bricks.map(rtdata, desc.params_mapping.mapping, desc.params_mapping.need_others);
|
||||||
|
}
|
||||||
params = bricks.apply_data(params, rtdata);
|
params = bricks.apply_data(params, rtdata);
|
||||||
var AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
|
var AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
|
||||||
var f = new AsyncFunction('params', 'event', desc.script);
|
var f = new AsyncFunction('params', 'event', desc.script);
|
||||||
@ -379,6 +443,7 @@ bricks.buildDispatchEventHandler = function(w, target, rtdata, desc){
|
|||||||
var params = {};
|
var params = {};
|
||||||
bricks.extend(params, desc.params)
|
bricks.extend(params, desc.params)
|
||||||
bricks.extend(params, rtdata);
|
bricks.extend(params, rtdata);
|
||||||
|
bricks.extend(params, inputdata2dic(desc.event_params));
|
||||||
params = bricks.apply_data(params, rtdata);
|
params = bricks.apply_data(params, rtdata);
|
||||||
return f.bind(target, desc.dispatch_event, params);
|
return f.bind(target, desc.dispatch_event, params);
|
||||||
}
|
}
|
||||||
@ -405,7 +470,7 @@ bricks.getWidgetById = function(id, from_widget){
|
|||||||
el = bricks.app.root.dom_element;
|
el = bricks.app.root.dom_element;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (ids[i]=='app'){
|
if (ids[i]=='app' || ids[i] == 'body'){
|
||||||
return bricks.app;
|
return bricks.app;
|
||||||
}
|
}
|
||||||
if (ids[i] == 'window'){
|
if (ids[i] == 'window'){
|
||||||
@ -444,6 +509,7 @@ bricks.App = class extends bricks.Layout {
|
|||||||
/*
|
/*
|
||||||
opts = {
|
opts = {
|
||||||
appname:
|
appname:
|
||||||
|
debug:false, true, 'server'
|
||||||
login_url:
|
login_url:
|
||||||
"charsize:
|
"charsize:
|
||||||
"language":
|
"language":
|
||||||
@ -460,10 +526,11 @@ bricks.App = class extends bricks.Layout {
|
|||||||
*/
|
*/
|
||||||
super(opts);
|
super(opts);
|
||||||
bricks.app = this;
|
bricks.app = this;
|
||||||
|
this.docks = [];
|
||||||
bricks.bug = opts.debug || false;
|
bricks.bug = opts.debug || false;
|
||||||
bricks.Body = this;
|
bricks.Body = this;
|
||||||
this.deviceid = bricks.deviceid(opts.appname || 'appname');
|
this.deviceid = bricks.deviceid(opts.appname || 'appname');
|
||||||
this.login_url = opts.login_url;
|
this.login_url = opts.login_url || '/rbac/userpassword_login.ui';
|
||||||
this.charsize = this.opts.charsize || 20;
|
this.charsize = this.opts.charsize || 20;
|
||||||
this.keyevent_blocked = false;
|
this.keyevent_blocked = false;
|
||||||
this.char_size = this.observable('charsize', this.charsize);
|
this.char_size = this.observable('charsize', this.charsize);
|
||||||
@ -482,8 +549,53 @@ bricks.App = class extends bricks.Layout {
|
|||||||
this.add_widget(this.tooltip);
|
this.add_widget(this.tooltip);
|
||||||
this._Width = this.dom_element.offsetWidth;
|
this._Width = this.dom_element.offsetWidth;
|
||||||
this._Height = this.dom_element.offsetHeight;
|
this._Height = this.dom_element.offsetHeight;
|
||||||
|
this.video_stream = null;
|
||||||
|
this.audio_stream = null;
|
||||||
|
this.video_devices = null
|
||||||
|
this.vpos = null;
|
||||||
document.addEventListener('keydown', this.key_down_action.bind(this));
|
document.addEventListener('keydown', this.key_down_action.bind(this));
|
||||||
|
this.screen_orient = window.screen.orientation.type;
|
||||||
|
window.screen.orientation.addEventListener('change', () => {
|
||||||
|
this.screen_orient = window.screen.orientation.type;
|
||||||
|
this.bind('orient_changed', this.screen_orient);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
async getCameras() {
|
||||||
|
try {
|
||||||
|
const devices = await navigator.mediaDevices.enumerateDevices();
|
||||||
|
this.video_devices = devices.filter(device => device.kind === 'videoinput');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取摄像头数量出错:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async start_camera(vpos) {
|
||||||
|
if (typeof(vpos) == 'undefined') vpos = 0;
|
||||||
|
if (this.video_devices === null){
|
||||||
|
await this.getCameras();
|
||||||
|
}
|
||||||
|
if (vpos == this.vpos) return;
|
||||||
|
this.vpos = vpos;
|
||||||
|
if (this.video_stream){
|
||||||
|
this.video_stream.getTracks().forEach(track => {
|
||||||
|
track.stop();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (navigator.mediaDevices.getUserMedia) {
|
||||||
|
var x = { deviceId: this.video_devices[vpos].deviceId };
|
||||||
|
this.video_stream = await navigator.mediaDevices.getUserMedia({ video: x });
|
||||||
|
} else {
|
||||||
|
console.log("Webcam access is not supported in this browser.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async start_mic() {
|
||||||
|
if (this.audio_stream) return;
|
||||||
|
if (navigator.mediaDevices.getUserMedia) {
|
||||||
|
this.audio_stream = navigator.mediaDevices.getUserMedia({ audio: true });
|
||||||
|
} else {
|
||||||
|
console.log("mic access is not supported in this browser.");
|
||||||
|
this.stream = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
new_zindex(){
|
new_zindex(){
|
||||||
const v = this.zindex;
|
const v = this.zindex;
|
||||||
this.zindex = v + 1;
|
this.zindex = v + 1;
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
SOURCES=" page_data_loader.js factory.js uitypesdef.js utils.js uitype.js \
|
SOURCES=" page_data_loader.js factory.js uitypesdef.js utils.js uitype.js \
|
||||||
i18n.js widget.js layout.js bricks.js image.js html.js \
|
i18n.js widget.js layout.js bricks.js image.js html.js splitter.js \
|
||||||
jsoncall.js myoperator.js scroll.js menu.js popup.js modal.js running.js \
|
jsoncall.js myoperator.js scroll.js menu.js popup.js camera.js modal.js running.js \
|
||||||
markdown_viewer.js video.js audio.js toolbar.js tab.js \
|
markdown_viewer.js video.js audio.js toolbar.js tab.js \
|
||||||
input.js registerfunction.js button.js accordion.js dataviewer.js \
|
input.js registerfunction.js button.js accordion.js dataviewer.js \
|
||||||
tree.js multiple_state_image.js dynamiccolumn.js form.js message.js conform.js \
|
tree.js multiple_state_image.js dynamiccolumn.js form.js message.js conform.js \
|
||||||
paging.js datagrid.js iframe.js cols.js echartsext.js \
|
paging.js datagrid.js iframe.js cols.js echartsext.js \
|
||||||
floaticonbar.js miniform.js wterm.js dynamicaccordion.js \
|
floaticonbar.js miniform.js wterm.js dynamicaccordion.js \
|
||||||
binstreaming.js streaming_audio.js vadtext.js rtc.js \
|
binstreaming.js streaming_audio.js vadtext.js rtc.js docxviewer.js \
|
||||||
llm_dialog.js llm.js websocket.js datarow.js tabular.js \
|
llm_dialog.js llm.js websocket.js datarow.js tabular.js \
|
||||||
line.js pie.js bar.js gobang.js "
|
line.js pie.js bar.js gobang.js period.js iconbarpage.js \
|
||||||
|
keypress.js asr.js webspeech.js countdown.js progressbar.js "
|
||||||
echo ${SOURCES}
|
echo ${SOURCES}
|
||||||
cat ${SOURCES} > ../dist/bricks.js
|
cat ${SOURCES} > ../dist/bricks.js
|
||||||
# uglifyjs --compress --mangle -- ../dist/bricks.js > ../dist/bricks.min.js
|
# uglifyjs --compress --mangle -- ../dist/bricks.js > ../dist/bricks.min.js
|
||||||
@ -38,4 +39,5 @@ cp -a ../examples/* ../dist/examples
|
|||||||
cp -a ../3parties/* ../dist/3parties
|
cp -a ../3parties/* ../dist/3parties
|
||||||
cp -a ../docs/* ../dist/docs
|
cp -a ../docs/* ../dist/docs
|
||||||
cp *.tmpl ../dist
|
cp *.tmpl ../dist
|
||||||
|
cp -a ../dist /tmp
|
||||||
echo "Finished ..."
|
echo "Finished ..."
|
||||||
|
99
bricks/camera.js
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
var bricks = window.bricks || {}
|
||||||
|
bricks.Camera = class extends bricks.Popup {
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
fps:60
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
constructor(opts){
|
||||||
|
opts.fps = opts.fps || 60;
|
||||||
|
opts.auto_dismiss = false;
|
||||||
|
super(opts);
|
||||||
|
this.stream = null;
|
||||||
|
this.video = document.createElement('video');
|
||||||
|
var filler = new bricks.Filler({});
|
||||||
|
var hbox = new bricks.HBox({
|
||||||
|
cheight:3
|
||||||
|
});
|
||||||
|
this.cur_camera_id = 0;
|
||||||
|
this.add_widget(filler);
|
||||||
|
this.add_widget(hbox);
|
||||||
|
var shot_btn = new bricks.Icon({
|
||||||
|
url:bricks_resource('imgs/camera.png'),
|
||||||
|
margin: '10px',
|
||||||
|
tip:'Take a picture',
|
||||||
|
rate:2.5
|
||||||
|
});
|
||||||
|
var switch_btn = new bricks.Icon({
|
||||||
|
url:bricks_resource('imgs/switch-camera.png'),
|
||||||
|
tip:'switch camera',
|
||||||
|
margin: '10px',
|
||||||
|
rate:1.5
|
||||||
|
});
|
||||||
|
var del_btn = new bricks.Icon({
|
||||||
|
url:bricks_resource('imgs/delete.png'),
|
||||||
|
tip:'canel it',
|
||||||
|
margin: '10px',
|
||||||
|
rate:1.5
|
||||||
|
})
|
||||||
|
del_btn.bind('click', this.dismiss.bind(this));
|
||||||
|
shot_btn.bind('click', this.take_picture.bind(this));
|
||||||
|
switch_btn.bind('click', this.switch_camera.bind(this, switch_btn));
|
||||||
|
this.imgw = new bricks.Image({
|
||||||
|
width:'100%'
|
||||||
|
});
|
||||||
|
hbox.add_widget(switch_btn);
|
||||||
|
hbox.add_widget(shot_btn);
|
||||||
|
hbox.add_widget(new bricks.Filler({}));
|
||||||
|
hbox.add_widget(del_btn);
|
||||||
|
filler.add_widget(this.imgw);
|
||||||
|
this.task_period = 1 / this.fps;
|
||||||
|
schedule_once(this.startCamera.bind(this), 0.1);
|
||||||
|
}
|
||||||
|
async switch_camera(btn, event){
|
||||||
|
if (bricks.app.video_devices.length < 2){
|
||||||
|
btn.disabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var vpos = bricks.app.vpos;
|
||||||
|
vpos += 1;
|
||||||
|
if (vpos >= bricks.app.video_devices.length){
|
||||||
|
vpos = 0;
|
||||||
|
}
|
||||||
|
this.startCamera(vpos);
|
||||||
|
}
|
||||||
|
async startCamera(vpos) {
|
||||||
|
await bricks.app.start_camera(vpos);
|
||||||
|
this.stream = bricks.app.video_stream;
|
||||||
|
this.video.srcObject = this.stream;
|
||||||
|
this.video.play();
|
||||||
|
this.show_cnt = 1;
|
||||||
|
this.task = schedule_once(this.show_picture.bind(this), this.task_period);
|
||||||
|
}
|
||||||
|
show_picture(){
|
||||||
|
if (this.task_period == 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var canvas = document.createElement('canvas');
|
||||||
|
canvas.height = this.video.videoHeight;
|
||||||
|
canvas.width = this.video.videoWidth;
|
||||||
|
const context = canvas.getContext('2d');
|
||||||
|
context.drawImage(this.video, 0, 0);
|
||||||
|
this.imgw.set_url(canvas.toDataURL('image/jpeg'));
|
||||||
|
this.task = schedule_once(this.show_picture.bind(this), this.task_period);
|
||||||
|
this.show_cnt += 1;
|
||||||
|
}
|
||||||
|
take_picture(event){
|
||||||
|
event.stopPropagation();
|
||||||
|
if (this.task){
|
||||||
|
task.cancel();
|
||||||
|
this.task = null;
|
||||||
|
}
|
||||||
|
this.task_period = 0;
|
||||||
|
this.task = null;
|
||||||
|
var d = this.imgw.base64();
|
||||||
|
this.dispatch('shot', d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.Factory.register('Camera', bricks.Camera);
|
@ -55,6 +55,7 @@ bricks.Cols = class extends bricks.VBox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async handle_click(rw, event){
|
async handle_click(rw, event){
|
||||||
|
event.stopPropagation();
|
||||||
var orev = null;
|
var orev = null;
|
||||||
if (this.select_record){
|
if (this.select_record){
|
||||||
orev = this.select_record;
|
orev = this.select_record;
|
||||||
@ -64,6 +65,8 @@ bricks.Cols = class extends bricks.VBox {
|
|||||||
}
|
}
|
||||||
this.select_record = rw;
|
this.select_record = rw;
|
||||||
this.select_record.set_css('selected_record');
|
this.select_record.set_css('selected_record');
|
||||||
|
console.log('record data=', rw.user_data);
|
||||||
|
this.dispatch('record_click', rw.user_data);
|
||||||
}
|
}
|
||||||
async dataHandle(d){
|
async dataHandle(d){
|
||||||
var data = d.rows;
|
var data = d.rows;
|
||||||
@ -71,18 +74,20 @@ bricks.Cols = class extends bricks.VBox {
|
|||||||
if (!data){
|
if (!data){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (! this.loader.is_max_page(page)){
|
var rev = ! this.loader.is_max_page(page);
|
||||||
|
if (rev){
|
||||||
data.reverse();
|
data.reverse();
|
||||||
}
|
}
|
||||||
for (var i=0;i<data.length;i++){
|
for (var i=0;i<data.length;i++){
|
||||||
var d = data[i];
|
var r = data[i];
|
||||||
var w = await bricks.widgetBuild(this.record_view, this.main, d);
|
var w = await bricks.widgetBuild(this.record_view, this.main, r);
|
||||||
|
w.user_data = r;
|
||||||
w.bind('click', this.handle_click.bind(this, w));
|
w.bind('click', this.handle_click.bind(this, w));
|
||||||
w.set_attribute('data-page', page);
|
w.set_attribute('data-page', page);
|
||||||
if (this.loader.is_max_page(page)){
|
if (rev){
|
||||||
this.main.add_widget(w);
|
|
||||||
} else {
|
|
||||||
this.main.add_widget(w, 0);
|
this.main.add_widget(w, 0);
|
||||||
|
} else {
|
||||||
|
this.main.add_widget(w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (d.delete_page){
|
if (d.delete_page){
|
||||||
@ -93,11 +98,11 @@ bricks.Cols = class extends bricks.VBox {
|
|||||||
var items = this.dom_element.querySelectorAll('[data-page="' + page + '"]');
|
var items = this.dom_element.querySelectorAll('[data-page="' + page + '"]');
|
||||||
for (var i=0;i<items.length;i++) {
|
for (var i=0;i<items.length;i++) {
|
||||||
var w = items[i].bricks_widget;
|
var w = items[i].bricks_widget;
|
||||||
this.container.remove_widget(w);
|
this.main.remove_widget(w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async load_first_page(params){
|
async load_first_page(params){
|
||||||
var p = bricks.extend({}, this.params);
|
var p = bricks.extend({}, this.data_params);
|
||||||
if (params){
|
if (params){
|
||||||
p = bricks.extend(p, params);
|
p = bricks.extend(p, params);
|
||||||
}
|
}
|
||||||
@ -112,14 +117,14 @@ bricks.Cols = class extends bricks.VBox {
|
|||||||
this.main = new bricks.DynamicColumn({
|
this.main = new bricks.DynamicColumn({
|
||||||
width:"100%",
|
width:"100%",
|
||||||
col_cwidth:this.col_cwidth,
|
col_cwidth:this.col_cwidth,
|
||||||
mobile_cols:this.mobile_cols,
|
mobile_cols:this.mobile_cols || 2
|
||||||
mobile_cols:2});
|
});
|
||||||
this.container.add_widget(this.main);
|
this.container.add_widget(this.main);
|
||||||
var d = await this.loader.loadData(p);
|
var d = await this.loader.loadData(p);
|
||||||
if (d){
|
if (d){
|
||||||
this.dataHandle(d);
|
this.dataHandle(d);
|
||||||
var total = this.container.dom_element.scrollHeight - this.container.dom_element.clientHeight;
|
var total = this.container.dom_element.scrollHeight - this.container.dom_element.clientHeight;
|
||||||
this.container.dom_element.scrollTop = d.pos_rate * total;
|
// this.container.dom_element.scrollTop = d.pos_rate * total;
|
||||||
} else {
|
} else {
|
||||||
bricks.debug(this.loader, 'load previous page error');
|
bricks.debug(this.loader, 'load previous page error');
|
||||||
}
|
}
|
||||||
@ -163,12 +168,12 @@ bricks.Cols = class extends bricks.VBox {
|
|||||||
if (d){
|
if (d){
|
||||||
this.dataHandle(d);
|
this.dataHandle(d);
|
||||||
var total = this.container.dom_element.scrollHeight - this.container.dom_element.clientHeight;
|
var total = this.container.dom_element.scrollHeight - this.container.dom_element.clientHeight;
|
||||||
this.container.dom_element.scrollTop = d.pos_rate * total;
|
// this.container.dom_element.scrollTop = d.pos_rate * total;
|
||||||
} else {
|
} else {
|
||||||
bricks.debug(this.loader, 'load next page error');
|
console.log(this.loader, 'load next page error');
|
||||||
}
|
}
|
||||||
} catch (e){
|
} catch (e){
|
||||||
bricks.debug('error happened', e);
|
console.log('error happened', e);
|
||||||
}
|
}
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
running.dismiss();
|
running.dismiss();
|
||||||
|
@ -1,13 +1,29 @@
|
|||||||
var bricks = window.bricks || {};
|
var bricks = window.bricks || {};
|
||||||
bricks.Conform = class extends bricks.Message {
|
bricks.Conform = class extends bricks.PopupWindow {
|
||||||
constructor(opts){
|
constructor(opts){
|
||||||
opts.auto_open = true;
|
|
||||||
opts.auto_close = false;
|
|
||||||
opts.timeout = 0;
|
opts.timeout = 0;
|
||||||
|
opts.auto_open = true;
|
||||||
super(opts);
|
super(opts);
|
||||||
this.create_toolbar();
|
this.create_conform();
|
||||||
}
|
}
|
||||||
create_toolbar(){
|
create_conform(){
|
||||||
|
var w = new bricks.VBox({width:'100%', height: '100%'});
|
||||||
|
this.create_message(w);
|
||||||
|
this.create_toolbar(w);
|
||||||
|
this.add_widget(w);
|
||||||
|
}
|
||||||
|
create_message(widget){
|
||||||
|
var w = new bricks.Filler();
|
||||||
|
widget.add_widget(w);
|
||||||
|
var w1 = new bricks.VScrollPanel({});
|
||||||
|
w.add_widget(w1);
|
||||||
|
var t = new bricks.Text({otext:this.opts.message,
|
||||||
|
wrap:true,
|
||||||
|
halign:'middle',
|
||||||
|
i18n:true});
|
||||||
|
w1.add_widget(t);
|
||||||
|
}
|
||||||
|
create_toolbar(widget){
|
||||||
var desc = {
|
var desc = {
|
||||||
tools:[
|
tools:[
|
||||||
bricks.extend({
|
bricks.extend({
|
||||||
@ -26,7 +42,7 @@ bricks.Conform = class extends bricks.Message {
|
|||||||
w.bind('conform', this.conform_hndl.bind(this));
|
w.bind('conform', this.conform_hndl.bind(this));
|
||||||
w.bind('discard', this.discard_hndl.bind(this));
|
w.bind('discard', this.discard_hndl.bind(this));
|
||||||
if (!w) return;
|
if (!w) return;
|
||||||
this.message_w.add_widget(w);
|
widget.add_widget(w);
|
||||||
}
|
}
|
||||||
conform_hndl(event){
|
conform_hndl(event){
|
||||||
this.dismiss();
|
this.dismiss();
|
||||||
|
76
bricks/countdown.js
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
var bricks = window.bricks || {};
|
||||||
|
|
||||||
|
bricks.Countdown = class extends bricks.VBox {
|
||||||
|
/*
|
||||||
|
options:
|
||||||
|
limit_time: 01:00:00
|
||||||
|
text_rate:
|
||||||
|
event:
|
||||||
|
timeout
|
||||||
|
timeout event is fired after the countdown time is over.
|
||||||
|
method:
|
||||||
|
start
|
||||||
|
start method is to start the countdown, step is 1 secord
|
||||||
|
*/
|
||||||
|
constructor(opts){
|
||||||
|
super(opts);
|
||||||
|
var parts = opts.limit_time.split(':');
|
||||||
|
var hours, minutes, seconds;
|
||||||
|
switch(parts.length){
|
||||||
|
case 0:
|
||||||
|
hours = 0;
|
||||||
|
minutes = 0;
|
||||||
|
seconds = 0;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
hours = 0;
|
||||||
|
minutes = 0;
|
||||||
|
seconds = parseInt(parts[0])
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
hours = 0;
|
||||||
|
minutes = 0;
|
||||||
|
seconds = parseInt(parts[0])
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
default:
|
||||||
|
hours = parseInt(parts[0]);
|
||||||
|
minutes = parseInt(parts[1]);
|
||||||
|
seconds = parseInt(parts[2])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.seconds = hours * 3600 + minutes * 60 + seconds;
|
||||||
|
this.text_w = new bricks.Text({
|
||||||
|
text:this.limit_time,
|
||||||
|
rate:this.text_rate
|
||||||
|
});
|
||||||
|
this.add_widget(this.text_w);
|
||||||
|
}
|
||||||
|
start(){
|
||||||
|
schedule_once(this.time_down_second.bind(this), 1)
|
||||||
|
}
|
||||||
|
formatTime(seconds) {
|
||||||
|
let hrs = Math.floor(seconds / 3600);
|
||||||
|
let mins = Math.floor((seconds % 3600) / 60);
|
||||||
|
let secs = seconds % 60;
|
||||||
|
|
||||||
|
return [
|
||||||
|
hrs.toString().padStart(2, '0'),
|
||||||
|
mins.toString().padStart(2, '0'),
|
||||||
|
secs.toString().padStart(2, '0')
|
||||||
|
].join(':');
|
||||||
|
}
|
||||||
|
time_down_second(){
|
||||||
|
if (this.seconds < 1){
|
||||||
|
this.dispatch('timeout');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var h, m, s;
|
||||||
|
this.seconds -= 1;
|
||||||
|
var ts = formatTime(this.seconds);
|
||||||
|
this.text_w.set_text(ts);
|
||||||
|
schedule_once(this.time_down_second.bind(this), 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.Factory.register('Countdown', bricks.Countdown);
|
@ -6,10 +6,26 @@ body {
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
overflow-x: auto; /* 允许内容超出容器显示 */
|
||||||
|
background-color: #b5e5e5;
|
||||||
|
}
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box!important;
|
box-sizing: border-box!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
height: 1px;
|
||||||
|
background-color: #8a8a8a;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flexbox {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
.curpos {
|
.curpos {
|
||||||
border-radius: 30%;
|
border-radius: 30%;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
@ -21,6 +37,14 @@ body {
|
|||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
border: 1px solid #888888;
|
border: 1px solid #888888;
|
||||||
}
|
}
|
||||||
|
.subcard {
|
||||||
|
background-color: #eeeeee;
|
||||||
|
}
|
||||||
|
.clickable {
|
||||||
|
color: #40cc40;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.video-in-video {
|
.video-in-video {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
@ -46,6 +70,34 @@ body {
|
|||||||
grid-gap: 1px;
|
grid-gap: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.resizebox {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
background-color: darkblue;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
cursor: se-resize; /* 改变鼠标指针样式 */
|
||||||
|
}
|
||||||
|
.popup {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
box-sizing: border-box; /* 包括边框在内计算宽度和高度 */
|
||||||
|
color: #111111;
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
border: 1px solid #c1c1c1;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.titlebar {
|
||||||
|
background-color: #d8d8c8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toppopup {
|
||||||
|
box-shadow: 10px 5px 10px #000, 0 -5px 5px #fff;
|
||||||
|
}
|
||||||
|
|
||||||
.modal {
|
.modal {
|
||||||
display:none;
|
display:none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -108,7 +160,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.scroll {
|
.scroll {
|
||||||
overflow:scroll;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vcontainer {
|
.vcontainer {
|
||||||
@ -138,7 +190,7 @@ body {
|
|||||||
.filler, .hfiller, .vfiller {
|
.filler, .hfiller, .vfiller {
|
||||||
flex: auto;
|
flex: auto;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
overflow:hidden;
|
overflow:hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vfiller .vbox:last-child {
|
.vfiller .vbox:last-child {
|
||||||
@ -210,16 +262,8 @@ body {
|
|||||||
|
|
||||||
.multicolumns {
|
.multicolumns {
|
||||||
column-width: 340px;
|
column-width: 340px;
|
||||||
colomn-gap: 10px';
|
colomn-gap: 10px;
|
||||||
overflow-x:none;
|
overflow-x: none;
|
||||||
}
|
|
||||||
|
|
||||||
.popup {
|
|
||||||
display: none;
|
|
||||||
position: absolution;
|
|
||||||
box-sizing: border-box; /* 包括边框在内计算宽度和高度 */
|
|
||||||
background-color: #f1f1f1;
|
|
||||||
border: 1px solid #c1c1c1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.selected_record {
|
.selected_record {
|
||||||
@ -271,6 +315,11 @@ body {
|
|||||||
height: 50px;
|
height: 50px;
|
||||||
background-color: blue;
|
background-color: blue;
|
||||||
}
|
}
|
||||||
|
.childrensize {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
.datagrid-row {
|
.datagrid-row {
|
||||||
flex:0 0 150px;
|
flex:0 0 150px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -334,14 +383,22 @@ body {
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
.tabular-header-row {
|
.tabular-header-row {
|
||||||
background-color: #dddddd;
|
display: flex;
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
top: 0;
|
||||||
width: auto;
|
position: sticky;
|
||||||
|
background-color: #dddddd;
|
||||||
|
min-width: 0;
|
||||||
|
min-width: fit-content;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.tabular-row {
|
.tabular-row {
|
||||||
width: auto;
|
display: flex;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
|
min-width: 0;
|
||||||
|
min-width: fit-content;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.tabular-row:nth-child(odd) {
|
.tabular-row:nth-child(odd) {
|
||||||
background-color: #5dfdfd;
|
background-color: #5dfdfd;
|
||||||
@ -350,10 +407,10 @@ body {
|
|||||||
background-color: #f9f9f9;
|
background-color: #f9f9f9;
|
||||||
}
|
}
|
||||||
.tabular-row-selected {
|
.tabular-row-selected {
|
||||||
background-color: #ef0000;
|
color: #ef0000;
|
||||||
}
|
}
|
||||||
.tabular-row-content {
|
.tabular-row-content {
|
||||||
padding: 10px;
|
padding: 2;
|
||||||
}
|
}
|
||||||
.tabular-cell {
|
.tabular-cell {
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
@ -365,6 +422,7 @@ body {
|
|||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
padding: 3px;
|
||||||
background-color:#fefedd;
|
background-color:#fefedd;
|
||||||
border-top-left-radius: 10px;
|
border-top-left-radius: 10px;
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0;
|
||||||
@ -387,3 +445,19 @@ body {
|
|||||||
.llm_title {
|
.llm_title {
|
||||||
background-color:#eeeeee;
|
background-color:#eeeeee;
|
||||||
}
|
}
|
||||||
|
.progress-container {
|
||||||
|
width: 80%;
|
||||||
|
background-color: #ddd;
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.progress-bar {
|
||||||
|
height: 30px;
|
||||||
|
width: 0%;
|
||||||
|
background-color: #4CAF50;
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ bricks.DataRow = class extends bricks.HBox {
|
|||||||
*/
|
*/
|
||||||
constructor(opts){
|
constructor(opts){
|
||||||
super(opts);
|
super(opts);
|
||||||
this.set_style('width', 'auto');
|
|
||||||
this.record_w = null;
|
this.record_w = null;
|
||||||
}
|
}
|
||||||
render_header(){
|
render_header(){
|
||||||
@ -30,13 +29,17 @@ bricks.DataRow = class extends bricks.HBox {
|
|||||||
this.render(false);
|
this.render(false);
|
||||||
}
|
}
|
||||||
render(header){
|
render(header){
|
||||||
this.build_toolbar(header);
|
// this.build_toolbar(header);
|
||||||
if (this.checkField){
|
if (this.checkField){
|
||||||
var w;
|
var w;
|
||||||
if (header){
|
if (header){
|
||||||
w = new bricks.BlankIcon({});
|
w = new bricks.BlankIcon({});
|
||||||
} else {
|
} else {
|
||||||
w = new bricks.UiCheck({name:this.checkField,value:this.user_data[this.checkField]});
|
var v = 0
|
||||||
|
if (this.user_data){
|
||||||
|
v = this.user_data[this.checkField];
|
||||||
|
}
|
||||||
|
w = new bricks.UiCheck({name:this.checkField,value:v});
|
||||||
w.bind('changed', this.get_check_state.bind(this));
|
w.bind('changed', this.get_check_state.bind(this));
|
||||||
}
|
}
|
||||||
this.add_widget(w);
|
this.add_widget(w);
|
||||||
@ -87,6 +90,7 @@ bricks.DataRow = class extends bricks.HBox {
|
|||||||
}
|
}
|
||||||
build_fields(header, cw){
|
build_fields(header, cw){
|
||||||
this.record_w = new bricks.HBox({height:'auto'});
|
this.record_w = new bricks.HBox({height:'auto'});
|
||||||
|
this.record_w.set_css('childrensize');
|
||||||
this.add_widget(this.record_w);
|
this.add_widget(this.record_w);
|
||||||
this._build_fields(header, this.record_w);
|
this._build_fields(header, this.record_w);
|
||||||
}
|
}
|
||||||
@ -108,7 +112,7 @@ bricks.DataRow = class extends bricks.HBox {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var opts = bricks.extend({
|
var opts = bricks.extend({
|
||||||
margin:'3px'
|
margin:'1px'
|
||||||
}, f);
|
}, f);
|
||||||
if (header || ! this.user_data){
|
if (header || ! this.user_data){
|
||||||
opts.value = f.label || f.name;
|
opts.value = f.label || f.name;
|
||||||
@ -116,10 +120,7 @@ bricks.DataRow = class extends bricks.HBox {
|
|||||||
opts.user_data = this.user_data;
|
opts.user_data = this.user_data;
|
||||||
opts.value = opts.tip = this.user_data[f.name];
|
opts.value = opts.tip = this.user_data[f.name];
|
||||||
}
|
}
|
||||||
var cwidth = cwidths[f.name];
|
opts.cwidth = cwidths[f.name] ||f.cwidth || 10;
|
||||||
if (cwidth){
|
|
||||||
opts.cwidth = cwidth;
|
|
||||||
}
|
|
||||||
var f = bricks.get_ViewBuilder(f.uitype);
|
var f = bricks.get_ViewBuilder(f.uitype);
|
||||||
if (!f) f = bricks.get_ViewBuilder('str');
|
if (!f) f = bricks.get_ViewBuilder('str');
|
||||||
var w = f(opts);
|
var w = f(opts);
|
||||||
|
@ -138,7 +138,7 @@ bricks.DataViewer = class extends bricks.VBox {
|
|||||||
}
|
}
|
||||||
if (this.toolbar){
|
if (this.toolbar){
|
||||||
this.toolbar.tools.forEach(t => {
|
this.toolbar.tools.forEach(t => {
|
||||||
if (! edit_names.incloudes(t.name)){
|
if (! edit_names.includes(t.name)){
|
||||||
tbdesc.tools.push(t);
|
tbdesc.tools.push(t);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -168,12 +168,13 @@ bricks.DataViewer = class extends bricks.VBox {
|
|||||||
this.delete_record(this.select_row);
|
this.delete_record(this.select_row);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var d = {
|
var data = null;
|
||||||
tabular:this,
|
if (this.select_row){
|
||||||
row:this.select_row,
|
var r = this.select_row;
|
||||||
data:row.user_data
|
var data = r.user_data;
|
||||||
}
|
}
|
||||||
this.dispathc(t.name. d);
|
console.log(tdesc.name, 'clicked ==================', tdesc.name, data)
|
||||||
|
this.dispatch(tdesc.name, data);
|
||||||
}
|
}
|
||||||
get_edit_fields(){
|
get_edit_fields(){
|
||||||
var fs = this.row_options.fields;
|
var fs = this.row_options.fields;
|
||||||
@ -193,7 +194,8 @@ bricks.DataViewer = class extends bricks.VBox {
|
|||||||
this.dispatch('row_check_changed', event.params.user_data);
|
this.dispatch('row_check_changed', event.params.user_data);
|
||||||
}
|
}
|
||||||
async renew_record_view(form, row){
|
async renew_record_view(form, row){
|
||||||
var d = form.getValue();
|
var d = form._getValue();
|
||||||
|
d = form._getValue();
|
||||||
var record = bricks.extend(row.user_data, d);
|
var record = bricks.extend(row.user_data, d);
|
||||||
row.renew(record);
|
row.renew(record);
|
||||||
}
|
}
|
||||||
@ -215,6 +217,11 @@ bricks.DataViewer = class extends bricks.VBox {
|
|||||||
fs.push(this.fields[i]);
|
fs.push(this.fields[i]);
|
||||||
}
|
}
|
||||||
var f = new bricks.ModalForm({
|
var f = new bricks.ModalForm({
|
||||||
|
"widget":this,
|
||||||
|
"archor":"cc",
|
||||||
|
"movable":true,
|
||||||
|
"resizable":true,
|
||||||
|
"archor":"cc",
|
||||||
"width":"90%",
|
"width":"90%",
|
||||||
"height":"70%",
|
"height":"70%",
|
||||||
"submit_url":this.editable.new_data_url,
|
"submit_url":this.editable.new_data_url,
|
||||||
@ -225,10 +232,10 @@ bricks.DataViewer = class extends bricks.VBox {
|
|||||||
}
|
}
|
||||||
async add_record_finish(f, event){
|
async add_record_finish(f, event){
|
||||||
f.dismiss();
|
f.dismiss();
|
||||||
|
this.render();
|
||||||
var resp = event.params;
|
var resp = event.params;
|
||||||
var desc = await resp.json();
|
var desc = await resp.json();
|
||||||
var w = await bricks.widgetBuild(desc);
|
var w = await bricks.widgetBuild(desc);
|
||||||
this.render();
|
|
||||||
}
|
}
|
||||||
update_record(){
|
update_record(){
|
||||||
var record = this.select_row.user_data;
|
var record = this.select_row.user_data;
|
||||||
@ -239,6 +246,10 @@ bricks.DataViewer = class extends bricks.VBox {
|
|||||||
fields.push(f);
|
fields.push(f);
|
||||||
}
|
}
|
||||||
var f = new bricks.ModalForm({
|
var f = new bricks.ModalForm({
|
||||||
|
"widget":this,
|
||||||
|
"movable":true,
|
||||||
|
"resizable":true,
|
||||||
|
"archor":"cc",
|
||||||
"width":"90%",
|
"width":"90%",
|
||||||
"height":"70%",
|
"height":"70%",
|
||||||
"submit_url":this.editable.update_data_url+'?id=' + record.id,
|
"submit_url":this.editable.update_data_url+'?id=' + record.id,
|
||||||
@ -251,15 +262,15 @@ bricks.DataViewer = class extends bricks.VBox {
|
|||||||
f.dismiss();
|
f.dismiss();
|
||||||
}
|
}
|
||||||
async update_record_finish(form, event){
|
async update_record_finish(form, event){
|
||||||
|
await this.renew_record_view(form, this.select_row);
|
||||||
var resp = event.params;
|
var resp = event.params;
|
||||||
var desc = await resp.json();
|
var desc = await resp.json();
|
||||||
var w = await bricks.widgetBuild(desc);
|
var w = await bricks.widgetBuild(desc);
|
||||||
if (desc.widgettype == 'Message'){
|
|
||||||
await this.renew_record_view(form, this.select_row);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
delete_record(row, record){
|
delete_record(row, record){
|
||||||
var conform_w = new bricks.Conform({
|
var conform_w = new bricks.Conform({
|
||||||
|
cwidth:16,
|
||||||
|
cheight:9,
|
||||||
target:this,
|
target:this,
|
||||||
title:'Delete conform',
|
title:'Delete conform',
|
||||||
message:'Are you sure to delete is record?'
|
message:'Are you sure to delete is record?'
|
||||||
@ -315,8 +326,8 @@ bricks.DataViewer = class extends bricks.VBox {
|
|||||||
var d = await this.loader.loadNextPage();
|
var d = await this.loader.loadNextPage();
|
||||||
if (d){
|
if (d){
|
||||||
this.dataHandle(d);
|
this.dataHandle(d);
|
||||||
var total = this.scrollpanel.dom_element.scrollHeight - this.scrollpanel.dom_element.clientHeight;
|
// var total = this.scrollpanel.dom_element.scrollHeight - this.scrollpanel.dom_element.clientHeight;
|
||||||
this.scrollpanel.dom_element.scrollTop = d.pos_rate * total;
|
// this.scrollpanel.dom_element.scrollTop = d.pos_rate * total;
|
||||||
} else {
|
} else {
|
||||||
bricks.debug(this.loader, 'load next page error');
|
bricks.debug(this.loader, 'load next page error');
|
||||||
}
|
}
|
||||||
|
119
bricks/docxviewer.js
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/* need mammoth module
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/mammoth/1.4.2/mammoth.browser.min.js"></script>
|
||||||
|
*/
|
||||||
|
var bricks = window.bricks || {};
|
||||||
|
|
||||||
|
bricks.DOCXviewer = class extends bricks.VBox {
|
||||||
|
/*
|
||||||
|
url:
|
||||||
|
*/
|
||||||
|
constructor(opts){
|
||||||
|
super(opts);
|
||||||
|
this.bind('on_parent', this.set_url.bind(this));
|
||||||
|
// schedule_once(this.set_url.bind(this, this.url), 0.2);
|
||||||
|
}
|
||||||
|
async set_url(url){
|
||||||
|
var container = this.dom_element
|
||||||
|
var hab = new bricks.HttpArrayBuffer();
|
||||||
|
var ab = await hab.get(this.url);
|
||||||
|
var result = await mammoth.convertToHtml({ arrayBuffer: ab });
|
||||||
|
container.innerHTML = result.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractBodyContent(htmlString) {
|
||||||
|
// 正则表达式匹配<body>和</body>之间的内容
|
||||||
|
const regex = /<body[^>]*>([\s\S]*?)<\/body>/i;
|
||||||
|
const matches = htmlString.match(regex);
|
||||||
|
return matches ? matches[1] : null; // 如果匹配到,返回匹配的内容,否则返回null
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.EXCELviewer = class extends bricks.VBox {
|
||||||
|
constructor(opts){
|
||||||
|
opts.height = "100%",
|
||||||
|
super(opts);
|
||||||
|
this.sheets_w = new bricks.HBox({cheight:3, width:'100%'});
|
||||||
|
this.sheets_w.set_css('scroll');
|
||||||
|
this.cur_sheetname = null;
|
||||||
|
this.container = new bricks.Filler({});
|
||||||
|
this.add_widget(this.container);
|
||||||
|
this.add_widget(this.sheets_w);
|
||||||
|
this.bind('on_parent', this.set_url.bind(this));
|
||||||
|
}
|
||||||
|
async set_url(url){
|
||||||
|
this.sheets_w.clear_widgets();
|
||||||
|
var hab = new bricks.HttpArrayBuffer();
|
||||||
|
var ab = await hab.get(this.url);
|
||||||
|
const data = new Uint8Array(ab);
|
||||||
|
this.workbook = XLSX.read(data, {type: 'array'});
|
||||||
|
this.workbook.SheetNames.forEach((sheetname, index) => {
|
||||||
|
var w = new bricks.Text({text:sheetname, wrap:false});
|
||||||
|
w.set_css('clickable');
|
||||||
|
w.set_style('padding', '10px');
|
||||||
|
w.bind('click', this.show_sheet_by_name.bind(this, sheetname, w));
|
||||||
|
this.sheets_w.add_widget(w);
|
||||||
|
if (index==0){
|
||||||
|
this.show_sheet_by_name(this.workbook.SheetNames[0], w);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
show_sheet_by_name(sheetname, tw){
|
||||||
|
if (this.cur_sheetname == sheetname) return;
|
||||||
|
this.sheets_w.children.forEach(c => c.set_css('selected', true));
|
||||||
|
tw.set_css('selected');
|
||||||
|
const x = new bricks.VScrollPanel({width: '100%', height: '100%'});
|
||||||
|
const sheet = this.workbook.Sheets[sheetname];
|
||||||
|
// const html = extractBodyContent(XLSX.utils.sheet_to_html(sheet));
|
||||||
|
const html = XLSX.utils.sheet_to_html(sheet);
|
||||||
|
x.dom_element.innerHTML = html;
|
||||||
|
this.container.clear_widgets();
|
||||||
|
this.container.add_widget(x);
|
||||||
|
this.cur_sheetname = sheetname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.PDFviewer = class extends bricks.VBox {
|
||||||
|
/*
|
||||||
|
url:
|
||||||
|
*/
|
||||||
|
constructor(opts){
|
||||||
|
opts.width = '100%';
|
||||||
|
super(opts);
|
||||||
|
this.bind('on_parent', this.set_url.bind(this));
|
||||||
|
}
|
||||||
|
async set_url(url){
|
||||||
|
var container = this.dom_element
|
||||||
|
var hab = new bricks.HttpArrayBuffer();
|
||||||
|
var ab = await hab.get(this.url);
|
||||||
|
const task = pdfjsLib.getDocument({ data: ab });
|
||||||
|
task.promise.then((pdf) => {
|
||||||
|
this.pdf = pdf;
|
||||||
|
for (let i = 1; i <= this.pdf.numPages; i++) {
|
||||||
|
this.pdf.getPage(i).then((page) => {
|
||||||
|
this.add_page_content(page);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log('error');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
add_page_content(page){
|
||||||
|
const scale = 1.5;
|
||||||
|
const viewport = page.getViewport({ scale });
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
const context = canvas.getContext('2d');
|
||||||
|
canvas.height = viewport.height;
|
||||||
|
canvas.width = viewport.width;
|
||||||
|
page.render({ canvasContext: context, viewport });
|
||||||
|
var w = new bricks.JsWidget();
|
||||||
|
w.dom_element.appendChild(canvas);
|
||||||
|
this.add_widget(w);
|
||||||
|
if (i < this.pdf.numPages){
|
||||||
|
w = new bricks.Splitter();
|
||||||
|
this.add_widget(w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bricks.Factory.register('DOCXviewer', bricks.DOCXviewer);
|
||||||
|
bricks.Factory.register('EXCELviewer', bricks.EXCELviewer);
|
||||||
|
bricks.Factory.register('PDFviewer', bricks.PDFviewer);
|
@ -30,21 +30,19 @@ bricks.DynamicColumn = class extends bricks.Layout {
|
|||||||
var cw;
|
var cw;
|
||||||
var cols;
|
var cols;
|
||||||
var gap;
|
var gap;
|
||||||
var width = this.get_width();
|
|
||||||
if (this.col_cwidth){
|
|
||||||
cw = bricks.app.charsize * this.col_cwidth;
|
|
||||||
} else {
|
|
||||||
cw = this.col_width;
|
|
||||||
}
|
|
||||||
gap = bricks.app.charsize * (this.col_cgap || 0.1);
|
gap = bricks.app.charsize * (this.col_cgap || 0.1);
|
||||||
if (width > 0){
|
var width = bricks.app.screenWidth();
|
||||||
if (bricks.is_mobile() && (width < this.get_height())){
|
var height = bricks.app.screenHeight();
|
||||||
cols = this.mobile_cols || 1;
|
if (bricks.is_mobile() && width < height){
|
||||||
} else {
|
cols = this.mobile_cols;
|
||||||
cols = (width + gap) / (cw + gap)
|
|
||||||
}
|
|
||||||
cols = Math.floor(width/cw);
|
|
||||||
cw = (width - (cols - 1) * gap) / cols;
|
cw = (width - (cols - 1) * gap) / cols;
|
||||||
|
console.log('====mobile==cols=', cols, '====');
|
||||||
|
} else {
|
||||||
|
if (this.col_cwidth){
|
||||||
|
cw = bricks.app.charsize * this.col_cwidth;
|
||||||
|
} else {
|
||||||
|
cw = this.col_width;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.dom_element.style.gridTemplateColumns = "repeat(auto-fill, minmax(" + cw + "px, 1fr))";
|
this.dom_element.style.gridTemplateColumns = "repeat(auto-fill, minmax(" + cw + "px, 1fr))";
|
||||||
this.set_style('gap', gap + 'px');
|
this.set_style('gap', gap + 'px');
|
||||||
|
@ -83,6 +83,7 @@ bricks.EchartsExt = class extends bricks.VBox {
|
|||||||
this.valueFields = this.get_series(data);
|
this.valueFields = this.get_series(data);
|
||||||
data = this.pivotify(data);
|
data = this.pivotify(data);
|
||||||
}
|
}
|
||||||
|
this.chart = echarts.init(this.holder.dom_element);
|
||||||
var opts = this.setup_options(data);
|
var opts = this.setup_options(data);
|
||||||
opts.grid = {
|
opts.grid = {
|
||||||
left: '3%',
|
left: '3%',
|
||||||
|
0
bricks/factory.js
Executable file → Normal file
@ -20,10 +20,22 @@ bricks.IconBar = class extends bricks.HBox {
|
|||||||
if (! opts.cheight){
|
if (! opts.cheight){
|
||||||
opts.cheight = 2;
|
opts.cheight = 2;
|
||||||
}
|
}
|
||||||
|
if (! opts.rate){
|
||||||
|
opts.rate = 1;
|
||||||
|
}
|
||||||
super(opts);
|
super(opts);
|
||||||
|
this.set_css('childrensize');
|
||||||
|
this.height_int = 0;
|
||||||
var tools = this.opts.tools;
|
var tools = this.opts.tools;
|
||||||
for (var i=0;i<tools.length;i++){
|
for (var i=0;i<tools.length;i++){
|
||||||
var w = this.build_item(tools[i]);
|
var opts_i = bricks.extend({}, tools[i]);
|
||||||
|
if (!opts_i.rate){
|
||||||
|
opts_i.rate = this.rate;
|
||||||
|
}
|
||||||
|
opts_i.cheight = opts.cheight;
|
||||||
|
opts_i.cwidth = opts.cheight;
|
||||||
|
opts_i.dynsize = true;
|
||||||
|
var w = this.build_item(opts_i);
|
||||||
w.set_style('margin-left', this.opts.margin || '10px');
|
w.set_style('margin-left', this.opts.margin || '10px');
|
||||||
w.set_style('margin-right', this.opts.margin || '10px');
|
w.set_style('margin-right', this.opts.margin || '10px');
|
||||||
if (tools[i].name){
|
if (tools[i].name){
|
||||||
@ -37,27 +49,27 @@ bricks.IconBar = class extends bricks.HBox {
|
|||||||
}
|
}
|
||||||
build_item(opts){
|
build_item(opts){
|
||||||
var rate = opts.rate || this.opts.rate || 1;
|
var rate = opts.rate || this.opts.rate || 1;
|
||||||
var h = bricks.app.charsize * rate;
|
var h = bricks.app.charsize * rate * opts.cheight;
|
||||||
if (this.height_int < h){
|
if (this.height_int < h){
|
||||||
this.height_int = h;
|
this.height_int = h;
|
||||||
}
|
}
|
||||||
if (opts.name == 'blankicon'){
|
if (opts.name == 'blankicon'){
|
||||||
return new bricks.BlankIcon({
|
return new bricks.BlankIcon({
|
||||||
rate:rate,
|
rate:rate,
|
||||||
|
cheight:opts.cheight,
|
||||||
|
cwidth:opts.cwidth,
|
||||||
dynsize:opts.dynsize||true
|
dynsize:opts.dynsize||true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var opts1 = bricks.extend({}, opts);
|
opts.url = opts.icon;
|
||||||
opts1.url = opts.icon;
|
var w = new bricks.Icon(opts);
|
||||||
opts1.rate = opts.rate || rate;
|
w.bind('click', this.regen_event.bind(this, opts));
|
||||||
opts1.dynsize = opts.dynsize||true;
|
|
||||||
var w = new bricks.Icon(opts1);
|
|
||||||
w.bind('click', this.regen_event.bind(this, opts1));
|
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
regen_event(desc, event){
|
regen_event(desc, event){
|
||||||
this.dispatch(desc.name, desc);
|
this.dispatch(desc.name, desc);
|
||||||
this.dispatch('command', desc);
|
this.dispatch('command', desc);
|
||||||
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ bricks.FormBase = class extends bricks.Layout {
|
|||||||
w.reset();
|
w.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getValue(){
|
_getValue(){
|
||||||
var data = {};
|
var data = {};
|
||||||
for (var name in this.name_inputs){
|
for (var name in this.name_inputs){
|
||||||
if (! this.name_inputs.hasOwnProperty(name)){
|
if (! this.name_inputs.hasOwnProperty(name)){
|
||||||
@ -195,6 +195,14 @@ bricks.FormBase = class extends bricks.Layout {
|
|||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
getValue(){
|
||||||
|
if (this.data) {
|
||||||
|
var ret = this.data;
|
||||||
|
this.data = null;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return this.get_formdata();
|
||||||
|
}
|
||||||
get_formdata(){
|
get_formdata(){
|
||||||
var data = new FormData();
|
var data = new FormData();
|
||||||
for (var name in this.name_inputs){
|
for (var name in this.name_inputs){
|
||||||
@ -204,37 +212,35 @@ bricks.FormBase = class extends bricks.Layout {
|
|||||||
var w = this.name_inputs[name];
|
var w = this.name_inputs[name];
|
||||||
var d = w.getValue();
|
var d = w.getValue();
|
||||||
if (w.required && ( d[name] == '' || d[name] === null)){
|
if (w.required && ( d[name] == '' || d[name] === null)){
|
||||||
bricks.debug('data=', data, 'd=', d);
|
|
||||||
new bricks.Error({title:'Requirement', message:'required field must input"' + w.label + '"'})
|
new bricks.Error({title:'Requirement', message:'required field must input"' + w.label + '"'})
|
||||||
w.focus();
|
w.focus();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (bricks.need_formdata_fields.includes(w.uitype)){
|
if (d[name] === null){
|
||||||
var files = w.get_files();
|
continue;
|
||||||
for (var i=0;i<files.length;i++){
|
|
||||||
// data.append(name, w.fileContents[i].body, w.fileContents[i].filename);
|
|
||||||
data.append(name, files[i]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
data.append(name, d[name]);
|
|
||||||
}
|
}
|
||||||
|
w.set_formdata(data);
|
||||||
}
|
}
|
||||||
|
this.data = data;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
async validation(){
|
async validation(){
|
||||||
var running = new bricks.Running({target:this});
|
var running = new bricks.Running({target:this});
|
||||||
try {
|
try {
|
||||||
var data;
|
var data;
|
||||||
|
data = this.get_formdata();
|
||||||
|
/*
|
||||||
if (this.need_formdata){
|
if (this.need_formdata){
|
||||||
data = this.get_formdata();
|
data = this.get_formdata();
|
||||||
} else {
|
} else {
|
||||||
data = this.getValue();
|
data = this.getValue();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if (! data) {
|
if (! data) {
|
||||||
running.dismiss();
|
running.dismiss();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data = bricks.delete_null_values(data);
|
// data = bricks.delete_null_values(data);
|
||||||
this.dispatch('submit', data);
|
this.dispatch('submit', data);
|
||||||
if (this.submit_url){
|
if (this.submit_url){
|
||||||
var rc = new bricks.HttpResponse();
|
var rc = new bricks.HttpResponse();
|
||||||
|
@ -4,34 +4,37 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<link rel="stylesheet" href="/bricks/3parties/xterm.css" />
|
<link rel="stylesheet" href="{{entire_url('/bricks/3parties/xterm.css')}}" />
|
||||||
<link href="/bricks/3parties/video-js.css" rel="stylesheet" />
|
<link href="{{entire_url('/bricks/3parties/video-js.css')}}" rel="stylesheet" />
|
||||||
<link rel="stylesheet" href="/bricks/css/bricks.css">
|
<link rel="stylesheet" href="{{entire_url('/bricks/css/bricks.css')}}">
|
||||||
|
<link rel="stylesheet", href="{{entire_url('/css/myapp.css')}}">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!--
|
<!--
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/js-docx-viewer/dist/css/docxviewer.min.css">
|
||||||
<script src="//cdn.bootcdn.net/ajax/libs/eruda/2.3.3/eruda.js"></script>
|
<script src="//cdn.bootcdn.net/ajax/libs/eruda/2.3.3/eruda.js"></script>
|
||||||
<script>eruda.init();</script>
|
<script>eruda.init();</script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/@ricky0123/vad-web@0.0.7/dist/bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/@ricky0123/vad-web@0.0.7/dist/bundle.min.js"></script>
|
||||||
|
<script src="https://unpkg.com/docx-js@3.2.0/lib/docx.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.14.305/pdf.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/mammoth/1.4.2/mammoth.browser.min.js"></script>
|
||||||
-->
|
-->
|
||||||
<script type="text/javascript" src="https://registry.npmmirror.com/echarts/5.5.1/files/dist/echarts.min.js"></script>
|
<script type="text/javascript" src="https://registry.npmmirror.com/echarts/5.5.1/files/dist/echarts.min.js"></script>
|
||||||
|
|
||||||
<script src="/bricks/3parties/marked.min.js"></script>
|
<script src="{{entire_url('/bricks/3parties/marked.min.js')}}"></script>
|
||||||
<script src="/bricks/3parties/xterm.js"></script>
|
<script src="{{entire_url('/bricks/3parties/xterm.js')}}"></script>
|
||||||
<script src="/bricks/3parties/video.min.js"></script>
|
<script src="{{entire_url('/bricks/3parties/xterm-addon-fit.js')}}"></script>
|
||||||
|
<script src="{{entire_url('/bricks/3parties/video.min.js')}}"></script>
|
||||||
<!---
|
<!---
|
||||||
<link href="https://unpkg.com/video.js@6/dist/video-js.css" rel="stylesheet">
|
<link href="https://unpkg.com/video.js@6/dist/video-js.css" rel="stylesheet">
|
||||||
<script src="https://unpkg.com/video.js@6/dist/video.js"></script></head>
|
<script src="https://unpkg.com/video.js@6/dist/video.js"></script></head>
|
||||||
--->
|
--->
|
||||||
|
|
||||||
<script src="/bricks/3parties/recorder.wav.min.js"></script>
|
<script src="{{entire_url('/bricks/3parties/recorder.wav.min.js')}}"></script>
|
||||||
<script src="/bricks/bricks.js"></script>
|
<script src="{{entire_url('/bricks/bricks.js')}}"></script>
|
||||||
|
<script src="{{entire_url('/js/myapp.js')}}"></script>
|
||||||
<script>
|
<script>
|
||||||
/*
|
|
||||||
if (bricks.is_mobile()){
|
|
||||||
alert('wh=' + window.innerWidth + ':' + window.innerHeight);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
const opts = {
|
const opts = {
|
||||||
"widget":
|
"widget":
|
||||||
|
0
bricks/i18n.js
Executable file → Normal file
55
bricks/iconbarpage.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
var bricks = window.bricks || {};
|
||||||
|
bricks.IconbarPage = class extends bricks.VBox {
|
||||||
|
/*
|
||||||
|
opts={
|
||||||
|
bar_opts:
|
||||||
|
bar_at: top or bottom
|
||||||
|
}
|
||||||
|
bar_opts:{
|
||||||
|
margin:
|
||||||
|
rate:
|
||||||
|
tools:
|
||||||
|
}
|
||||||
|
tools = [
|
||||||
|
tool, ...
|
||||||
|
]
|
||||||
|
tool = {
|
||||||
|
name:
|
||||||
|
icon:
|
||||||
|
label: optional
|
||||||
|
tip,
|
||||||
|
dynsize
|
||||||
|
rate:
|
||||||
|
context:
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
constructor(opts){
|
||||||
|
opts.height = '100%'
|
||||||
|
opts.bar_at = opts.bar_at || 'top';
|
||||||
|
super(opts);
|
||||||
|
var bar = new bricks.IconTextBar(this.bar_opts);
|
||||||
|
this.content = new bricks.Filler({});
|
||||||
|
if (this.bar_at == 'top'){
|
||||||
|
this.add_widget(bar);
|
||||||
|
this.add_widget(this.content);
|
||||||
|
} else {
|
||||||
|
this.add_widget(this.content);
|
||||||
|
this.add_widget(bar);
|
||||||
|
}
|
||||||
|
bar.bind('command', this.command_handle.bind(this))
|
||||||
|
schedule_once(this.show_content.bind(this, this.bar_opts.tools[0]), 0.1);
|
||||||
|
}
|
||||||
|
async command_handle(event){
|
||||||
|
var tool = event.params;
|
||||||
|
await this.show_content(tool);
|
||||||
|
}
|
||||||
|
async show_content(tool){
|
||||||
|
var w = await bricks.widgetBuild(tool.content, this);
|
||||||
|
if (w && ! w.parent) {
|
||||||
|
this.content.add_widget(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.Factory.register('IconbarPage', bricks.IconbarPage);
|
@ -1,6 +1,7 @@
|
|||||||
var bricks = window.bricks || {};
|
var bricks = window.bricks || {};
|
||||||
bricks.Iframe = class extends bricks.Layout {
|
bricks.Iframe = class extends bricks.Layout {
|
||||||
constructor(opts){
|
constructor(opts){
|
||||||
|
opts.height = opts.height || '100%';
|
||||||
super(opts);
|
super(opts);
|
||||||
this.dom_element.src = opts.url;
|
this.dom_element.src = opts.url;
|
||||||
}
|
}
|
||||||
@ -9,4 +10,12 @@ bricks.Iframe = class extends bricks.Layout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bricks.NewWindow = class extends bricks.JsWidget {
|
||||||
|
constructor(opts){
|
||||||
|
super(opts);
|
||||||
|
window.open(opts.url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.Factory.register('NewWindow', bricks.NewWindow);
|
||||||
bricks.Factory.register('Iframe', bricks.Iframe);
|
bricks.Factory.register('Iframe', bricks.Iframe);
|
||||||
|
3
bricks/image.js
Executable file → Normal file
@ -46,8 +46,7 @@ bricks.Image = class extends bricks.JsWidget {
|
|||||||
|
|
||||||
// 获取画布数据并转换为 base64
|
// 获取画布数据并转换为 base64
|
||||||
var dataURL = canvas.toDataURL('image/png'); // 可以根据需要修改图像格式
|
var dataURL = canvas.toDataURL('image/png'); // 可以根据需要修改图像格式
|
||||||
dataURL = this.removeBase64Header(dataURL);
|
// dataURL = this.removeBase64Header(dataURL);
|
||||||
console.log(dataURL);
|
|
||||||
return dataURL;
|
return dataURL;
|
||||||
}
|
}
|
||||||
set_url(url){
|
set_url(url){
|
||||||
|
BIN
bricks/imgs/app.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
bricks/imgs/app_delete.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
bricks/imgs/app_fullscreen.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
bricks/imgs/app_minimax.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
bricks/imgs/camera.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
bricks/imgs/dislike.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
bricks/imgs/input.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
bricks/imgs/left-bottom-triangle.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
BIN
bricks/imgs/left-top-triangle.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 12 KiB |
BIN
bricks/imgs/right-bottom-triangle.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
bricks/imgs/right-top-triangle.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
bricks/imgs/search.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
bricks/imgs/switch-camera.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
bricks/imgs/tag.png
Normal file
After Width: | Height: | Size: 15 KiB |
203
bricks/input.js
Executable file → Normal file
@ -17,6 +17,9 @@ bricks.UiType =class extends bricks.Layout {
|
|||||||
}
|
}
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
set_formdata(formdata){
|
||||||
|
formdata.append(this.name, this.resultValue());
|
||||||
|
}
|
||||||
resultValue(){
|
resultValue(){
|
||||||
return this.value;
|
return this.value;
|
||||||
}
|
}
|
||||||
@ -46,6 +49,47 @@ bricks.UiType =class extends bricks.Layout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bricks.UiAudioRecorder = class extends bricks.AudioRecorder {
|
||||||
|
constructor(opts){
|
||||||
|
super(opts);
|
||||||
|
this.uitype = 'audiorecorder';
|
||||||
|
this.name = this.opts.name;
|
||||||
|
this.required = opts.required || false;
|
||||||
|
this.value = opts.value || opts.defaultvalue||'';
|
||||||
|
this.bind('record_ended', this.getValue.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
getValue(){
|
||||||
|
var o = {}
|
||||||
|
this.value = this.recordData.data;
|
||||||
|
o[this.name] = this.value;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
set_formdata(formdata){
|
||||||
|
formdata.append(this.name, this.value, 'record.wav');
|
||||||
|
}
|
||||||
|
resultValue(){
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
focus(){
|
||||||
|
this.dom_element.focus();
|
||||||
|
}
|
||||||
|
reset(){
|
||||||
|
}
|
||||||
|
setValue(v){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
set_disabled(f){
|
||||||
|
this.dom_element.disabled = f;
|
||||||
|
}
|
||||||
|
set_readonly(f){
|
||||||
|
this.dom_element.readOnly = f;
|
||||||
|
}
|
||||||
|
set_required(f){
|
||||||
|
this.dom_element.required = f;
|
||||||
|
this.required = f;
|
||||||
|
}
|
||||||
|
}
|
||||||
bricks.UiAudioText = class extends bricks.UiType {
|
bricks.UiAudioText = class extends bricks.UiType {
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
@ -70,10 +114,12 @@ bricks.UiAudioText = class extends bricks.UiType {
|
|||||||
clear_text(){
|
clear_text(){
|
||||||
this.text_w.setValue('');
|
this.text_w.setValue('');
|
||||||
}
|
}
|
||||||
getValue(){
|
resultValue(){
|
||||||
return this.text_w.getValue();
|
this.value = this.text_w.resultValue();
|
||||||
|
return this.value;
|
||||||
}
|
}
|
||||||
setValue(v){
|
setValue(v){
|
||||||
|
this.value = v;
|
||||||
this.text_w.setValue(v);
|
this.text_w.setValue(v);
|
||||||
}
|
}
|
||||||
set_result_text(event){
|
set_result_text(event){
|
||||||
@ -203,6 +249,105 @@ bricks.UiStr =class extends bricks.UiType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bricks.UiSearch = class extends bricks.HBox {
|
||||||
|
/*
|
||||||
|
search_url:
|
||||||
|
valueField
|
||||||
|
textField
|
||||||
|
select_event
|
||||||
|
popup_options
|
||||||
|
value,
|
||||||
|
text
|
||||||
|
*/
|
||||||
|
constructor(opts){
|
||||||
|
super(opts);
|
||||||
|
this.uitype = 'search';
|
||||||
|
var inputdesc = {
|
||||||
|
name:this.name,
|
||||||
|
value:this.text,
|
||||||
|
readonly:true
|
||||||
|
}
|
||||||
|
this.str_in = new bricks.UiStr(inputdesc);
|
||||||
|
this.search_icon = new bricks.Icon({
|
||||||
|
url:bricks_resource('imgs/search.png'),
|
||||||
|
rate:1.5
|
||||||
|
});
|
||||||
|
this.str_in.set_css('filler');
|
||||||
|
this.search_icon.set_css('clickable');
|
||||||
|
this.search_icon.bind('click', this.open_search_window.bind(this));
|
||||||
|
this.add_widget(this.str_in);
|
||||||
|
this.add_widget(this.search_icon);
|
||||||
|
}
|
||||||
|
async open_search_window(event){
|
||||||
|
var desc = {
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":this.search_url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var w = await bricks.widgetBuild(desc, this);
|
||||||
|
var tabular = null;
|
||||||
|
for (var i=0;i<w.children.length;i++){
|
||||||
|
if (w.children[i] instanceof bricks.Tabular){
|
||||||
|
tabular = w.children[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!tabular){
|
||||||
|
console.log('tubular not found is w');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var win = bricks.default_popupwindow(this.popup_options||{});
|
||||||
|
win.add_widget(w);
|
||||||
|
win.open();
|
||||||
|
tabular.bind(this.search_event, this.set_data.bind(this));
|
||||||
|
tabular.bind(this.search_event, win.dismiss.bind(win));
|
||||||
|
}
|
||||||
|
set_data(event){
|
||||||
|
var d = event.params;
|
||||||
|
this.value = d[this.valueField];
|
||||||
|
this.str_in.setValue(d[this.textField])
|
||||||
|
}
|
||||||
|
getValue(){
|
||||||
|
var o = {}
|
||||||
|
o[this.name] = this.resultValue();
|
||||||
|
var d = this.getUserData();
|
||||||
|
if (d){
|
||||||
|
o = bricks.extend(o, d);
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
set_formdata(formdata){
|
||||||
|
formdata.append(this.name, this.resultValue());
|
||||||
|
}
|
||||||
|
resultValue(){
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
focus(){
|
||||||
|
this.str_in.dom_element.focus();
|
||||||
|
}
|
||||||
|
reset(){
|
||||||
|
var v = this.opts.value||this.opts.defaultvalue|| '';
|
||||||
|
this.setValue(v);
|
||||||
|
this.str_in.setValue(this.opts.text||'');
|
||||||
|
}
|
||||||
|
setValue(v, t){
|
||||||
|
if (! v)
|
||||||
|
v = '';
|
||||||
|
this.vlaue = v;
|
||||||
|
this.str_in.setValue(t);
|
||||||
|
}
|
||||||
|
set_disabled(f){
|
||||||
|
this.dom_element.disabled = f;
|
||||||
|
}
|
||||||
|
set_readonly(f){
|
||||||
|
this.dom_element.readOnly = f;
|
||||||
|
}
|
||||||
|
set_required(f){
|
||||||
|
this.dom_element.required = f;
|
||||||
|
this.required = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
bricks.UiPassword =class extends bricks.UiStr {
|
bricks.UiPassword =class extends bricks.UiStr {
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
@ -265,6 +410,7 @@ bricks.UiFloat =class extends bricks.UiInt {
|
|||||||
this.dom_element.step = step;
|
this.dom_element.step = step;
|
||||||
}
|
}
|
||||||
resultValue(){
|
resultValue(){
|
||||||
|
super.resultValue();
|
||||||
return parseFloat(this.value);
|
return parseFloat(this.value);
|
||||||
}
|
}
|
||||||
setValue(v){
|
setValue(v){
|
||||||
@ -331,7 +477,7 @@ bricks.UiFile =class extends bricks.UiStr {
|
|||||||
return this.dom_element.files;
|
return this.dom_element.files;
|
||||||
}
|
}
|
||||||
resultValue(){
|
resultValue(){
|
||||||
return this.get_files();
|
return this.get_files()[0];
|
||||||
}
|
}
|
||||||
setValue(v){
|
setValue(v){
|
||||||
return;
|
return;
|
||||||
@ -344,6 +490,12 @@ bricks.UiImage =class extends bricks.VBox {
|
|||||||
opts.name = opts.name || 'image';
|
opts.name = opts.name || 'image';
|
||||||
super(opts);
|
super(opts);
|
||||||
this.uitype='image';
|
this.uitype='image';
|
||||||
|
this.camera_w = new bricks.Icon({
|
||||||
|
url:bricks_resource('imgs/camera.png'),
|
||||||
|
tip:'use cemera to take a picture',
|
||||||
|
rate:2});
|
||||||
|
this.add_widget(this.camera_w);
|
||||||
|
this.camera_w.bind('click', this.take_photo.bind(this));
|
||||||
this.bind('drop', this.dropHandle.bind(this));
|
this.bind('drop', this.dropHandle.bind(this));
|
||||||
this.input = document.createElement('input');
|
this.input = document.createElement('input');
|
||||||
this.input.type = 'file';
|
this.input.type = 'file';
|
||||||
@ -354,6 +506,27 @@ bricks.UiImage =class extends bricks.VBox {
|
|||||||
this.dom_element.appendChild(this.input);
|
this.dom_element.appendChild(this.input);
|
||||||
this.imgw = null;
|
this.imgw = null;
|
||||||
}
|
}
|
||||||
|
take_photo(event){
|
||||||
|
event.stopPropagation();
|
||||||
|
var camera = new bricks.Camera({
|
||||||
|
"archor":"cc",
|
||||||
|
"auto_open":true,
|
||||||
|
"height":"90%",
|
||||||
|
"width":"90%"
|
||||||
|
});
|
||||||
|
camera.bind('shot', this.accept_photo.bind(this, camera));
|
||||||
|
}
|
||||||
|
accept_photo(camera, event){
|
||||||
|
camera.dismiss();
|
||||||
|
if (this.imgw){
|
||||||
|
this.remove_widget(this.imgw);
|
||||||
|
}
|
||||||
|
this.imgw = new bricks.Image({
|
||||||
|
url:event.params,
|
||||||
|
width:'100%'
|
||||||
|
});
|
||||||
|
this.add_widget(this.imgw);
|
||||||
|
}
|
||||||
handleFileSelect(event){
|
handleFileSelect(event){
|
||||||
const file = event.target.files[0];
|
const file = event.target.files[0];
|
||||||
this.show_image(file);
|
this.show_image(file);
|
||||||
@ -367,7 +540,11 @@ bricks.UiImage =class extends bricks.VBox {
|
|||||||
show_image(file) {
|
show_image(file) {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onload = (e) => {
|
reader.onload = (e) => {
|
||||||
this.clear_widgets();
|
if (this.imgw){
|
||||||
|
this.remove_widget(this.imgw);
|
||||||
|
}
|
||||||
|
this.value = e.target.result;
|
||||||
|
console.log('this.value=', this.value);
|
||||||
this.imgw = new bricks.Image({
|
this.imgw = new bricks.Image({
|
||||||
url:e.target.result,
|
url:e.target.result,
|
||||||
width:'100%'
|
width:'100%'
|
||||||
@ -376,10 +553,22 @@ bricks.UiImage =class extends bricks.VBox {
|
|||||||
};
|
};
|
||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
}
|
}
|
||||||
|
set_formdata(fd){
|
||||||
|
// fd.append(this.name, this.resultValue(), 'test.png');
|
||||||
|
fd.append(this.name, this.resultValue());
|
||||||
|
}
|
||||||
|
resultValue(){
|
||||||
|
if (this.imgw){
|
||||||
|
this.value = this.imgw.base64();
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
getValue(){
|
getValue(){
|
||||||
var ret = {}
|
var ret = {}
|
||||||
if (this.imgw){
|
if (this.imgw){
|
||||||
ret[this.name] = this.imgw.base64()
|
// ret[this.name] = this.imgw.base64()
|
||||||
|
ret[this.name] = this.value;
|
||||||
} else {
|
} else {
|
||||||
ret[this.name] = null;
|
ret[this.name] = null;
|
||||||
}
|
}
|
||||||
@ -718,7 +907,7 @@ bricks.UiCode =class extends bricks.UiType {
|
|||||||
e.removeChild(e.firstChild);
|
e.removeChild(e.firstChild);
|
||||||
}
|
}
|
||||||
var v = this.opts.value || this.opts.defaultvalue || null;
|
var v = this.opts.value || this.opts.defaultvalue || null;
|
||||||
if (!v && ! this.opts.nullable){
|
if (!v && ! this.opts.nullable && data.length > 0){
|
||||||
v = data[0][this.opts.valueField]
|
v = data[0][this.opts.valueField]
|
||||||
}
|
}
|
||||||
if (this.opts.nullable){
|
if (this.opts.nullable){
|
||||||
@ -861,6 +1050,7 @@ bricks.UiVideo =class extends bricks.UiStr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var Input = new bricks._Input();
|
var Input = new bricks._Input();
|
||||||
|
Input.register('UiAudioRecorder', 'audiorecorder', bricks.UiAudioRecorder);
|
||||||
Input.register('UiStr', 'str', bricks.UiStr);
|
Input.register('UiStr', 'str', bricks.UiStr);
|
||||||
Input.register('UiHide', 'hide', bricks.UiHide);
|
Input.register('UiHide', 'hide', bricks.UiHide);
|
||||||
Input.register('UiTel', 'tel', bricks.UiTel);
|
Input.register('UiTel', 'tel', bricks.UiTel);
|
||||||
@ -878,3 +1068,4 @@ Input.register('UiPassword', 'password', bricks.UiPassword);
|
|||||||
Input.register('UiAudio', 'audio', bricks.UiAudio);
|
Input.register('UiAudio', 'audio', bricks.UiAudio);
|
||||||
Input.register('UiVideo', 'video', bricks.UiVideo);
|
Input.register('UiVideo', 'video', bricks.UiVideo);
|
||||||
Input.register('UiAudioText', 'audiotext', bricks.UiAudioText);
|
Input.register('UiAudioText', 'audiotext', bricks.UiAudioText);
|
||||||
|
Input.register('UiSearch', 'search', bricks.UiSearch);
|
||||||
|
131
bricks/jsoncall.js
Executable file → Normal file
@ -44,9 +44,9 @@ bricks.HttpText = class {
|
|||||||
};
|
};
|
||||||
bricks.extend(this.headers, headers);
|
bricks.extend(this.headers, headers);
|
||||||
var width=0, height=0;
|
var width=0, height=0;
|
||||||
var is_mobile = 0
|
var is_mobile = '0'
|
||||||
if (bricks.is_mobile()){
|
if (bricks.is_mobile()){
|
||||||
is_mobile = 1;
|
is_mobile = '1';
|
||||||
}
|
}
|
||||||
if (bricks.app) {
|
if (bricks.app) {
|
||||||
width = bricks.app.screenWidth();
|
width = bricks.app.screenWidth();
|
||||||
@ -77,8 +77,6 @@ bricks.HttpText = class {
|
|||||||
return await resp.text();
|
return await resp.text();
|
||||||
}
|
}
|
||||||
add_own_params(params){
|
add_own_params(params){
|
||||||
if (! params)
|
|
||||||
params = {};
|
|
||||||
var session = bricks.app.get_session();
|
var session = bricks.app.get_session();
|
||||||
if (params instanceof FormData){
|
if (params instanceof FormData){
|
||||||
for ( const [key, value] of Object.entries(this.params)){
|
for ( const [key, value] of Object.entries(this.params)){
|
||||||
@ -89,6 +87,8 @@ bricks.HttpText = class {
|
|||||||
}
|
}
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
if (! params)
|
||||||
|
params = {};
|
||||||
var p = bricks.extend({}, this.params);
|
var p = bricks.extend({}, this.params);
|
||||||
p = bricks.extend(p, params);
|
p = bricks.extend(p, params);
|
||||||
if (session){
|
if (session){
|
||||||
@ -102,46 +102,66 @@ bricks.HttpText = class {
|
|||||||
}
|
}
|
||||||
return Object.assign(this.headers, headers);
|
return Object.assign(this.headers, headers);
|
||||||
}
|
}
|
||||||
async httpcall(url, {method='GET', headers=null, params=null}={}){
|
async bricks_fetch(url, {method='GET', headers=null, params=null}={}){
|
||||||
url = this.url_parse(url);
|
url = this.url_parse(url);
|
||||||
var data = this.add_own_params(params);
|
var data = this.add_own_params(params);
|
||||||
var header = this.add_own_headers(headers);
|
var header = this.add_own_headers(headers);
|
||||||
var _params = {
|
var _params = {
|
||||||
method:method
|
method:method
|
||||||
}
|
}
|
||||||
// _params.headers = headers;
|
if (data instanceof FormData){
|
||||||
if (method == 'GET' || method == 'HEAD') {
|
method = 'POST';
|
||||||
let pstr = url_params(data);
|
_params.body = data;
|
||||||
url = url + '?' + pstr;
|
|
||||||
} else {
|
} else {
|
||||||
if (data instanceof FormData){
|
if (method == 'GET' || method == 'HEAD') {
|
||||||
_params.body = data;
|
let pstr = url_params(data);
|
||||||
|
url = url + '?' + pstr;
|
||||||
} else {
|
} else {
|
||||||
_params.body = JSON.stringify(data);
|
_params.body = JSON.stringify(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const fetchResult = await fetch(url, _params);
|
return await fetch(url, _params);
|
||||||
var result=null;
|
}
|
||||||
result = await this.get_result_data(fetchResult);
|
async httpcall(url, opts){
|
||||||
if (fetchResult.ok){
|
const fetchResult = await this.bricks_fetch(url, {
|
||||||
var ck = objget(fetchResult.headers, 'Set-Cookie');
|
method: opts.method,
|
||||||
if (ck){
|
headers: opts.headers,
|
||||||
var session = ck.split(';')[0];
|
params: opts.params});
|
||||||
bricks.app.save_session(session);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if (fetchResult.status == 401 && bricks.app.login_url){
|
if (fetchResult.status == 401 && bricks.app.login_url){
|
||||||
|
console.log('go to login')
|
||||||
return await this.withLoginInfo(url, _params);
|
return await this.withLoginInfo(url, _params);
|
||||||
}
|
}
|
||||||
const resp_error = {
|
if (fetchResult.status == 403){
|
||||||
"type":"Error",
|
var w = new bricks.Error({
|
||||||
"message":result.message || 'Something went wrong',
|
"title":"access error",
|
||||||
"data":result.data || '',
|
"auto_open":true,
|
||||||
"code":result.code || ''
|
"message":"you are forbidden to access it",
|
||||||
};
|
"archor":"cc",
|
||||||
error.info = resp_error;
|
"cheight":10,
|
||||||
return error;
|
"cwidth":16,
|
||||||
|
"timeout":5
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (! fetchResult.ok){
|
||||||
|
var w = new bricks.Error({
|
||||||
|
"title":"access error",
|
||||||
|
"auto_open":true,
|
||||||
|
"message":"server return error with error code" + fetchResult.status,
|
||||||
|
"archor":"cc",
|
||||||
|
"cheight":10,
|
||||||
|
"cwidth":16,
|
||||||
|
"timeout":5
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var result = await this.get_result_data(fetchResult);
|
||||||
|
var ck = objget(fetchResult.headers, 'Set-Cookie');
|
||||||
|
if (ck){
|
||||||
|
var session = ck.split(';')[0];
|
||||||
|
bricks.app.save_session(session);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
async withLoginInfo(url, params){
|
async withLoginInfo(url, params){
|
||||||
var get_login_info = function(e){
|
var get_login_info = function(e){
|
||||||
@ -149,50 +169,13 @@ bricks.HttpText = class {
|
|||||||
return e.target.getValue();
|
return e.target.getValue();
|
||||||
}
|
}
|
||||||
var w = await bricks.widgetBuild({
|
var w = await bricks.widgetBuild({
|
||||||
"id":"login_form",
|
|
||||||
"widgettype":"urlwidget",
|
"widgettype":"urlwidget",
|
||||||
"options":{
|
"options":{
|
||||||
"url":bricks.app.login_url
|
"url":bricks.app.login_url
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var login_info = await new Promise((resolve, reject, w) => {
|
return null;
|
||||||
w.bind('submit', (event) => {
|
|
||||||
resolve(event.target.getValue());
|
|
||||||
event.target.dismiss();
|
|
||||||
});
|
|
||||||
w.bind('discard', (event) => {
|
|
||||||
resolve(null);
|
|
||||||
event.target.dismiss()
|
|
||||||
});
|
|
||||||
});
|
|
||||||
if (login_info){
|
|
||||||
this.set_authorization_header(params, lgin_info);
|
|
||||||
const fetchResult = await fetch(url, params);
|
|
||||||
var result=null;
|
|
||||||
result = await this.get_result_data(fetchResult);
|
|
||||||
if (fetchResult.ok){
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if (fetchResult.status == 401){
|
|
||||||
return await this.withLoginInfo(url, params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const resp_error = {
|
|
||||||
"type":"Error",
|
|
||||||
"message":result.message || 'Something went wrong',
|
|
||||||
"data":result.data || '',
|
|
||||||
"code":result.code || ''
|
|
||||||
};
|
|
||||||
const error = new Error();
|
|
||||||
error.info = resp_error;
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
set_authorization_header(params, lgin_info){
|
|
||||||
var auth = 'password' + '::' + login_info.user + '::' + login_info.password;
|
|
||||||
var rsa = bricks.app.rsa;
|
|
||||||
var code = rsa.encrypt(auth);
|
|
||||||
self.header.authorization = btoa(code)
|
|
||||||
}
|
|
||||||
async get(url, {headers=null, params=null}={}){
|
async get(url, {headers=null, params=null}={}){
|
||||||
return await this.httpcall(url, {
|
return await this.httpcall(url, {
|
||||||
method:'GET',
|
method:'GET',
|
||||||
@ -209,6 +192,18 @@ bricks.HttpText = class {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bricks.HttpArrayBuffer = class extends bricks.HttpText {
|
||||||
|
async get_result_data(resp){
|
||||||
|
return await resp.arrayBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.HttpBin = class extends bricks.HttpText {
|
||||||
|
async get_result_data(resp){
|
||||||
|
return await resp.blob();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bricks.HttpResponse = class extends bricks.HttpText {
|
bricks.HttpResponse = class extends bricks.HttpText {
|
||||||
async get_result_data(resp){
|
async get_result_data(resp){
|
||||||
return resp;
|
return resp;
|
||||||
|
18
bricks/keypress.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
var bricks = window.bricks || {};
|
||||||
|
|
||||||
|
bricks.KeyPress = class extends bricks.VBox {
|
||||||
|
constructor(opts){
|
||||||
|
super(opts);
|
||||||
|
bricks.app.bind('keydown', this.key_handler.bind(this));
|
||||||
|
}
|
||||||
|
key_handler(event){
|
||||||
|
var key = event.key;
|
||||||
|
if (!key) return;
|
||||||
|
this.clear_widgets();
|
||||||
|
var w = new bricks.Text({text:'key press is:' + key});
|
||||||
|
this.add_widget(w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.Factory.register('KeyPress', bricks.KeyPress);
|
||||||
|
|
67
bricks/layout.js
Executable file → Normal file
@ -4,17 +4,37 @@ bricks.key_selectable_stack = [];
|
|||||||
|
|
||||||
bricks.Layout = class extends bricks.JsWidget {
|
bricks.Layout = class extends bricks.JsWidget {
|
||||||
constructor(options){
|
constructor(options){
|
||||||
|
if (! options){
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
super(options);
|
super(options);
|
||||||
this._container = true;
|
this._container = true;
|
||||||
|
this.keyselectable = options.keyselectable || false;
|
||||||
this.children = [];
|
this.children = [];
|
||||||
|
if (this.use_key_select){
|
||||||
|
this.enable_key_select();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
build_title(){
|
||||||
|
if (this.title){
|
||||||
|
this.title_w = new bricks.Title3({otext:this.title, i18n:true, dynsize:true});
|
||||||
|
this.add_widget(this.title_w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
build_description(){
|
||||||
|
if (this.description){
|
||||||
|
this.description_w = new bricks.Text({otext:this.description,
|
||||||
|
i18n:true, dynsize:true
|
||||||
|
});
|
||||||
|
this.add_widget(this.description_w);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
set_key_select_items(){
|
set_key_select_items(){
|
||||||
this.key_select_items = this.children;
|
this.key_select_items = this.children;
|
||||||
}
|
}
|
||||||
enable_key_select(){
|
enable_key_select(){
|
||||||
if (!this.keyselectable) return;
|
this.keyselectable = true;
|
||||||
this.set_key_select_items();
|
this.set_key_select_items();
|
||||||
this.selected_children = null;
|
|
||||||
bricks.app.bind('keydown', this.key_handler.bind(this));
|
bricks.app.bind('keydown', this.key_handler.bind(this));
|
||||||
bricks.key_selectable_stack.push(this)
|
bricks.key_selectable_stack.push(this)
|
||||||
this.select_default_item();
|
this.select_default_item();
|
||||||
@ -25,9 +45,9 @@ bricks.Layout = class extends bricks.JsWidget {
|
|||||||
return bricks.key_selectable_stack[p] == this;
|
return bricks.key_selectable_stack[p] == this;
|
||||||
}
|
}
|
||||||
disable_key_select(){
|
disable_key_select(){
|
||||||
if (!this.keyselectable) return;
|
this.keyselectable = false;
|
||||||
|
bricks.app.unbind('keydown', this.key_handler.bind(this));
|
||||||
if (this.is_currkeyselectable()){
|
if (this.is_currkeyselectable()){
|
||||||
bricks.app.unbind('keydown', this.key_handler.bind(this));
|
|
||||||
this.select_item.selected(false);
|
this.select_item.selected(false);
|
||||||
this.select_item = null;
|
this.select_item = null;
|
||||||
bricks.key_selectable_stack.pop();
|
bricks.key_selectable_stack.pop();
|
||||||
@ -35,7 +55,8 @@ bricks.Layout = class extends bricks.JsWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
select_item(w){
|
select_item(w){
|
||||||
if (!this.keyselectable) return;
|
if (!w) return;
|
||||||
|
// if (!this.keyselectable) return;
|
||||||
if (this.selected_item){
|
if (this.selected_item){
|
||||||
this.selected_item.selected(false);
|
this.selected_item.selected(false);
|
||||||
}
|
}
|
||||||
@ -86,25 +107,31 @@ bricks.Layout = class extends bricks.JsWidget {
|
|||||||
}
|
}
|
||||||
down_level(){
|
down_level(){
|
||||||
this.set_key_select_items();
|
this.set_key_select_items();
|
||||||
for (var i=0;i<this.key_select_items.length;i++){
|
var w = this.selected_item;
|
||||||
var w = this.key_select_items[i];
|
if (! w) return;
|
||||||
if(w.keyselectable){
|
if (! w.keyselectable){
|
||||||
w.enable_key_select();
|
w = w.find_first_keyselectable_child();
|
||||||
return true;
|
if (! w) return;
|
||||||
}
|
|
||||||
try {
|
|
||||||
if (w.down_level()){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} catch (e){
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
bricks.key_selectable_stack.push(this);
|
||||||
|
this.disable_key_select();
|
||||||
|
w.enable_key_select();
|
||||||
|
}
|
||||||
|
find_first_keyselectable_child(){
|
||||||
|
for (var i=0;i<this.children;i++){
|
||||||
|
if (this.children[i].keyselectable){
|
||||||
|
return this.children[i];
|
||||||
|
}
|
||||||
|
var sw = this.children[i].find_first_keyselectable_child();
|
||||||
|
if (sw) return sw;
|
||||||
|
}
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
enter_handler(){
|
enter_handler(){
|
||||||
|
if (! this.selected_item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.selected_item.dispatch('click');
|
this.selected_item.dispatch('click');
|
||||||
this.down_level();
|
|
||||||
}
|
}
|
||||||
key_handler(event){
|
key_handler(event){
|
||||||
if (!this.is_currkeyselectable()){
|
if (!this.is_currkeyselectable()){
|
||||||
|
283
bricks/llm.js
@ -41,7 +41,7 @@ bricks.LlmMsgAudio = class extends bricks.UpStreaming {
|
|||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bricks.ModelOutput = class extends bricks.HBox {
|
bricks.ModelOutput = class extends bricks.VBox {
|
||||||
/* {
|
/* {
|
||||||
icon:
|
icon:
|
||||||
output_view:
|
output_view:
|
||||||
@ -53,16 +53,29 @@ bricks.ModelOutput = class extends bricks.HBox {
|
|||||||
opts = {};
|
opts = {};
|
||||||
}
|
}
|
||||||
opts.width = '100%';
|
opts.width = '100%';
|
||||||
|
opts.height = 'auto';
|
||||||
super(opts);
|
super(opts);
|
||||||
|
var hb = new bricks.HBox({width:'100%', cheight:2});
|
||||||
|
this.img = new bricks.Icon({
|
||||||
|
rate:2,
|
||||||
|
tip:this.opts.model,
|
||||||
|
url:this.icon||bricks_resource('imgs/llm.png')
|
||||||
|
});
|
||||||
|
hb.add_widget(this.img);
|
||||||
|
var mname = new bricks.Text({text:this.opts.model});
|
||||||
|
hb.add_widget(mname);
|
||||||
|
this.add_widget(hb);
|
||||||
|
|
||||||
|
this.content = new bricks.HBox({width:'100%'});
|
||||||
|
this.add_widget(this.content);
|
||||||
this.logid = null;
|
this.logid = null;
|
||||||
this.img = new bricks.Icon({rate:2,url:this.icon||bricks_resource('imgs/llm.png')});
|
|
||||||
this.run = new bricks.BaseRunning({target:this});
|
this.run = new bricks.BaseRunning({target:this});
|
||||||
this.add_widget(this.img);
|
this.content.add_widget(this.run);
|
||||||
this.add_widget(this.run);
|
|
||||||
this.filler = new bricks.VBox({});
|
this.filler = new bricks.VBox({});
|
||||||
this.filler.set_css('filler');
|
this.filler.set_css('filler');
|
||||||
this.add_widget(this.filler);
|
this.content.add_widget(new bricks.BlankIcon({rate:2, flexShrink:0}));
|
||||||
this.add_widget(new bricks.BlankIcon({rate:2, flexShrink:0}));
|
this.content.add_widget(this.filler);
|
||||||
|
this.content.add_widget(new bricks.BlankIcon({rate:2, flexShrink:0}));
|
||||||
this.build_estimate_widgets();
|
this.build_estimate_widgets();
|
||||||
}
|
}
|
||||||
build_estimate_widgets(){
|
build_estimate_widgets(){
|
||||||
@ -104,7 +117,7 @@ bricks.ModelOutput = class extends bricks.HBox {
|
|||||||
async update_data(data){
|
async update_data(data){
|
||||||
if (this.run) {
|
if (this.run) {
|
||||||
this.run.stop_timepass();
|
this.run.stop_timepass();
|
||||||
this.remove_widget(this.run);
|
this.content.remove_widget(this.run);
|
||||||
if(this.textvoice){
|
if(this.textvoice){
|
||||||
this.upstreaming = new bricks.UpStreaming({
|
this.upstreaming = new bricks.UpStreaming({
|
||||||
url:this.tts_url
|
url:this.tts_url
|
||||||
@ -116,9 +129,18 @@ bricks.ModelOutput = class extends bricks.HBox {
|
|||||||
this.upstreaming.send(data.content);
|
this.upstreaming.send(data.content);
|
||||||
}
|
}
|
||||||
this.run = null;
|
this.run = null;
|
||||||
var w = await bricks.widgetBuild(this.output_view, this.llmio, data);
|
|
||||||
w.set_css('llm_msg');
|
|
||||||
this.filler.clear_widgets();
|
this.filler.clear_widgets();
|
||||||
|
if (typeof this.output_view === 'string'){
|
||||||
|
this.output_view = JSON.parse(this.output_view);
|
||||||
|
}
|
||||||
|
var desc = bricks.apply_data(this.output_view, data);
|
||||||
|
var w = await bricks.widgetBuild(desc, this.llmio);
|
||||||
|
if (! w){
|
||||||
|
console.log('widgetBuild() return null, desc=', this.output_view, desc, 'data=', data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
w.set_css('llm_msg');
|
||||||
|
w.set_style('width', '100%');
|
||||||
this.filler.add_widget(w);
|
this.filler.add_widget(w);
|
||||||
this.filler.add_widget(this.estimate_w);
|
this.filler.add_widget(this.estimate_w);
|
||||||
if (data.logid){
|
if (data.logid){
|
||||||
@ -157,57 +179,74 @@ bricks.LlmModel = class extends bricks.JsWidget {
|
|||||||
constructor(llmio, opts){
|
constructor(llmio, opts){
|
||||||
super(opts);
|
super(opts);
|
||||||
this.llmio = llmio;
|
this.llmio = llmio;
|
||||||
if (opts.use_session){
|
this.messages = [];
|
||||||
this.messages = [];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
render_title(){
|
render_title(){
|
||||||
var w = new bricks.HBox({});
|
var w = new bricks.HBox({padding:'15px'});
|
||||||
w.bind('click', this.show_setup_panel.bind(this))
|
w.bind('click', this.show_setup_panel.bind(this))
|
||||||
var img = new bricks.Icon({rate:2,url:this.opts.icon||bricks_resource('imgs/llm.png')});
|
var img = new bricks.Icon({
|
||||||
var txt = new bricks.Text({text:this.opts.model});
|
rate:2,
|
||||||
|
tip:this.opts.model,
|
||||||
|
url:this.opts.icon||bricks_resource('imgs/llm.png')
|
||||||
|
});
|
||||||
|
// var txt = new bricks.Text({text:this.opts.model});
|
||||||
w.add_widget(img);
|
w.add_widget(img);
|
||||||
w.add_widget(txt);
|
// w.add_widget(txt);
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
show_setup_panel(event){
|
show_setup_panel(event){
|
||||||
|
|
||||||
}
|
}
|
||||||
async model_inputed(data){
|
inputdata2uploaddata(data){
|
||||||
var mout = new bricks.ModelOutput({
|
var d;
|
||||||
textvoice:this.textvoice,
|
if (data instanceof FormData){
|
||||||
tts_url:this.tts_url,
|
d = bricks.formdata_copy(data);
|
||||||
icon:this.opts.icon,
|
|
||||||
estimate_url:this.llmio.estimate_url,
|
|
||||||
output_view:this.opts.output_view});
|
|
||||||
this.llmio.o_w.add_widget(mout);
|
|
||||||
var fmt = this.opts.user_message_format || { role:'user', content:'${prompt}'};
|
|
||||||
var umsg = bricks.apply_data(fmt, data);
|
|
||||||
var d = data;
|
|
||||||
if (this.messages){
|
|
||||||
this.messages.push(umsg);
|
|
||||||
d = bricks.extend({}, data);
|
|
||||||
d.messages = this.messages;
|
|
||||||
d.model = this.opts.model;
|
|
||||||
d.modelinstanceid = this.opts.modelinstanceid;
|
|
||||||
d.modeltypeid = this.opts.modeltypeid;
|
|
||||||
} else {
|
} else {
|
||||||
d = bricks.extend({}, data);
|
d = objcopy(data);
|
||||||
|
}
|
||||||
|
var fmt = this.opts.user_message_format;
|
||||||
|
if (fmt){
|
||||||
|
var umsg = bricks.apply_data(fmt, inputdata2dic(data));
|
||||||
|
this.messages.push(umsg);
|
||||||
|
}
|
||||||
|
if (data instanceof FormData){
|
||||||
|
d.append('model', this.opts.model)
|
||||||
|
d.append('modelinstanceid', this.opts.modelinstanceid)
|
||||||
|
d.append('modeltypeid', this.opts.modeltypeid)
|
||||||
|
d.append('messages', JSON.stringify(this.messages));
|
||||||
|
} else {
|
||||||
|
d.messages = JSON.stringify(this.messages);
|
||||||
d.model = this.opts.model;
|
d.model = this.opts.model;
|
||||||
d.mapi = this.mapi;
|
|
||||||
d.modelinstanceid = this.opts.modelinstanceid;
|
d.modelinstanceid = this.opts.modelinstanceid;
|
||||||
d.modeltypeid = this.opts.modeltypeid;
|
d.modeltypeid = this.opts.modeltypeid;
|
||||||
}
|
}
|
||||||
console.log('upload data=', d, this.options);
|
return d;
|
||||||
|
}
|
||||||
|
async model_inputed(data){
|
||||||
|
if (!opts.use_session){
|
||||||
|
this.messages = [];
|
||||||
|
}
|
||||||
|
var mout = new bricks.ModelOutput({
|
||||||
|
textvoice:this.textvoice,
|
||||||
|
tts_url:this.tts_url,
|
||||||
|
icon:this.opts.icon,
|
||||||
|
model:this.opts.model,
|
||||||
|
estimate_url:this.llmio.estimate_url,
|
||||||
|
output_view:this.opts.output_view});
|
||||||
|
this.llmio.o_w.add_widget(mout);
|
||||||
if (this.response_mode == 'stream' || this.response_mode == 'async') {
|
if (this.response_mode == 'stream' || this.response_mode == 'async') {
|
||||||
|
var d = this.inputdata2uploaddata(data);
|
||||||
|
console.log('data_inouted=', data, 'upload_data=', d);
|
||||||
var hr = new bricks.HttpResponseStream();
|
var hr = new bricks.HttpResponseStream();
|
||||||
var resp = await hr.post(this.opts.url, {params:d});
|
var resp = await hr.post(this.opts.url, {params:d});
|
||||||
await hr.handle_chunk(resp, this.chunk_response.bind(this, mout));
|
await hr.handle_chunk(resp, this.chunk_response.bind(this, mout));
|
||||||
this.chunk_ended();
|
this.chunk_ended();
|
||||||
} else {
|
} else {
|
||||||
|
var d = this.inputdata2uploaddata(data);
|
||||||
var hj = new bricks.HttpJson()
|
var hj = new bricks.HttpJson()
|
||||||
var resp = await hj.post(this.opts.url, {params:d});
|
var resp = await hj.post(this.opts.url, {params:d});
|
||||||
if (this.response_mode == 'sync'){
|
if (this.response_mode == 'sync'){
|
||||||
|
resp.content = bricks.escapeSpecialChars(resp.content)
|
||||||
mout.update_data(resp);
|
mout.update_data(resp);
|
||||||
if (this.messages){
|
if (this.messages){
|
||||||
var msg = this.llm_msg_format();
|
var msg = this.llm_msg_format();
|
||||||
@ -236,7 +275,7 @@ bricks.LlmModel = class extends bricks.JsWidget {
|
|||||||
d.content = bricks.escapeSpecialChars(d.content);
|
d.content = bricks.escapeSpecialChars(d.content);
|
||||||
this.resp_data = d;
|
this.resp_data = d;
|
||||||
mout.update_data(d);
|
mout.update_data(d);
|
||||||
console.log('stream data=', d);
|
// console.log('stream data=', d);
|
||||||
}
|
}
|
||||||
chunk_ended(){
|
chunk_ended(){
|
||||||
if (! this.messages) {
|
if (! this.messages) {
|
||||||
@ -255,6 +294,7 @@ bricks.LlmIO = class extends bricks.VBox {
|
|||||||
options:
|
options:
|
||||||
{
|
{
|
||||||
user_icon:
|
user_icon:
|
||||||
|
list_models_url:
|
||||||
input_fields:
|
input_fields:
|
||||||
input_view:
|
input_view:
|
||||||
output_view:
|
output_view:
|
||||||
@ -278,31 +318,158 @@ bricks.LlmIO = class extends bricks.VBox {
|
|||||||
constructor(opts){
|
constructor(opts){
|
||||||
super(opts);
|
super(opts);
|
||||||
this.llmmodels = [];
|
this.llmmodels = [];
|
||||||
this.title_w = new bricks.HBox({cheight:2});
|
this.title_w = new bricks.HBox({cheight:3});
|
||||||
this.i_w = new bricks.VBox({cheight:5});
|
var bottom_box = new bricks.HBox({cheight:3});
|
||||||
|
this.i_w = new bricks.Icon({
|
||||||
|
rate:2,
|
||||||
|
url:bricks_resource('imgs/input.png'),
|
||||||
|
margin:'14px',
|
||||||
|
tip:'input data',
|
||||||
|
css:'clickable'
|
||||||
|
});
|
||||||
|
this.nm_w = new bricks.Icon({
|
||||||
|
rate:2,
|
||||||
|
url:bricks_resource('imgs/add.png'),
|
||||||
|
margin:'14px',
|
||||||
|
tip:'add new model',
|
||||||
|
css:'clickable'
|
||||||
|
});
|
||||||
|
bottom_box.add_widget(this.i_w);
|
||||||
|
bottom_box.add_widget(this.nm_w);
|
||||||
|
|
||||||
|
this.nm_w.bind('click', this.open_search_models.bind(this));
|
||||||
|
this.i_w.bind('click', this.open_input_widget.bind(this));
|
||||||
this.o_w = new bricks.Filler({overflow:'auto'});
|
this.o_w = new bricks.Filler({overflow:'auto'});
|
||||||
this.add_widget(this.title_w);
|
this.add_widget(this.title_w);
|
||||||
this.add_widget(this.o_w);
|
this.add_widget(this.o_w);
|
||||||
if (this.models.length < 2 && this.tts_url){
|
if (this.models.length < 2 && this.tts_url){
|
||||||
this.textvoice = true;
|
this.textvoice = true;
|
||||||
}
|
}
|
||||||
this.add_widget(this.i_w);
|
this.add_widget(bottom_box);
|
||||||
this.models.forEach( m =>{
|
this.models.forEach( m =>{
|
||||||
if (this.textvoice){
|
this.show_added_model(m);
|
||||||
m.textvoice = true;
|
|
||||||
m.tts_url = this.tts_url;
|
|
||||||
}
|
|
||||||
var lm = new bricks.LlmModel(this, m);
|
|
||||||
this.llmmodels.push(lm);
|
|
||||||
var tw = lm.render_title();
|
|
||||||
this.title_w.add_widget(tw);
|
|
||||||
});
|
});
|
||||||
this.build_input();
|
}
|
||||||
|
show_added_model(m){
|
||||||
|
if (this.textvoice){
|
||||||
|
m.textvoice = true;
|
||||||
|
m.tts_url = this.tts_url;
|
||||||
|
}
|
||||||
|
var lm = new bricks.LlmModel(this, m);
|
||||||
|
this.llmmodels.push(lm);
|
||||||
|
var tw = lm.render_title();
|
||||||
|
this.title_w.add_widget(tw);
|
||||||
|
}
|
||||||
|
async open_search_models(event){
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
var rect = this.showRectage();
|
||||||
|
var opts = {
|
||||||
|
title:"select model",
|
||||||
|
icon:bricks_resource('imgs/search.png'),
|
||||||
|
auto_destroy:true,
|
||||||
|
auto_open:true,
|
||||||
|
auto_dismiss:false,
|
||||||
|
movable:true,
|
||||||
|
top:rect.top + 'px',
|
||||||
|
left:rect.left + 'px',
|
||||||
|
width: rect.right - rect.left + 'px',
|
||||||
|
height: rect.bottom - rect.top + 'px'
|
||||||
|
}
|
||||||
|
var w = new bricks.PopupWindow(opts);
|
||||||
|
var sopts = {
|
||||||
|
data_url:this.list_models_url,
|
||||||
|
data_params:{
|
||||||
|
mii:this.models[0].modelinstanceid,
|
||||||
|
mti:this.models[0].modeltypeid
|
||||||
|
},
|
||||||
|
data_method:'POST',
|
||||||
|
col_cwidth: 24,
|
||||||
|
record_view:{
|
||||||
|
widgettype:"VBox",
|
||||||
|
options:{
|
||||||
|
cheight:20,
|
||||||
|
css:"card"
|
||||||
|
},
|
||||||
|
subwidgets:[
|
||||||
|
{
|
||||||
|
widgettype:"Title4",
|
||||||
|
options:{
|
||||||
|
text:"${name}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
widgettype:"Filler",
|
||||||
|
options:{
|
||||||
|
css:"scroll"
|
||||||
|
},
|
||||||
|
subwidgets:[
|
||||||
|
{
|
||||||
|
widgettype:"VBox",
|
||||||
|
options:{
|
||||||
|
css:"subcard"
|
||||||
|
},
|
||||||
|
subwidgets:[
|
||||||
|
{
|
||||||
|
widgettype:"Text",
|
||||||
|
options:{
|
||||||
|
text:"模型描述:${description}",
|
||||||
|
wrap:true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
widgettype:"Text",
|
||||||
|
options:{
|
||||||
|
text:"启用日期:${enable_date}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var cols = new bricks.Cols(sopts);
|
||||||
|
cols.bind('record_click', this.add_new_model.bind(this));
|
||||||
|
cols.bind('record_click', w.dismiss.bind(w));
|
||||||
|
w.add_widget(cols);
|
||||||
|
w.open();
|
||||||
|
}
|
||||||
|
async add_new_model(event){
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
this.models.push(event.params);
|
||||||
|
this.show_added_model(event.params);
|
||||||
|
}
|
||||||
|
async open_input_widget(event){
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
var rect = this.showRectage();
|
||||||
|
var opts = {
|
||||||
|
title:"input data",
|
||||||
|
icon:bricks_resource('imgs/input.png'),
|
||||||
|
auto_destroy:true,
|
||||||
|
auto_open:true,
|
||||||
|
auto_dismiss:false,
|
||||||
|
movable:true,
|
||||||
|
top:rect.top + 'px',
|
||||||
|
left:rect.left + 'px',
|
||||||
|
width: rect.right - rect.left + 'px',
|
||||||
|
height: rect.bottom - rect.top + 'px'
|
||||||
|
}
|
||||||
|
var w = new bricks.PopupWindow(opts);
|
||||||
|
var fopts = {
|
||||||
|
fields:this.input_fields
|
||||||
|
}
|
||||||
|
var fw = new bricks.Form(fopts);
|
||||||
|
fw.bind('submit', this.handle_input.bind(this));
|
||||||
|
fw.bind('submit', w.destroy.bind(w));
|
||||||
|
w.add_widget(fw);
|
||||||
|
w.open();
|
||||||
}
|
}
|
||||||
async handle_input(event){
|
async handle_input(event){
|
||||||
var params = event.params;
|
var params = event.params;
|
||||||
if (params.prompt)
|
|
||||||
params.prompt = bricks.escapeSpecialChars(params.prompt);
|
|
||||||
await this.show_input(params);
|
await this.show_input(params);
|
||||||
for(var i=0;i<this.llmmodels.length;i++){
|
for(var i=0;i<this.llmmodels.length;i++){
|
||||||
var lm = this.llmmodels[i];
|
var lm = this.llmmodels[i];
|
||||||
@ -314,7 +481,9 @@ bricks.LlmIO = class extends bricks.VBox {
|
|||||||
}
|
}
|
||||||
async show_input(params){
|
async show_input(params){
|
||||||
var box = new bricks.HBox({width:'100%'});
|
var box = new bricks.HBox({width:'100%'});
|
||||||
var w = await bricks.widgetBuild(this.input_view, this.o_w, params);
|
var data = inputdata2dic(params);
|
||||||
|
console.log('data=', data, 'input_view=', this.input_view);
|
||||||
|
var w = await bricks.widgetBuild(this.input_view, this.o_w, data);
|
||||||
w.set_css(this.msg_css||'user_msg');
|
w.set_css(this.msg_css||'user_msg');
|
||||||
w.set_css('filler');
|
w.set_css('filler');
|
||||||
var img = new bricks.Icon({rate:2,url:this.user_icon||bricks_resource('imgs/user.png')});
|
var img = new bricks.Icon({rate:2,url:this.user_icon||bricks_resource('imgs/user.png')});
|
||||||
@ -323,14 +492,6 @@ bricks.LlmIO = class extends bricks.VBox {
|
|||||||
box.add_widget(img);
|
box.add_widget(img);
|
||||||
this.o_w.add_widget(box);
|
this.o_w.add_widget(box);
|
||||||
}
|
}
|
||||||
build_input(){
|
|
||||||
var fopts = {
|
|
||||||
fields:this.input_fields
|
|
||||||
};
|
|
||||||
var fw = new bricks.InlineForm(fopts);
|
|
||||||
fw.bind('submit', this.handle_input.bind(this));
|
|
||||||
this.i_w.add_widget(fw);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bricks.Factory.register('LlmIO', bricks.LlmIO);
|
bricks.Factory.register('LlmIO', bricks.LlmIO);
|
||||||
|
@ -96,13 +96,12 @@ bricks.LlmMsgBox = class extends bricks.HBox {
|
|||||||
var d = {
|
var d = {
|
||||||
messages:this.messages,
|
messages:this.messages,
|
||||||
mapi:this.mapi,
|
mapi:this.mapi,
|
||||||
prompt:prompt,
|
|
||||||
model:this.model,
|
model:this.model,
|
||||||
}
|
}
|
||||||
// console.log('messages=', this.messages, 'msg=', msg, 'umsg=', umsg);
|
// console.log('messages=', this.messages, 'msg=', msg, 'umsg=', umsg);
|
||||||
if (this.response_mode == 'stream') {
|
if (this.response_mode == 'stream') {
|
||||||
var hr = new bricks.HttpResponseStream();
|
var hr = new bricks.HttpResponseStream();
|
||||||
var resp = await hr.post(this.url, {params:d});
|
var resp = await hr.post(this.url, {data:d});
|
||||||
this.responsed();
|
this.responsed();
|
||||||
await hr.handle_chunk(resp, this.chunk_response.bind(this));
|
await hr.handle_chunk(resp, this.chunk_response.bind(this));
|
||||||
this.chunk_ended();
|
this.chunk_ended();
|
||||||
|
0
bricks/markdown_viewer.js
Executable file → Normal file
28
bricks/menu.js
Executable file → Normal file
@ -11,6 +11,8 @@ bricks.Menu = class extends bricks.VBox {
|
|||||||
super(options);
|
super(options);
|
||||||
this.dom_element.style.display = "";
|
this.dom_element.style.display = "";
|
||||||
this.dom_element.style.backgroundColor = options.bgcolor || "white";
|
this.dom_element.style.backgroundColor = options.bgcolor || "white";
|
||||||
|
this.build_title();
|
||||||
|
this.build_description();
|
||||||
this.create_children(this, this.opts.items);
|
this.create_children(this, this.opts.items);
|
||||||
this.bind('item_click', this.menu_clicked.bind(this));
|
this.bind('item_click', this.menu_clicked.bind(this));
|
||||||
}
|
}
|
||||||
@ -24,12 +26,19 @@ bricks.Menu = class extends bricks.VBox {
|
|||||||
console.log(event);
|
console.log(event);
|
||||||
let e = event.target;
|
let e = event.target;
|
||||||
let opts = event.params;
|
let opts = event.params;
|
||||||
if (! opts.url){
|
var t;
|
||||||
console.log('itme.url is null');
|
var popts;
|
||||||
this.dispatch('command', opts);
|
if (this.target == 'PopupWindow'){
|
||||||
return;
|
popts = bricks.get_popupwindow_default_options();
|
||||||
|
bricks.extend(popts, this.popup_options || {});
|
||||||
|
t = new bricks.PopupWindow(popts);
|
||||||
|
} else if (this.target == 'Popup'){
|
||||||
|
popts = bricks.get_popup_default_options();
|
||||||
|
bricks.extend(popts, this.popup_options || {});
|
||||||
|
t = new bricks.Popup(popts);
|
||||||
|
} else {
|
||||||
|
t = bricks.getWidgetById(this.target);
|
||||||
}
|
}
|
||||||
var t = bricks.getWidgetById(this.target);
|
|
||||||
if (t){
|
if (t){
|
||||||
var desc = {
|
var desc = {
|
||||||
"widgettype":"urlwidget",
|
"widgettype":"urlwidget",
|
||||||
@ -38,7 +47,7 @@ bricks.Menu = class extends bricks.VBox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var w = await bricks.widgetBuild(desc, this);
|
var w = await bricks.widgetBuild(desc, this);
|
||||||
if (w){
|
if (w && ! w.parent){
|
||||||
t.clear_widgets();
|
t.clear_widgets();
|
||||||
t.add_widget(w);
|
t.add_widget(w);
|
||||||
} else {
|
} else {
|
||||||
@ -47,6 +56,7 @@ bricks.Menu = class extends bricks.VBox {
|
|||||||
} else {
|
} else {
|
||||||
console.log('menu_clicked():', this.target, 'not found')
|
console.log('menu_clicked():', this.target, 'not found')
|
||||||
}
|
}
|
||||||
|
this.dispatch('command', opts);
|
||||||
}
|
}
|
||||||
create_children(w, items){
|
create_children(w, items){
|
||||||
for (let i=0;i<items.length;i++){
|
for (let i=0;i<items.length;i++){
|
||||||
@ -59,13 +69,17 @@ bricks.Menu = class extends bricks.VBox {
|
|||||||
itw.add_widget(subw);
|
itw.add_widget(subw);
|
||||||
itw.add_widget(w1);
|
itw.add_widget(w1);
|
||||||
this.create_children(w1, item.items);
|
this.create_children(w1, item.items);
|
||||||
subw.bind('click', w1.toggle_hide.bind(w1));
|
subw.bind('click', this.items_toggle_hide.bind(this, w1));
|
||||||
} else {
|
} else {
|
||||||
subw.bind('click', this.regen_menuitem_event.bind(this, item))
|
subw.bind('click', this.regen_menuitem_event.bind(this, item))
|
||||||
w.add_widget(subw);
|
w.add_widget(subw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
items_toggle_hide(w, event){
|
||||||
|
w.toggle_hide();
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
create_menuitem(item){
|
create_menuitem(item){
|
||||||
var w = new bricks.HBox({cheight:this.item_cheight||2});
|
var w = new bricks.HBox({cheight:this.item_cheight||2});
|
||||||
var iw, tw;
|
var iw, tw;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
var bricks = window.bricks || {};
|
var bricks = window.bricks || {};
|
||||||
|
|
||||||
bricks.Message = class extends bricks.Modal {
|
bricks.Message = class extends bricks.PopupWindow {
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
title:
|
title:
|
||||||
@ -11,55 +11,41 @@ bricks.Message = class extends bricks.Modal {
|
|||||||
opts.auto_open = true;
|
opts.auto_open = true;
|
||||||
super(opts);
|
super(opts);
|
||||||
this.create_message_widget();
|
this.create_message_widget();
|
||||||
this.panel.set_css('message');
|
this.set_css('message');
|
||||||
}
|
}
|
||||||
create_message_widget(){
|
create_message_widget(){
|
||||||
this.message_w = new bricks.VBox({width:'100%',height:'100%'});
|
|
||||||
var w = new bricks.Filler();
|
var w = new bricks.Filler();
|
||||||
this.message_w.add_widget(w);
|
this.add_widget(w);
|
||||||
|
var w1 = new bricks.VScrollPanel({});
|
||||||
|
w.add_widget(w1);
|
||||||
var t = new bricks.Text({otext:this.opts.message,
|
var t = new bricks.Text({otext:this.opts.message,
|
||||||
wrap:true,
|
wrap:true,
|
||||||
halign:'middle',
|
halign:'middle',
|
||||||
i18n:true});
|
i18n:true});
|
||||||
w.add_widget(t);
|
w1.add_widget(t);
|
||||||
this.add_widget(this.message_w);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bricks.Error = class extends bricks.Message {
|
bricks.Error = class extends bricks.Message {
|
||||||
constructor(opts){
|
constructor(opts){
|
||||||
super(opts);
|
super(opts);
|
||||||
this.panel.set_css('error');
|
this.set_css('error');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bricks.show_error = function(opts){
|
bricks.show_error = function(opts){
|
||||||
|
opts.cheight = opts.cheight || 9;
|
||||||
|
opts.cwidth = opts.cwidth || 16;
|
||||||
var w = new bricks.Error(opts);
|
var w = new bricks.Error(opts);
|
||||||
w.open();
|
w.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
bricks.show_message = function(opts){
|
bricks.show_message = function(opts){
|
||||||
|
opts.cheight = opts.cheight || 9;
|
||||||
|
opts.cwidth = opts.cwidth || 16;
|
||||||
var w = new bricks.Message(opts);
|
var w = new bricks.Message(opts);
|
||||||
w.open();
|
w.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
bricks.PopupForm = class extends bricks.VBox {
|
|
||||||
/*
|
|
||||||
{
|
|
||||||
form:{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
constructor(options){
|
|
||||||
super(options);
|
|
||||||
this.form = new bricks.Form(this.opts.form);
|
|
||||||
this.add_widget(this.form);
|
|
||||||
this.form.bind('submit', this.close_popup.bind(this));
|
|
||||||
this.form.bind('discard', this.close_popup.bind(this));
|
|
||||||
}
|
|
||||||
close_popup(e){
|
|
||||||
this.dismiss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bricks.Factory.register('Message', bricks.Message);
|
bricks.Factory.register('Message', bricks.Message);
|
||||||
bricks.Factory.register('Error', bricks.Error);
|
bricks.Factory.register('Error', bricks.Error);
|
||||||
|
0
bricks/minify_tools.txt
Executable file → Normal file
5
bricks/modal.js
Executable file → Normal file
@ -167,7 +167,7 @@ bricks.Modal = class extends bricks.BaseModal {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
bricks.ModalForm = class extends bricks.Modal {
|
bricks.ModalForm = class extends bricks.PopupWindow {
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
auto_open:
|
auto_open:
|
||||||
@ -189,6 +189,9 @@ bricks.ModalForm = class extends bricks.Modal {
|
|||||||
super(opts);
|
super(opts);
|
||||||
this.build_form();
|
this.build_form();
|
||||||
}
|
}
|
||||||
|
_getValue(){
|
||||||
|
return this.form._getValue();
|
||||||
|
}
|
||||||
getValue(){
|
getValue(){
|
||||||
return this.form.getValue();
|
return this.form.getValue();
|
||||||
}
|
}
|
||||||
|
0
bricks/myoperator.js
Executable file → Normal file
99
bricks/period.js
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
var bricks = window.bricks || {};
|
||||||
|
bricks.str2date = function(sdate){
|
||||||
|
let [year, month, day] = sdate.split("-");
|
||||||
|
var dateObj = new Date(year, month - 1, day);
|
||||||
|
return dateObj;
|
||||||
|
}
|
||||||
|
bricks.date2str = function(date){
|
||||||
|
let year = date.getFullYear();
|
||||||
|
let month = String(date.getMonth() + 1).padStart(2, '0');
|
||||||
|
let day = String(date.getDate()).padStart(2, '0');
|
||||||
|
let formattedDate = `${year}-${month}-${day}`;
|
||||||
|
return formattedDate;
|
||||||
|
}
|
||||||
|
bricks.addMonths = function(dateObj, months){
|
||||||
|
var newDate = new Date(dateObj);
|
||||||
|
newDate.setMonth(newDate.getMonth() + months);
|
||||||
|
return newDate;
|
||||||
|
}
|
||||||
|
bricks.addYears = function(dateObj, years){
|
||||||
|
const newDate = new Date(dateObj);
|
||||||
|
newDate.setYear(newDate.getYear() + years);
|
||||||
|
return newDate;
|
||||||
|
}
|
||||||
|
bricks.addDays = function(dateObj, days){
|
||||||
|
var newdate = new Date(dateObj);
|
||||||
|
newdate.setDate(newdate.getDate() + days);
|
||||||
|
return newdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.PeriodDays = class extends bricks.HBox {
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
start_date:
|
||||||
|
end_date:
|
||||||
|
step_type: 'days', 'months', 'years'
|
||||||
|
step_cnt:
|
||||||
|
title:'',
|
||||||
|
splitter:' -- '
|
||||||
|
}
|
||||||
|
event: 'changed';
|
||||||
|
*/
|
||||||
|
constructor(opts){
|
||||||
|
opts.splitter = opts.splitter || ' 至 ';
|
||||||
|
opts.step_cnt = opts.step_cnt || 1;
|
||||||
|
super(opts);
|
||||||
|
this.start_w = new bricks.Text({
|
||||||
|
text:opts.start_date
|
||||||
|
});
|
||||||
|
this.end_w = new bricks.Text({
|
||||||
|
text:opts.end_date
|
||||||
|
});
|
||||||
|
this.start_w.set_css('clickable');
|
||||||
|
this.end_w.set_css('clickable');
|
||||||
|
this.start_w.bind('click', this.step_back.bind(this));
|
||||||
|
this.end_w.bind('click', this.step_forward.bind(this));
|
||||||
|
if (this.title){
|
||||||
|
this.add_widget(new bricks.Text({otext:this.title, i18n:true}));
|
||||||
|
}
|
||||||
|
this.add_widget(this.start_w);
|
||||||
|
this.add_widget(new bricks.Text({
|
||||||
|
otext:this.splitter,
|
||||||
|
i18n:true
|
||||||
|
}));
|
||||||
|
this.add_widget(this.end_w);
|
||||||
|
}
|
||||||
|
date_add(strdate, step_cnt, step_type){
|
||||||
|
var date = bricks.str2date(strdate);
|
||||||
|
switch(step_type){
|
||||||
|
case 'years':
|
||||||
|
var nd = bricks.addYears(date, step_cnt);
|
||||||
|
return bricks.date2str(nd);
|
||||||
|
break;
|
||||||
|
case 'months':
|
||||||
|
var nd = bricks.addMonths(date, step_cnt);
|
||||||
|
return bricks.date2str(nd);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
var nd = bricks.addDays(date, step_cnt);
|
||||||
|
return bricks.date2str(nd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
step_back(){
|
||||||
|
this.start_date = this.date_add(this.start_date, -this.step_cnt, this.step_type);
|
||||||
|
this.end_date = this.date_add(this.end_date, -this.step_cnt, this.step_type);
|
||||||
|
this.start_w.set_text(this.start_date);
|
||||||
|
this.end_w.set_text(this.end_date);
|
||||||
|
this.dispatch('changed', {start_date:this.start_date, end_date:this.end_date});
|
||||||
|
}
|
||||||
|
step_forward(){
|
||||||
|
this.start_date = this.date_add(this.start_date, this.step_cnt, this.step_type);
|
||||||
|
this.end_date = this.date_add(this.end_date, this.step_cnt, this.step_type);
|
||||||
|
this.start_w.set_text(this.start_date);
|
||||||
|
this.end_w.set_text(this.end_date);
|
||||||
|
this.dispatch('changed', {start_date:this.start_date, end_date:this.end_date});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.Factory.register('PeriodDays', bricks.PeriodDays);
|
491
bricks/popup.js
@ -1,87 +1,482 @@
|
|||||||
var bricks = window.bricks || {};
|
var bricks = window.bricks || {};
|
||||||
|
|
||||||
|
bricks.get_popup_default_options = function(){
|
||||||
|
return {
|
||||||
|
timeout:0,
|
||||||
|
archor:'cc',
|
||||||
|
auto_open:true,
|
||||||
|
auto_dismiss:true,
|
||||||
|
auto_destroy:true,
|
||||||
|
movable:true,
|
||||||
|
resizable:false,
|
||||||
|
modal:true
|
||||||
|
}
|
||||||
|
}
|
||||||
bricks.Popup = class extends bricks.VBox {
|
bricks.Popup = class extends bricks.VBox {
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
timeout:0
|
timeout:0
|
||||||
auto_open:
|
|
||||||
archor:one of ['tl', 'tc', 'tr', 'cl', 'cc', 'cr', 'bl','bc', 'br']
|
archor:one of ['tl', 'tc', 'tr', 'cl', 'cc', 'cr', 'bl','bc', 'br']
|
||||||
widget:null for bricks.Body, string value for widget's id or a widget object;
|
widget:null for bricks.Body, string value for widget's id or a widget object;
|
||||||
auto_dismiss:
|
auto_open:boolean
|
||||||
|
auto_dismiss:boolean
|
||||||
|
auto_destroy:boolean
|
||||||
|
movable:boolean
|
||||||
|
dismiss_event:
|
||||||
|
resizable:boolean
|
||||||
|
modal:boolean
|
||||||
|
content:{}
|
||||||
*/
|
*/
|
||||||
constructor(opts){
|
constructor(opts){
|
||||||
super(opts);
|
super(opts);
|
||||||
|
this.no_opened = true;
|
||||||
this.auto_task = null;
|
this.auto_task = null;
|
||||||
this.issub = false;
|
this.issub = false;
|
||||||
this.set_css('modal');
|
this.opened = false;
|
||||||
const zindex = bricks.app.new_zindex();
|
this.set_css('popup');
|
||||||
this.set_style('zIndex', zindex);
|
this.bring_to_top();
|
||||||
|
this.content_box = new bricks.VBox({height:'100%',width:'100%'});
|
||||||
|
super.add_widget(this.content_box);
|
||||||
|
this.content_w = this.content_box;
|
||||||
|
this.moving_w = this;
|
||||||
if (this.auto_dismiss){
|
if (this.auto_dismiss){
|
||||||
bricks.Body.bind('click', this.click_outside.bind(this));
|
bricks.Body.bind('click', this.click_outside.bind(this));
|
||||||
}
|
}
|
||||||
|
this.target_w = bricks.Body;
|
||||||
|
this.moving_status = false;
|
||||||
|
if (this.movable){
|
||||||
|
this.setup_movable();
|
||||||
|
// console.log('movable ...');
|
||||||
|
}
|
||||||
|
if (this.resizable){
|
||||||
|
this.setup_resizable();
|
||||||
|
}
|
||||||
|
this.set_style('display', 'none');
|
||||||
|
bricks.Body.add_widget(this);
|
||||||
|
this.bind('click', this.bring_to_top.bind(this));
|
||||||
|
if (this.auto_open){
|
||||||
|
this.open();
|
||||||
|
}
|
||||||
|
if (this.content){
|
||||||
|
this.bind('opened', this.load_content.bind(this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async load_content(){
|
||||||
|
var w = await bricks.widgetBuild(this.content, this);
|
||||||
|
if (w){
|
||||||
|
this.set_dismiss_events(w);
|
||||||
|
this.content_w.clear_widgets();
|
||||||
|
this.content_w.add_widget(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_dismiss_events(w){
|
||||||
|
if (!this.dismiss_events) return;
|
||||||
|
this.dismiss_events.forEach(ename => {
|
||||||
|
w.bind(ename, this.destroy.bind(this));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
bring_to_top(){
|
||||||
|
if (this == bricks.app.toppopup){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (bricks.app.toppopup)
|
||||||
|
bricks.app.toppopup.set_css('toppopup', true);
|
||||||
|
this.zindex = bricks.app.new_zindex();
|
||||||
|
this.set_style('zIndex', this.zindex);
|
||||||
|
console.log('this.zindex=', this.zindex, 'app.zindex=', bricks.app.zindex);
|
||||||
|
this.set_css('toppopup');
|
||||||
|
bricks.app.toppopup = this;
|
||||||
|
}
|
||||||
|
popup_from_widget(from_w){
|
||||||
|
var myrect = this.showRectage();
|
||||||
|
var rect = from_w.showRectage();
|
||||||
|
var x,y;
|
||||||
|
var ox, oy;
|
||||||
|
ox = (rect.right - rect.left) / 2 + rect.left;
|
||||||
|
oy = (rect.bottom - rect.top) / 2 + rect.top;
|
||||||
|
if (ox < bricks.app.screenWidth() / 2) {
|
||||||
|
x = rect.right + 3;
|
||||||
|
if (x + (myrect.right - myrect.left) > bricks.app.screenWidth()){
|
||||||
|
x = bricks.app.screenWidth() - (myrect.right - myrect.left);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
x = rect.left - (myrect.right - myrect.left) - 3
|
||||||
|
if (x < 0) x = 0;
|
||||||
|
}
|
||||||
|
if (oy < bricks.app.screenHeight() / 2){
|
||||||
|
y = rect.bottom + 3;
|
||||||
|
if (y + (myrect.bottom - myrect.top) > bricks.app.screenHeight()){
|
||||||
|
y = bricks.app.screenHeight() - (myrect.bottom - myrect.top);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
y = rect.bottom - (myrect.bottom - myrect.top) - 3
|
||||||
|
if (y < 0) y = 0;
|
||||||
|
}
|
||||||
|
this.set_style('top', y + 'px');
|
||||||
|
this.set_style('left', x + 'px');
|
||||||
|
}
|
||||||
|
setup_resizable(){
|
||||||
|
this.resizable_w = new bricks.Icon({rate:1.5, url:bricks_resource('imgs/right-bottom-triangle.png')});
|
||||||
|
super.add_widget(this.resizable_w);
|
||||||
|
this.resizable_w.set_css('resizebox');
|
||||||
|
this.resizable_w.bind('mousedown', this.resize_start_pos.bind(this));
|
||||||
|
bricks.Body.bind('mousemove', this.resizing.bind(this));
|
||||||
|
bricks.Body.bind('mouseup', this.stop_resizing.bind(this));
|
||||||
|
}
|
||||||
|
resize_start_pos(e){
|
||||||
|
if (e.target != this.resizable_w.dom_element)
|
||||||
|
{
|
||||||
|
// console.log('not event target');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var rect = this.showRectage();
|
||||||
|
this.resize_status = true;
|
||||||
|
this.s_offsetX = e.clientX;
|
||||||
|
this.s_offsetY = e.clientY;
|
||||||
|
this.s_width = rect.width;
|
||||||
|
this.s_height = rect.height;
|
||||||
|
e.preventDefault();
|
||||||
|
// console.log('resize_start_pos():', this.s_width, this.s_height, this.s_offsetX, this.s_offsetY);
|
||||||
|
}
|
||||||
|
resizing(e){
|
||||||
|
if (e.target != this.resizable_w.dom_element){
|
||||||
|
this.stop_resizing();
|
||||||
|
// console.log('resizing(): not event target');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.resize_status){
|
||||||
|
// console.log('resizing(): not in resize status');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var cx, cy;
|
||||||
|
cx = this.s_width + e.clientX - this.s_offsetX;
|
||||||
|
cy = this.s_height + e.clientY - this.s_offsetY;
|
||||||
|
this.set_style('width', cx + 'px');
|
||||||
|
this.set_style('height', cy + 'px');
|
||||||
|
// console.log('resizing():', this.resize_status, cx, cy);
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
positify_tl(){
|
||||||
|
var rect, w, h, t, l;
|
||||||
|
if (this.top && this.left){
|
||||||
|
this.set_style('top', this.top);
|
||||||
|
this.set_style('left', this.left);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rect = bricks.app.showRectage();
|
||||||
|
if (this.cwidth && this.cwidth > 0){
|
||||||
|
w = this.cwidth * bricks.app.charsize;
|
||||||
|
} else if (this.width){
|
||||||
|
if (this.width.endsWith('px')){
|
||||||
|
w = parseFloat(this.width);
|
||||||
|
} else {
|
||||||
|
w = parseFloat(this.width) * rect.width / 100;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
w = rect.width * 0.8;
|
||||||
|
}
|
||||||
|
if (this.cheight && this.cheight > 0){
|
||||||
|
h = this.cheight * bricks.app.charsize;
|
||||||
|
} else if (this.height){
|
||||||
|
if (this.height.endsWith('px')){
|
||||||
|
h = parseFloat(this.height);
|
||||||
|
} else {
|
||||||
|
h = parseFloat(this.height) * rect.height / 100;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
h = rect.height * 0.8;
|
||||||
|
}
|
||||||
|
var archor = this.archor || 'cc';
|
||||||
|
switch(archor[0]){
|
||||||
|
case 't':
|
||||||
|
t = 0;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
t = (rect.height - h) / 2;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
t = rect.height - h;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
t = (rect.height - h) / 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch(archor[1]){
|
||||||
|
case 'l':
|
||||||
|
l = 0;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
l = (rect.width - w) / 2;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
l = rect.width - w;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
l = (rect.width - w) / 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.set_style('top', t + 'px');
|
||||||
|
this.set_style('left', l + 'px');
|
||||||
|
return {
|
||||||
|
top:t,
|
||||||
|
left:l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_resizing(e){
|
||||||
|
this.resize_status = false;
|
||||||
|
bricks.Body.unbind('mousemove', this.resizing.bind(this));
|
||||||
|
bricks.Body.unbind('mouseup', this.stop_resizing.bind(this));
|
||||||
|
// console.log('stop_resizing():', this.resize_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_movable(){
|
||||||
|
this.moving_w.bind('mousedown', this.rec_start_pos.bind(this));
|
||||||
|
this.moving_w.bind('touchstart', this.rec_start_pos.bind(this));
|
||||||
|
}
|
||||||
|
rec_start_pos(e){
|
||||||
|
if (e.target != this.moving_w.dom_element)
|
||||||
|
{
|
||||||
|
// console.log('moving star failed', e.target, this.moving_w.dom_element, 'difference ...');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.moving_status = true;
|
||||||
|
var rect = this.showRectage();
|
||||||
|
this.offsetX = e.clientX - rect.left;
|
||||||
|
this.offsetY = e.clientY - rect.top;
|
||||||
|
// console.log(rect, '========', this.offsetX, this.offsetY, e.clientX, e.clientY);
|
||||||
|
|
||||||
|
bricks.Body.bind('mouseup', this.stop_moving.bind(this));
|
||||||
|
bricks.Body.bind('touchend', this.stop_moving.bind(this));
|
||||||
|
this.moving_w.bind('mousemove', this.moving.bind(this));
|
||||||
|
this.moving_w.bind('touchmove', this.moving.bind(this));
|
||||||
|
e.preventDefault();
|
||||||
|
// console.log('moving started ...');
|
||||||
|
}
|
||||||
|
moving(e){
|
||||||
|
if (e.target != this.moving_w.dom_element){
|
||||||
|
// console.log('moving failed', e.target, this.moving_w.dom_element, 'difference ...');
|
||||||
|
this.stop_moving();
|
||||||
|
}
|
||||||
|
if (!this.moving_status){
|
||||||
|
// console.log('moving failed', 'not started ...');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var cx, cy;
|
||||||
|
cx = e.clientX - this.offsetX;
|
||||||
|
cy = e.clientY - this.offsetY;
|
||||||
|
// console.log(cx, cy, e.clientX, e.clientY, this.offsetX, this.offsetY, '==========');
|
||||||
|
this.set_style('left', cx + 'px');
|
||||||
|
this.set_style('top', cy + 'px');
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
stop_moving(e){
|
||||||
|
// console.log('stop moving ....');
|
||||||
|
this.moving_status = false;
|
||||||
|
this.moving_w.unbind('mousemove', this.moving.bind(this));
|
||||||
|
this.moving_w.unbind('touchmove', this.moving.bind(this));
|
||||||
|
bricks.Body.unbind('mouseup', this.stop_moving.bind(this));
|
||||||
|
bricks.Body.unbind('touchend', this.stop_moving.bind(this));
|
||||||
}
|
}
|
||||||
click_outside(event){
|
click_outside(event){
|
||||||
if (event.target != this.dom_element){
|
if (event.target != this.dom_element){
|
||||||
this.dismiss();
|
this.dismiss();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
add_widget(w, index){
|
|
||||||
super.add_widget(w, index);
|
|
||||||
if (this.auto_open){
|
|
||||||
this.open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
transform2screen_at(rect, lt){
|
|
||||||
var screen_rect = bricks.Body.showRectage();
|
|
||||||
top = rect.top + parseInt(lt.y) / 100 * rect.height;
|
|
||||||
left = rect.left + parseInt(lt.x) / 100 * rect.width;
|
|
||||||
return {
|
|
||||||
top:top + 'px',
|
|
||||||
left:left + 'px'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
convert_width(){
|
|
||||||
|
|
||||||
}
|
}
|
||||||
open(){
|
open(){
|
||||||
var rect;
|
if (!this.parent){
|
||||||
|
bricks.app.add_widget(this);
|
||||||
if (this.widget instanceof bricks.JsWidget){
|
|
||||||
rect = this.widget.showRectage()
|
|
||||||
this.issub = true;
|
|
||||||
} else if (this.widget instanceof String){
|
|
||||||
var w = bricks.getWidgetById(this.widget, bricks.Body);
|
|
||||||
if (!w){
|
|
||||||
ithis.issub = true
|
|
||||||
rect = bricks.Body.showRectage();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rect = bricks.Body.showRectage();
|
|
||||||
}
|
}
|
||||||
var lt = archor_at(this.archor);
|
var rect, w, h;
|
||||||
if (this.issub){
|
if (this.opened) {
|
||||||
lt = this.transform2screen_at(rect, lt);
|
return;
|
||||||
if (this.width && this.width.endsWith('%')){
|
|
||||||
this.set_style('width', parseFloat(rect.width) * parseFloat(this.width) + 'px');
|
|
||||||
}
|
|
||||||
if (this.height && this.height.endsWith('%')){
|
|
||||||
this.set_style('height', parseFloat(rect.height) * parseFloat(this.height) + 'px');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.set_style('top',lt.top);
|
this.opened = true;
|
||||||
this.set_style('left',lt.left);
|
if (this.no_opened){
|
||||||
|
if (this.widget instanceof bricks.JsWidget){
|
||||||
|
this.target_w = this.widget;
|
||||||
|
this.issub = true;
|
||||||
|
} else {
|
||||||
|
var w = bricks.getWidgetById(this.widget, bricks.Body);
|
||||||
|
if (w){
|
||||||
|
this.issub = true
|
||||||
|
this.target_w = w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.positify_tl()
|
||||||
|
}
|
||||||
|
this.no_opened = false;
|
||||||
this.set_style('display', 'block');
|
this.set_style('display', 'block');
|
||||||
|
this.dispatch('opened');
|
||||||
if (this.timeout > 0){
|
if (this.timeout > 0){
|
||||||
this.auto_task = schedule_once(this.auto_dismiss.bind(this), this.timeout)
|
this.auto_task = schedule_once(this.dismiss.bind(this), this.timeout)
|
||||||
}
|
}
|
||||||
|
if (this.opts.modal && this.opts.widget){
|
||||||
|
this.target_w.disabled(true);
|
||||||
|
}
|
||||||
|
this.bring_to_top();
|
||||||
}
|
}
|
||||||
dismiss(){
|
dismiss(){
|
||||||
|
if (! this.opened) return;
|
||||||
|
if (this.opts.modal){
|
||||||
|
this.target_w.disabled(false);
|
||||||
|
}
|
||||||
|
this.opened = false;
|
||||||
if (this.auto_task){
|
if (this.auto_task){
|
||||||
this.auto_task.cancel();
|
this.auto_task.cancel();
|
||||||
this.auto_task = null;
|
this.auto_task = null;
|
||||||
}
|
}
|
||||||
this.set_style('display','none');
|
this.set_style('display','none');
|
||||||
|
this.dispatch('dismissed');
|
||||||
|
if (this.auto_destroy){
|
||||||
|
this.destroy();
|
||||||
|
this.dispatch('destroy');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
destroy(){
|
||||||
|
if (this.opened){
|
||||||
|
this.dismiss();
|
||||||
|
}
|
||||||
|
if (this.parent){
|
||||||
|
this.parent.remove_widget(this);
|
||||||
|
this.parent = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add_widget(w, i){
|
||||||
|
this.set_dismiss_events(w);
|
||||||
|
this.content_w.add_widget(w, i);
|
||||||
|
if (this.auto_open){
|
||||||
|
this.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remove_widget(w){
|
||||||
|
return this.content_w.remove_widget(w);
|
||||||
|
}
|
||||||
|
clear_widgets(){
|
||||||
|
return this.content_w.clear_widgets();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.get_popupwindow_default_options = function(){
|
||||||
|
return {
|
||||||
|
timeout:0,
|
||||||
|
archor:'cc',
|
||||||
|
auto_open:true,
|
||||||
|
auto_dismiss:true,
|
||||||
|
auto_destroy:true,
|
||||||
|
movable:true,
|
||||||
|
resizable:true,
|
||||||
|
modal:true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bricks.PopupWindow = class extends bricks.Popup {
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
title:
|
||||||
|
icon:
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
constructor(opts){
|
||||||
|
opts.movable = true;
|
||||||
|
opts.resizable = true;
|
||||||
|
var ao = opts.auto_open;
|
||||||
|
opts.auto_open = false
|
||||||
|
opts.auto_dismiss = false;
|
||||||
|
opts.auto_destroy = false;
|
||||||
|
super(opts);
|
||||||
|
this.auto_open = ao;
|
||||||
|
this.title_bar = new bricks.HBox({css:'titlebar', cheight:2, width:'100%'});
|
||||||
|
this.moving_w = this.title_bar;
|
||||||
|
this.add_widget(this.title_bar);
|
||||||
|
this.build_title_bar();
|
||||||
|
var filler = new bricks.Filler({});
|
||||||
|
this.add_widget(filler)
|
||||||
|
|
||||||
|
this.content_w = new bricks.Layout({height:'100%', width:'100%'});
|
||||||
|
this.content_w.set_css('flexbox');
|
||||||
|
filler.add_widget(this.content_w);
|
||||||
|
if (this.auto_open){
|
||||||
|
this.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
build_title_bar(){
|
||||||
|
var icon = new bricks.Icon({
|
||||||
|
rate:this.opts.rate,
|
||||||
|
url:this.opts.icon || bricks_resource('imgs/app.png')
|
||||||
|
});
|
||||||
|
this.title_bar.add_widget(icon);
|
||||||
|
this.tb_w = new bricks.IconBar( {
|
||||||
|
cheight:1,
|
||||||
|
margin:'5px',
|
||||||
|
rate:0.8,
|
||||||
|
tools:[
|
||||||
|
{
|
||||||
|
name:'delete',
|
||||||
|
icon:bricks_resource('imgs/app_delete.png'),
|
||||||
|
dynsize:true,
|
||||||
|
tip:'Destroy this window'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'minimax',
|
||||||
|
icon:bricks_resource('imgs/app_minimax.png'),
|
||||||
|
dynsize:true,
|
||||||
|
tip:'minimax this window'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name:'fullscreen',
|
||||||
|
icon:bricks_resource('imgs/app_fullscreen.png'),
|
||||||
|
dynsize:true,
|
||||||
|
tip:'fullscreen this window'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
this.title_bar.add_widget(this.tb_w);
|
||||||
|
this.tb_w.bind('delete', this.destroy.bind(this));
|
||||||
|
this.tb_w.bind('minimax', this.dismiss.bind(this));
|
||||||
|
this.tb_w.bind('fullscreen', this.enter_fullscreen.bind(this));
|
||||||
|
if (this.title){
|
||||||
|
this.title_w = new bricks.Text({text:this.title});
|
||||||
|
this.title_bar.add_widget(this.title_w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_title(txt){
|
||||||
|
if (this.title_w){
|
||||||
|
this.title_w.set_text(txt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open(){
|
||||||
|
var f = bricks.app.docks.find(o => {
|
||||||
|
if (o == this){
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (! f){
|
||||||
|
bricks.app.docks.push(this);
|
||||||
|
}
|
||||||
|
super.open();
|
||||||
|
}
|
||||||
|
dismiss(){
|
||||||
|
var f = bricks.app.docks.find(o=> o===this);
|
||||||
|
if (!f){
|
||||||
|
bricks.app.docks.push(this);
|
||||||
|
}
|
||||||
|
super.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bricks.Dock = class extends bricks.HBox {
|
||||||
|
constructor(opts){
|
||||||
|
opts.cheight = opts.cheight || 2;
|
||||||
|
opts.width = opts.width || "80%";
|
||||||
|
super(opts);
|
||||||
|
this.set_css('scroll');
|
||||||
|
this.pw = [];
|
||||||
|
}
|
||||||
|
add_popupwindow(pw){
|
||||||
|
var info = pw.get_window_info();
|
||||||
|
|
||||||
|
}
|
||||||
|
del_popupwindow(pw){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bricks.Factory.register('Popup', bricks.Popup);
|
bricks.Factory.register('Popup', bricks.Popup);
|
||||||
|
bricks.Factory.register('PopupWindow', bricks.PopupWindow);
|
||||||
|
24
bricks/progressbar.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
var bricks = window.bricks || {};
|
||||||
|
|
||||||
|
bricks.ProgressBar = class extends bricks.HBox {
|
||||||
|
/*
|
||||||
|
options:
|
||||||
|
total_value
|
||||||
|
bar_cwidth
|
||||||
|
event:
|
||||||
|
*/
|
||||||
|
constructor(opts){
|
||||||
|
super(opts);
|
||||||
|
this.set_css('progress-container');
|
||||||
|
this.text_w = new bricks.Text({text:'0%', cheight:this.bar_cwidth||2});
|
||||||
|
this.text_w.set_css('progress-bar')
|
||||||
|
this.add_widget(this.text_w);
|
||||||
|
}
|
||||||
|
set_value(v){
|
||||||
|
var pzt = (current / total) * 100;
|
||||||
|
pzt = Math.max(0, Math.min(100, percentage));
|
||||||
|
this.text_w.set_style('width', pzt + '%')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bricks.Factory.register('ProgressBar', bricks.ProgressBar);
|
||||||
|
|
0
bricks/registerfunction.js
Executable file → Normal file
11
bricks/splitter.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
var bricks = window.bricks || {};
|
||||||
|
bricks.Splitter = class extends bricks.JsWidget {
|
||||||
|
constructor(ops){
|
||||||
|
super({});
|
||||||
|
}
|
||||||
|
create(){
|
||||||
|
this.dom_element = this._create('hr')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bricks.Factory.register('Splitter', bricks.Splitter);
|
0
bricks/tab.js
Executable file → Normal file
@ -26,7 +26,6 @@ bricks.Tabular = class extends bricks.DataViewer {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
var row = new bricks.VBox({
|
var row = new bricks.VBox({
|
||||||
css:'tabular-row'
|
|
||||||
});
|
});
|
||||||
row.add_widget(r);
|
row.add_widget(r);
|
||||||
var content = new bricks.VBox({
|
var content = new bricks.VBox({
|
||||||
@ -60,13 +59,16 @@ bricks.Tabular = class extends bricks.DataViewer {
|
|||||||
} else {
|
} else {
|
||||||
row.set_css('tabular-row-selected');
|
row.set_css('tabular-row-selected');
|
||||||
}
|
}
|
||||||
|
this.dispatch('row_selected', row.user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async toggle_content(row, flag){
|
async toggle_content(row, flag){
|
||||||
if (flag){
|
if (flag){
|
||||||
row.content_widget.show();
|
row.content_widget.show();
|
||||||
row.content_widget.clear_widgets();
|
row.content_widget.clear_widgets();
|
||||||
var w = await bricks.widgetBuild(this.content_view, row.content_widget, row.user_data);
|
var desc = objcopy(this.content_view);
|
||||||
|
desc = bricks.apply_data(desc, row.user_data);
|
||||||
|
var w = await bricks.widgetBuild(desc, row.content_widget);
|
||||||
if (w){
|
if (w){
|
||||||
row.content_widget.add_widget(w);
|
row.content_widget.add_widget(w);
|
||||||
}
|
}
|
||||||
@ -97,10 +99,13 @@ bricks.Tabular = class extends bricks.DataViewer {
|
|||||||
header = false;
|
header = false;
|
||||||
}
|
}
|
||||||
var dr = new bricks.DataRow(options);
|
var dr = new bricks.DataRow(options);
|
||||||
|
dr.set_css('tabular-row');
|
||||||
dr.render(header);
|
dr.render(header);
|
||||||
|
/*
|
||||||
dr.event_names.forEach(e => {
|
dr.event_names.forEach(e => {
|
||||||
dr.toolbar_w.bind(e, this.record_event_handle.bind(this, e, record, dr));
|
dr.toolbar_w.bind(e, this.record_event_handle.bind(this, e, record, dr));
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
dr.bind('check_changed', this.record_check_changed.bind(this));
|
dr.bind('check_changed', this.record_check_changed.bind(this));
|
||||||
return dr;
|
return dr;
|
||||||
}
|
}
|
||||||
@ -109,7 +114,7 @@ bricks.Tabular = class extends bricks.DataViewer {
|
|||||||
this.dispatch('row_check_changed', event.params.user_data);
|
this.dispatch('row_check_changed', event.params.user_data);
|
||||||
}
|
}
|
||||||
async renew_record_view(form, row){
|
async renew_record_view(form, row){
|
||||||
var d = form.getValue();
|
var d = form._getValue();
|
||||||
var record = bricks.extend(row.user_data, d);
|
var record = bricks.extend(row.user_data, d);
|
||||||
if (this.content_view){
|
if (this.content_view){
|
||||||
row.rec_widget.renew(record);
|
row.rec_widget.renew(record);
|
||||||
|
1
bricks/toolbar.js
Executable file → Normal file
@ -26,6 +26,7 @@ bricks.Toolbar = class extends bricks.Layout {
|
|||||||
this.bar = new bricks.HScrollPanel(options);
|
this.bar = new bricks.HScrollPanel(options);
|
||||||
this.dom_element.classList.add('htoolbar')
|
this.dom_element.classList.add('htoolbar')
|
||||||
}
|
}
|
||||||
|
this.bar.enable_key_select()
|
||||||
this.add_widget(this.bar);
|
this.add_widget(this.bar);
|
||||||
this.clicked_btn = null;
|
this.clicked_btn = null;
|
||||||
this.preffix_css = this.opts.css || 'toolbar';
|
this.preffix_css = this.opts.css || 'toolbar';
|
||||||
|
58
bricks/tree.js
Executable file → Normal file
@ -133,9 +133,8 @@ bricks.TreeNode = class extends bricks.VBox {
|
|||||||
if (this.view_w){
|
if (this.view_w){
|
||||||
widget.add_widget(this.view_w);
|
widget.add_widget(this.view_w);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
this.str_w.set_text(this.user_data[this.tree.opts.textField]);
|
|
||||||
}
|
}
|
||||||
|
this.str_w.set_text(this.user_data[this.tree.opts.textField]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,6 +170,8 @@ bricks.Tree = class extends bricks.VScrollPanel {
|
|||||||
this.row_height = this.opts.row_height || '35px';
|
this.row_height = this.opts.row_height || '35px';
|
||||||
this.multitype_tree = this.opts.multitype_tree||false;
|
this.multitype_tree = this.opts.multitype_tree||false;
|
||||||
this.selected_node = null;
|
this.selected_node = null;
|
||||||
|
this.build_title();
|
||||||
|
this.build_description();
|
||||||
this.create_toolbar();
|
this.create_toolbar();
|
||||||
this.checked_data = [];
|
this.checked_data = [];
|
||||||
this.container = new bricks.VBox({
|
this.container = new bricks.VBox({
|
||||||
@ -209,14 +210,14 @@ bricks.Tree = class extends bricks.VScrollPanel {
|
|||||||
create_toolbar(){
|
create_toolbar(){
|
||||||
var toolbar = bricks.extend({}, this.toolbar);
|
var toolbar = bricks.extend({}, this.toolbar);
|
||||||
var tools = [];
|
var tools = [];
|
||||||
if (toolbar.tools){
|
|
||||||
toolbar.tools.forEach(f => tools.push(f));
|
|
||||||
}
|
|
||||||
if (this.editable){
|
if (this.editable){
|
||||||
tools.push({icon:bricks_resource('imgs/add.png'), name:'add'});
|
tools.push({icon:bricks_resource('imgs/add.png'), name:'add'});
|
||||||
tools.push({icon:bricks_resource('imgs/update.png'), name:'update'});
|
tools.push({icon:bricks_resource('imgs/update.png'), name:'update'});
|
||||||
tools.push({icon:bricks_resource('imgs/delete.png'), name:'delete'});
|
tools.push({icon:bricks_resource('imgs/delete.png'), name:'delete'});
|
||||||
}
|
}
|
||||||
|
if (toolbar.tools){
|
||||||
|
toolbar.tools.forEach(f => tools.push(f));
|
||||||
|
}
|
||||||
if (tools.length == 0){
|
if (tools.length == 0){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -230,7 +231,7 @@ bricks.Tree = class extends bricks.VScrollPanel {
|
|||||||
switch (opts.name){
|
switch (opts.name){
|
||||||
case 'add':
|
case 'add':
|
||||||
this.add_new_node();
|
this.add_new_node();
|
||||||
breaks;
|
break;
|
||||||
case 'delete':
|
case 'delete':
|
||||||
this.delete_node();
|
this.delete_node();
|
||||||
break;
|
break;
|
||||||
@ -238,16 +239,17 @@ bricks.Tree = class extends bricks.VScrollPanel {
|
|||||||
this.update_node();
|
this.update_node();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
if ((opts.selected_data || opts.checked_data) && ! this.selected_node){
|
||||||
|
w = new bricks.Error({title:'Error', message:'No selected node found'});
|
||||||
|
w.open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
console.log('opts=', opts);
|
console.log('opts=', opts);
|
||||||
var d = null;
|
var d = null;
|
||||||
if (opts.checked_data){
|
if (opts.checked_data){
|
||||||
d = {
|
d = this.checked_data
|
||||||
checked_data:JSON.stringify(this.checked_data)
|
} else if (opts.selected_data){
|
||||||
}
|
d = this.selected_node.user_data
|
||||||
} else if (opts.selected_node){
|
|
||||||
d = {
|
|
||||||
selected_data:JSON.stringify(this.selected_node.user_data)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.dispatch(opts.name, d);
|
this.dispatch(opts.name, d);
|
||||||
break;
|
break;
|
||||||
@ -269,7 +271,11 @@ bricks.Tree = class extends bricks.VScrollPanel {
|
|||||||
var node = this;
|
var node = this;
|
||||||
if (this.selected_node){
|
if (this.selected_node){
|
||||||
node = this.selected_node;
|
node = this.selected_node;
|
||||||
d[this.parentField] = node.get_id();
|
if (d instanceof FormData){
|
||||||
|
d.append(this.parentField, node.get_id());
|
||||||
|
} else {
|
||||||
|
d[this.parentField] = node.get_id();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (this.editable.add_url){
|
if (this.editable.add_url){
|
||||||
var jc = new bricks.HttpJson()
|
var jc = new bricks.HttpJson()
|
||||||
@ -316,6 +322,8 @@ bricks.Tree = class extends bricks.VScrollPanel {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var w = new bricks.Conform({
|
var w = new bricks.Conform({
|
||||||
|
cwidth:16,
|
||||||
|
cheight:9,
|
||||||
title:'Delete node',
|
title:'Delete node',
|
||||||
message:'Please conform delete selected node'
|
message:'Please conform delete selected node'
|
||||||
});
|
});
|
||||||
@ -383,24 +391,34 @@ bricks.Tree = class extends bricks.VScrollPanel {
|
|||||||
async update_node_inputed(event){
|
async update_node_inputed(event){
|
||||||
var d = event.params;
|
var d = event.params;
|
||||||
var node = this.selected_node;
|
var node = this.selected_node;
|
||||||
d[this.idField] = node.get_id();
|
if (d instanceof FormData){
|
||||||
|
d.append(this.idField, node.get_id());
|
||||||
|
} else {
|
||||||
|
d[this.idField] = node.get_id();
|
||||||
|
}
|
||||||
if(this.editable.update_url){
|
if(this.editable.update_url){
|
||||||
var jc = new bricks.HttpJson()
|
var jc = new bricks.HttpJson()
|
||||||
var desc = await jc.post(this.editable.update_url, {params:d});
|
var desc = await jc.post(this.editable.update_url, {params:d});
|
||||||
if (desc.widgettype == 'Message'){
|
if (desc.widgettype == 'Message'){
|
||||||
await this.update_node_data(node, d);
|
var o = formdata2object(d);
|
||||||
|
await this.update_node_data(node, o);
|
||||||
}
|
}
|
||||||
var w = await bricks.widgetBuild(desc, this);
|
var w = await bricks.widgetBuild(desc, this);
|
||||||
w.open();
|
w.open();
|
||||||
} else {
|
} else {
|
||||||
await this.update_node_data(node, d);
|
var o = formdata2object(d);
|
||||||
|
await this.update_node_data(node, o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async update_node_data(node, data){
|
async update_node_data(node, data){
|
||||||
for (var name in Object.keys(data)){
|
var data_keys = Object.keys(node.user_data);
|
||||||
node.user_data[name] = data[name];
|
Object.keys(data).forEach(k => {
|
||||||
}
|
if (data_keys.includes(k)){
|
||||||
|
console.log(node.user_data[k], ':', k, ':', data[k]);
|
||||||
|
node.user_data[k] = data[k];
|
||||||
|
}
|
||||||
|
});
|
||||||
await node.update_content();
|
await node.update_content();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
0
bricks/uitypesdef.js
Executable file → Normal file
291
bricks/utils.js
Executable file → Normal file
@ -1,22 +1,104 @@
|
|||||||
var bricks = window.bricks || {};
|
var bricks = window.bricks || {};
|
||||||
bricks.bug = false;
|
bricks.bug = false;
|
||||||
|
|
||||||
|
bricks.formdata_copy = function(fd){
|
||||||
|
var cfd = new FormData();
|
||||||
|
|
||||||
|
// 遍历 originalFormData 中的所有条目并添加到 clonedFormData 中
|
||||||
|
for (var pair of fd.entries()) {
|
||||||
|
cfd.append(pair[0], pair[1]);
|
||||||
|
}
|
||||||
|
return cfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.map = function(data_source, mapping, need_others){
|
||||||
|
ret = {};
|
||||||
|
Object.entries(data_source).forEach(([key, value]) => {
|
||||||
|
if (mapping.hasOwnProperty(key)){
|
||||||
|
ret[mapping[key]] = data_source[key];
|
||||||
|
} else if (need_others){
|
||||||
|
ret[key] = data_source[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.relocate_by_eventpos = function(event, widget){
|
||||||
|
var ex,ey;
|
||||||
|
var x,y;
|
||||||
|
var xsize = bricks.Body.dom_element.clientWidth;
|
||||||
|
var ysize = bricks.Body.dom_element.clientHeight;
|
||||||
|
ex = event.clientX;
|
||||||
|
ey = event.clientY;
|
||||||
|
var mxs = widget.dom_element.offsetWidth;
|
||||||
|
var mys = widget.dom_element.offsetHeight;
|
||||||
|
if (ex < (xsize / 2)) {
|
||||||
|
x = ex + bricks.app.charsize;
|
||||||
|
} else {
|
||||||
|
x = ex - mxs - bricks.app.charsize;
|
||||||
|
}
|
||||||
|
if (ey < (ysize / 2)) {
|
||||||
|
y = ey + bricks.app.charsize;
|
||||||
|
} else {
|
||||||
|
y = ey - mys - bricks.app.charsize;
|
||||||
|
}
|
||||||
|
widget.set_style('left', x + 'px');
|
||||||
|
widget.set_style('top', y + 'px');
|
||||||
|
}
|
||||||
|
|
||||||
|
var formdata2object = function(formdata){
|
||||||
|
let result = {};
|
||||||
|
formdata.forEach((value, key) => {
|
||||||
|
result[key] = value;
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
var inputdata2dic = function(data){
|
||||||
|
try {
|
||||||
|
var d = {}
|
||||||
|
for (let k of data.keys()){
|
||||||
|
var x = data.get(k);
|
||||||
|
if (k == 'prompt'){
|
||||||
|
x = bricks.escapeSpecialChars(x);
|
||||||
|
}
|
||||||
|
d[k] = x;
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
} catch (e){
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
bricks.delete_null_values = function(obj) {
|
bricks.delete_null_values = function(obj) {
|
||||||
for (let key in obj) {
|
for (let key in obj) {
|
||||||
if (obj[key] === null) {
|
if (obj[key] === null) {
|
||||||
delete obj[key];
|
delete obj[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
bricks.is_empty = function(obj){
|
bricks.is_empty = function(obj){
|
||||||
if (obj === null) return true;
|
if (obj === null) return true;
|
||||||
return JSON.stringify(obj) === '{}';
|
return JSON.stringify(obj) === '{}';
|
||||||
}
|
}
|
||||||
|
bricks.serverdebug = async function(message){
|
||||||
|
var jc = new bricks.HttpJson();
|
||||||
|
await jc.post(url='/debug', {params:{
|
||||||
|
message:message
|
||||||
|
}});
|
||||||
|
return;
|
||||||
|
}
|
||||||
bricks.debug = function(...args){
|
bricks.debug = function(...args){
|
||||||
if (! bricks.bug){
|
if (! bricks.bug){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (bricks.bug == 'server'){
|
||||||
|
var message = args.join(" ");
|
||||||
|
f = bricks.serverdebug.bind(null, message);
|
||||||
|
schedule_once(f, 0.1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
var callInfo;
|
var callInfo;
|
||||||
try {
|
try {
|
||||||
throw new Error();
|
throw new Error();
|
||||||
@ -31,7 +113,7 @@ bricks.debug = function(...args){
|
|||||||
}
|
}
|
||||||
|
|
||||||
bricks.is_mobile = function(){
|
bricks.is_mobile = function(){
|
||||||
var userAgent = navigator.userAgent;
|
var userAgent = navigator.userAgent;
|
||||||
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent)) {
|
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -77,9 +159,9 @@ var currentScriptPath = function () {
|
|||||||
}
|
}
|
||||||
currentScript = scripts[ scripts.length - 1 ].src;
|
currentScript = scripts[ scripts.length - 1 ].src;
|
||||||
}
|
}
|
||||||
var currentScriptChunks = currentScript.split( '/' );
|
var currentScriptChunks = currentScript.split( '/' );
|
||||||
var currentScriptFile = currentScriptChunks[ currentScriptChunks.length - 1 ];
|
var currentScriptFile = currentScriptChunks[ currentScriptChunks.length - 1 ];
|
||||||
return currentScript.replace( currentScriptFile, '' );
|
return currentScript.replace( currentScriptFile, '' );
|
||||||
}
|
}
|
||||||
|
|
||||||
bricks.path = currentScriptPath();
|
bricks.path = currentScriptPath();
|
||||||
@ -94,17 +176,17 @@ var bricks_resource = function(name){
|
|||||||
* @see https://stackoverflow.com/a/71692555/2228771
|
* @see https://stackoverflow.com/a/71692555/2228771
|
||||||
*/
|
*/
|
||||||
function querySelectorAllShadows(selector, el = document.body) {
|
function querySelectorAllShadows(selector, el = document.body) {
|
||||||
// recurse on childShadows
|
// recurse on childShadows
|
||||||
const childShadows = Array.from(el.querySelectorAll('*')).
|
const childShadows = Array.from(el.querySelectorAll('*')).
|
||||||
map(el => el.shadowRoot).filter(Boolean);
|
map(el => el.shadowRoot).filter(Boolean);
|
||||||
|
|
||||||
bricks.debug('[querySelectorAllShadows]', selector, el, `(${childShadows.length} shadowRoots)`);
|
bricks.debug('[querySelectorAllShadows]', selector, el, `(${childShadows.length} shadowRoots)`);
|
||||||
|
|
||||||
const childResults = childShadows.map(child => querySelectorAllShadows(selector, child));
|
const childResults = childShadows.map(child => querySelectorAllShadows(selector, child));
|
||||||
|
|
||||||
// fuse all results into singular, flat array
|
// fuse all results into singular, flat array
|
||||||
const result = Array.from(el.querySelectorAll(selector));
|
const result = Array.from(el.querySelectorAll(selector));
|
||||||
return result.concat(childResults).flat();
|
return result.concat(childResults).flat();
|
||||||
}
|
}
|
||||||
|
|
||||||
var schedule_once = function(f, t){
|
var schedule_once = function(f, t){
|
||||||
@ -182,7 +264,7 @@ bricks.obj_fmtstr = function(obj, fmt){
|
|||||||
'${name:}, ${age=}'
|
'${name:}, ${age=}'
|
||||||
*/
|
*/
|
||||||
var s = fmt;
|
var s = fmt;
|
||||||
s = s.replace(/\${(\w+)([:=]*)}/g, (k, key, op) => {
|
s = s.replace(/\${(\w+)([:=]*)}/g, (k, key, op) => {
|
||||||
if (obj.hasOwnProperty(key)){
|
if (obj.hasOwnProperty(key)){
|
||||||
if (op == ''){
|
if (op == ''){
|
||||||
return obj[key];
|
return obj[key];
|
||||||
@ -257,7 +339,7 @@ var archorize = function(ele,archor){
|
|||||||
}
|
}
|
||||||
|
|
||||||
Array.prototype.insert = function ( index, ...items ) {
|
Array.prototype.insert = function ( index, ...items ) {
|
||||||
this.splice( index, 0, ...items );
|
this.splice( index, 0, ...items );
|
||||||
};
|
};
|
||||||
|
|
||||||
Array.prototype.remove = function(item){
|
Array.prototype.remove = function(item){
|
||||||
@ -297,26 +379,26 @@ var convert2int = function(s){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setCookie(name,value,days) {
|
function setCookie(name,value,days) {
|
||||||
var expires = "";
|
var expires = "";
|
||||||
if (days) {
|
if (days) {
|
||||||
var date = new Date();
|
var date = new Date();
|
||||||
date.setTime(date.getTime() + (days*24*60*60*1000));
|
date.setTime(date.getTime() + (days*24*60*60*1000));
|
||||||
expires = "; expires=" + date.toUTCString();
|
expires = "; expires=" + date.toUTCString();
|
||||||
}
|
}
|
||||||
document.cookie = name + "=" + (value || "") + expires + "; path=/";
|
document.cookie = name + "=" + (value || "") + expires + "; path=/";
|
||||||
}
|
}
|
||||||
function getCookie(name) {
|
function getCookie(name) {
|
||||||
var nameEQ = name + "=";
|
var nameEQ = name + "=";
|
||||||
var ca = document.cookie.split(';');
|
var ca = document.cookie.split(';');
|
||||||
for(var i=0;i < ca.length;i++) {
|
for(var i=0;i < ca.length;i++) {
|
||||||
var c = ca[i];
|
var c = ca[i];
|
||||||
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
||||||
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
function eraseCookie(name) {
|
function eraseCookie(name) {
|
||||||
document.cookie = name +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
document.cookie = name +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
||||||
}
|
}
|
||||||
|
|
||||||
var set_max_height = function(w1, w2){
|
var set_max_height = function(w1, w2){
|
||||||
@ -330,13 +412,48 @@ var set_max_height = function(w1, w2){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var objcopy = function(obj){
|
var objcopy = function(obj){
|
||||||
var o = {}
|
var s = JSON.stringify(obj);
|
||||||
for ( k in obj){
|
return JSON.parse(s);
|
||||||
if (obj.hasOwnProperty(k)){
|
}
|
||||||
o[k] = obj[k];
|
|
||||||
}
|
bricks.set_stream_source = async function(target, url, params){
|
||||||
}
|
var widget;
|
||||||
return o;
|
if (typeof target == typeof ''){
|
||||||
|
widget = bricks.getWidgetById(target);
|
||||||
|
} else if (target instanceof bricks.JsWidget){
|
||||||
|
widget = target;
|
||||||
|
} else {
|
||||||
|
widget = await bricks.widgetBuild(target);
|
||||||
|
}
|
||||||
|
if (! widget){
|
||||||
|
bricks.debug('playResponseAudio():', target, 'can not found or build a widget');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const mediaSource = new MediaSource();
|
||||||
|
mediaSource.addEventListener('sourceopen', handleSourceOpen);
|
||||||
|
widget.set_url(URL.createObjectURL(mediaSource));
|
||||||
|
function handleSourceOpen(){
|
||||||
|
const sourceBuffer = mediaSource.addSourceBuffer('audio/wav; codecs=1');
|
||||||
|
var ht = new bricks.HttpText();
|
||||||
|
ht.bricks_fetch(url, {params:params})
|
||||||
|
.then(response => response.body)
|
||||||
|
.then(body => {
|
||||||
|
const reader = body.getReader();
|
||||||
|
const read = () => {
|
||||||
|
reader.read().then(({ done, value }) => {
|
||||||
|
if (done) {
|
||||||
|
mediaSource.endOfStream();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sourceBuffer.appendBuffer(value);
|
||||||
|
read();
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('Error reading audio stream:', error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
read();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bricks.playResponseAudio = async function(response, target){
|
bricks.playResponseAudio = async function(response, target){
|
||||||
@ -354,8 +471,8 @@ bricks.playResponseAudio = async function(response, target){
|
|||||||
bricks.debug('playResponseAudio():', target, 'can not found or build a widget');
|
bricks.debug('playResponseAudio():', target, 'can not found or build a widget');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const blob = await response.blob();
|
const blob = await response.blob();
|
||||||
const url = URL.createObjectURL(blob);
|
const url = URL.createObjectURL(blob);
|
||||||
widget.set_url(url);
|
widget.set_url(url);
|
||||||
widget.play();
|
widget.play();
|
||||||
}
|
}
|
||||||
@ -382,12 +499,88 @@ bricks.Observable = class {
|
|||||||
this.value = v;
|
this.value = v;
|
||||||
}
|
}
|
||||||
set(v){
|
set(v){
|
||||||
if (this.value != v){
|
var ov = this.value;
|
||||||
|
this.value = v;
|
||||||
|
if (this.value != ov){
|
||||||
this.owner.dispatch(this.name, v);
|
this.owner.dispatch(this.name, v);
|
||||||
}
|
}
|
||||||
this.value = v;
|
|
||||||
}
|
}
|
||||||
get(){
|
get(){
|
||||||
return this.v;
|
return this.v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bricks.Queue = class {
|
||||||
|
constructor() {
|
||||||
|
this.items = [];
|
||||||
|
this._done = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加元素到队列尾部
|
||||||
|
enqueue(element) {
|
||||||
|
this.items.push(element);
|
||||||
|
}
|
||||||
|
done(){
|
||||||
|
this._done = true;
|
||||||
|
}
|
||||||
|
is_done(){
|
||||||
|
return this._done;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除队列的第一个元素并返回
|
||||||
|
dequeue() {
|
||||||
|
if (this.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return this.items.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看队列的第一个元素
|
||||||
|
peek() {
|
||||||
|
if (this.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return this.items[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查队列是否为空
|
||||||
|
isEmpty() {
|
||||||
|
return this.items.length === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取队列的大小
|
||||||
|
size() {
|
||||||
|
return this.items.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空队列
|
||||||
|
clear() {
|
||||||
|
this.items = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打印队列元素
|
||||||
|
print() {
|
||||||
|
console.log(this.items.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function blobToBase64(blob) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onloadend = function() {
|
||||||
|
resolve(reader.result);
|
||||||
|
};
|
||||||
|
reader.onerror = reject;
|
||||||
|
reader.readAsDataURL(blob);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// 使用队列
|
||||||
|
const queue = new Queue();
|
||||||
|
queue.enqueue(1);
|
||||||
|
queue.enqueue(2);
|
||||||
|
queue.enqueue(3);
|
||||||
|
queue.print(); // 输出: 1,2,3
|
||||||
|
console.log(queue.dequeue()); // 输出: 1
|
||||||
|
queue.print(); // 输出: 2,3
|
||||||
|
*/
|
||||||
|
218
bricks/video.js
Executable file → Normal file
@ -26,6 +26,7 @@ bricks.VideoBody = class extends bricks.Layout {
|
|||||||
bricks.Video = class extends bricks.Layout {
|
bricks.Video = class extends bricks.Layout {
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
|
title:
|
||||||
vtype:
|
vtype:
|
||||||
url:
|
url:
|
||||||
fullscreen:
|
fullscreen:
|
||||||
@ -34,13 +35,22 @@ bricks.Video = class extends bricks.Layout {
|
|||||||
*/
|
*/
|
||||||
constructor(options){
|
constructor(options){
|
||||||
super(options);
|
super(options);
|
||||||
this.video_body = new bricks.VideoBody(options);
|
// this.video_body = new bricks.VideoBody(options);
|
||||||
this.add_widget(this.video_body);
|
this.set_css('video-js');
|
||||||
|
this.set_css('vjs-big-play-centered');
|
||||||
|
this.set_css('vjs-fluid');
|
||||||
|
this.set_style('width', '100%');
|
||||||
|
this.set_style('height', '100%');
|
||||||
|
this.set_style('object-fit', 'contain');
|
||||||
|
this.cur_url = opts.url;
|
||||||
|
this.cur_vtype = opts.type;
|
||||||
schedule_once(this.create_player.bind(this), 0.1);
|
schedule_once(this.create_player.bind(this), 0.1);
|
||||||
this.hidedbtn = new bricks.Button({label:'click me'});
|
}
|
||||||
this.hidedbtn.bind('click', this.play.bind(this));
|
create(){
|
||||||
this.hidedbtn.hide();
|
var e;
|
||||||
this.add_widget(this.hidedbtn);
|
e = document.createElement('video');
|
||||||
|
this.dom_element = e;
|
||||||
|
e.controls = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy_resource(params, event){
|
destroy_resource(params, event){
|
||||||
@ -62,17 +72,46 @@ bricks.Video = class extends bricks.Layout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
findVideoButtonByClass(cls){
|
||||||
|
var e = this.dom_element;
|
||||||
|
return e.querySelector('.' + cls);
|
||||||
|
}
|
||||||
|
|
||||||
auto_play(){
|
auto_play(){
|
||||||
schedule_once(this._auto_play.bind(this), 0.5);
|
schedule_once(this._auto_play.bind(this), 0.8);
|
||||||
}
|
}
|
||||||
_auto_play(){
|
_auto_play(){
|
||||||
|
this.set_url(this.opts.url);
|
||||||
|
return;
|
||||||
|
var play_btn = this.findVideoButtonByClass('vjs-big-play-button');
|
||||||
|
if (!play_btn){
|
||||||
|
console.log('vjs-big-play-button not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (play_btn.style.display == 'none'){
|
||||||
|
console.log('playing .............already');
|
||||||
|
return;
|
||||||
|
}
|
||||||
console.log('video ready, auto_playing ....');
|
console.log('video ready, auto_playing ....');
|
||||||
schedule_once(this.disable_captions.bind(this), 2);
|
var clickevent = new MouseEvent('click', {
|
||||||
this.hidedbtn.dispatch('click');
|
'bubbles': true, // 事件是否冒泡
|
||||||
|
'cancelable': true // 事件是否可取消
|
||||||
|
});
|
||||||
|
play_btn.dispatchEvent(clickevent);
|
||||||
|
/*
|
||||||
|
if (this.autounmute && this.player.muted){
|
||||||
|
schedule_once(this.dispatch_mute.bind(this), 1);
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
play(){
|
play(){
|
||||||
console.log('Video:play() called....');
|
console.log('Video:play() called....');
|
||||||
this.player.play();
|
this.player.play();
|
||||||
|
// this.player.muted(false);
|
||||||
|
}
|
||||||
|
unmuted(){
|
||||||
|
this.player.muted(false);
|
||||||
}
|
}
|
||||||
set_fullscreen(){
|
set_fullscreen(){
|
||||||
if (this.fullscreen){
|
if (this.fullscreen){
|
||||||
@ -85,9 +124,31 @@ bricks.Video = class extends bricks.Layout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dispatch_mute(){
|
||||||
|
var mute_btn = this.findVideoButtonByClass("vjs-mute-control.vjs-control.vjs-button");
|
||||||
|
if (!mute_btn){
|
||||||
|
var isMute = this.player.muted();
|
||||||
|
if (isMuted){
|
||||||
|
this.player.muted(False);
|
||||||
|
}
|
||||||
|
bricks.test_element = this;
|
||||||
|
console.log(this, 'there is not mute button found, isMuted=', isMuted);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var clickevent = new MouseEvent('click', {
|
||||||
|
'bubbles': true, // 事件是否冒泡
|
||||||
|
'cancelable': true // 事件是否可取消
|
||||||
|
});
|
||||||
|
var isMuted = this.player.muted();
|
||||||
|
if (isMuted){
|
||||||
|
mute_btn.dispatchEvent(clickevent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
create_player(){
|
create_player(){
|
||||||
if(this.url){
|
if(this.url){
|
||||||
this.player = videojs(this.video_body.dom_element, {
|
// this.player = videojs(this.video_body.dom_element, {
|
||||||
|
this.player = videojs(this.dom_element, {
|
||||||
controls:true,
|
controls:true,
|
||||||
autoplay:this.autoplay,
|
autoplay:this.autoplay,
|
||||||
muted:true,
|
muted:true,
|
||||||
@ -98,37 +159,49 @@ bricks.Video = class extends bricks.Layout {
|
|||||||
this.player.on('error',this.report_error.bind(this));
|
this.player.on('error',this.report_error.bind(this));
|
||||||
this.player.on('play', this.report_playok.bind(this));
|
this.player.on('play', this.report_playok.bind(this));
|
||||||
this.player.on('ended', this.report_ended.bind(this));
|
this.player.on('ended', this.report_ended.bind(this));
|
||||||
this._set_source();
|
this.set_url(this.opts.url);
|
||||||
this.player.ready(this.set_fullscreen.bind(this));
|
this.player.ready(this.set_fullscreen.bind(this));
|
||||||
/*
|
|
||||||
if (this.autoplay){
|
if (this.autoplay){
|
||||||
this.player.autoplay = true;
|
this.auto_play();
|
||||||
this.player.muted = true;
|
|
||||||
this.player.ready(this.auto_play.bind(this));
|
|
||||||
} else {
|
|
||||||
console.log('autoplay=', this.autoplay, this.auto_play);
|
|
||||||
// this.player.ready(this.auto_play.bind(this));
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
report_ended(){
|
report_ended(){
|
||||||
this.dispatch('play_end',{src:this.video_body.cur_url,type:this.video_body.cur_vtype});
|
if (this.play_status != 'playok'){
|
||||||
|
returnl
|
||||||
|
}
|
||||||
|
this.play_status = 'playend';
|
||||||
|
this.dispatch('play_end',{src:this.cur_url,type:this.cur_vtype});
|
||||||
}
|
}
|
||||||
report_playok(){
|
report_playok(){
|
||||||
console.log(this.video_body.cur_url, 'play ok');
|
if (this.play_status != ''){
|
||||||
this.dispatch('play_ok', {src:this.video_body.cur_url,type:this.video_body.cur_vtype});
|
return;
|
||||||
|
}
|
||||||
|
this.play_status = 'playok';
|
||||||
|
console.log(this.cur_url, 'play ok');
|
||||||
|
if (this.autounmute && this.player.muted()){
|
||||||
|
schedule_once(this.dispatch_mute.bind(this), 2.5);
|
||||||
|
console.log('mute btn clicked');
|
||||||
|
} else {
|
||||||
|
console.log(this.autounmute, 'player.muted=', this.player.muted);
|
||||||
|
}
|
||||||
|
this.dispatch('play_ok', {src:this.cur_url,type:this.cur_vtype});
|
||||||
}
|
}
|
||||||
report_error(){
|
report_error(){
|
||||||
console.log(this.video_body.cur_url, 'play failed', this.err_cnt, 'times');
|
if (this.play_status != ''){
|
||||||
this.dispatch('play_failed', {'src':this.video_body.cur_url, type:this.video_body.cur_vtype});
|
return;
|
||||||
|
}
|
||||||
|
this.play_status = 'playfailed';
|
||||||
|
console.log(this.cur_url, 'play failed', this.err_cnt, 'times');
|
||||||
|
this.dispatch('play_failed', {'src':this.cur_url, type:this.cur_vtype});
|
||||||
}
|
}
|
||||||
_set_source(){
|
_set_source(){
|
||||||
if (this.player){
|
if (this.player){
|
||||||
this.player.src({
|
this.player.src({
|
||||||
src:this.video_body.cur_url,
|
src:this.cur_url,
|
||||||
type:this.video_body.cur_vtype
|
type:this.cur_vtype
|
||||||
});
|
});
|
||||||
|
this.play_status = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_source(url, vtype){
|
set_source(url, vtype){
|
||||||
@ -137,17 +210,106 @@ bricks.Video = class extends bricks.Layout {
|
|||||||
vtype = 'application/x-mpegURL';
|
vtype = 'application/x-mpegURL';
|
||||||
} else if (t.endsWith('.mp4')){
|
} else if (t.endsWith('.mp4')){
|
||||||
vtype = 'video/mp4';
|
vtype = 'video/mp4';
|
||||||
|
} else if (t.endsWith('.avi')){
|
||||||
|
vtype = 'video/avi';
|
||||||
} else if (t.endsWith('.webm')){
|
} else if (t.endsWith('.webm')){
|
||||||
vtype = 'video/webm';
|
vtype = 'video/webm';
|
||||||
} else {
|
} else {
|
||||||
vtype = 'application/x-mpegURL';
|
vtype = 'application/x-mpegURL';
|
||||||
}
|
}
|
||||||
if(this.player){
|
if(this.player){
|
||||||
this.video_body.cur_url = url;
|
this.cur_url = url;
|
||||||
this.video_body.cur_vtype = vtype;
|
this.cur_vtype = vtype;
|
||||||
this._set_source();
|
this._set_source();
|
||||||
|
this.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
set_url(url){
|
||||||
|
this.set_source(url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bricks.Iptv = class extends bricks.VBox {
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
iptv_data_url:
|
||||||
|
playok_url:
|
||||||
|
playfailed_url:
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
constructor(opts){
|
||||||
|
super(opts);
|
||||||
|
schedule_once(this.build_subwidgets.bind(this), 0.1);
|
||||||
|
}
|
||||||
|
async build_subwidgets(){
|
||||||
|
console.log('build_subwidgets called');
|
||||||
|
var jc = new bricks.HttpJson();
|
||||||
|
this.deviceid = bricks.deviceid('iptv')
|
||||||
|
this.user_data = await jc.httpcall(this.iptv_data_url, {
|
||||||
|
params:{
|
||||||
|
deviceid:this.deviceid
|
||||||
|
},
|
||||||
|
method:'GET'
|
||||||
|
});
|
||||||
|
console.log('this.user_data =', this.user_data);
|
||||||
|
this.video = new bricks.Video({
|
||||||
|
autoplay:true,
|
||||||
|
autounmute:this.autounmute,
|
||||||
|
url:this.user_data.url
|
||||||
|
});
|
||||||
|
this.title_w = new bricks.Text({text:this.user_data.tv_name, wrap:false});
|
||||||
|
this.add_widget(this.title_w);
|
||||||
|
this.add_widget(this.video);
|
||||||
|
this.video.bind('play_ok', this.report_play_ok.bind(this));
|
||||||
|
this.video.bind('play_failed', this.report_play_failed.bind(this));
|
||||||
|
}
|
||||||
|
async report_play_ok(){
|
||||||
|
console.log(this.user_data, 'channel playing ...', this.playok_url);
|
||||||
|
if (this.playok_url){
|
||||||
|
var ht = new bricks.HttpText();
|
||||||
|
var resp = ht.httpcall(this.playok_url,{
|
||||||
|
params:{
|
||||||
|
deviceid:this.deviceid,
|
||||||
|
channelid:this.user_data.id
|
||||||
|
},
|
||||||
|
method:"GET"
|
||||||
|
});
|
||||||
|
if (resp != 'Error'){
|
||||||
|
console.log('report playok ok');
|
||||||
|
} else {
|
||||||
|
console.log('report playok failed');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('this.playok_url not defined', this.playok_url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async report_play_failed(){
|
||||||
|
console.log(this.user_data, 'channel play failed ...');
|
||||||
|
if (this.playfailed_url){
|
||||||
|
var ht = new bricks.HttpText();
|
||||||
|
var resp = ht.httpcall(this.playfailed_url,{
|
||||||
|
params:{
|
||||||
|
deviceid:this.deviceid,
|
||||||
|
channelid:this.user_data.id
|
||||||
|
},
|
||||||
|
method:"GET"
|
||||||
|
});
|
||||||
|
if (resp != 'Error'){
|
||||||
|
console.log('report playfailed ok');
|
||||||
|
} else {
|
||||||
|
console.log('report playfailed failed');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('this.playfailed_url not defined', this.playfailed_url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setValue(data){
|
||||||
|
this.user_data = data;
|
||||||
|
this.title_w.set_text(data.tv_name);
|
||||||
|
this.video.set_url(data.url);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
bricks.Factory.register('Video', bricks.Video);
|
bricks.Factory.register('Video', bricks.Video);
|
||||||
|
bricks.Factory.register('Iptv', bricks.Iptv);
|
||||||
|
73
bricks/webspeech.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
var bricks = window.bricks || {};
|
||||||
|
|
||||||
|
bricks.WebTTS = class extends bricks.VBox {
|
||||||
|
constructor(opts){
|
||||||
|
super(opts);
|
||||||
|
}
|
||||||
|
speak(text){
|
||||||
|
// 检查浏览器是否支持SpeechSynthesis
|
||||||
|
if ('speechSynthesis' in window) {
|
||||||
|
var utterance = new SpeechSynthesisUtterance(text);
|
||||||
|
// 设置语音属性,例如语言
|
||||||
|
utterance.lang = bricks.app.lang;
|
||||||
|
utterance.pitch = 1;
|
||||||
|
utterance.rate = 1;
|
||||||
|
utterance.onstart = function(event) {
|
||||||
|
console.log('语音合成开始');
|
||||||
|
};
|
||||||
|
// 当语音合成结束时触发
|
||||||
|
utterance.onend = function(event) {
|
||||||
|
console.log('语音合成结束');
|
||||||
|
};
|
||||||
|
// 当语音合成出错时触发
|
||||||
|
utterance.onerror = function(event) {
|
||||||
|
console.error('语音合成出错:', event.error);
|
||||||
|
};
|
||||||
|
// 将utterance添加到语音合成队列
|
||||||
|
window.speechSynthesis.speak(utterance);
|
||||||
|
} else {
|
||||||
|
console.error('浏览器不支持SpeechSynthesis');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.WebASR = class extends bricks.VBox {
|
||||||
|
constructor(opts){
|
||||||
|
super(opts);
|
||||||
|
this.reognition = None;
|
||||||
|
}
|
||||||
|
start_recording(){
|
||||||
|
// 检查浏览器是否支持SpeechRecognition
|
||||||
|
if ('SpeechRecognition' in window) {
|
||||||
|
// 创建SpeechRecognition实例
|
||||||
|
this.recognition = new SpeechRecognition();
|
||||||
|
// 处理识别错误
|
||||||
|
this.recognition.onerror = function(event) {
|
||||||
|
console.error('识别错误:', event.error);
|
||||||
|
};
|
||||||
|
// 处理语音识别结束事件
|
||||||
|
this.recognition.onend = function() {
|
||||||
|
console.log('语音识别已结束');
|
||||||
|
};
|
||||||
|
// 处理识别结果
|
||||||
|
this.recognition.onresult = function(event) {
|
||||||
|
var transcript = event.results[0][0].transcript;
|
||||||
|
this.dispatch('asr_result', {
|
||||||
|
content:transcript
|
||||||
|
});
|
||||||
|
console.log('识别结果:', transcript);
|
||||||
|
};
|
||||||
|
this.recognition.lang = bricks.app.lang;
|
||||||
|
this.recognition.start();
|
||||||
|
} else {
|
||||||
|
console.log('browser has not SpeechRecognition');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stop_recording(){
|
||||||
|
this.recognition.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bricks.Factory.register('WebTTS', bricks.WebTTS);
|
||||||
|
bricks.Factory.register('WebASR', bricks.WebASR);
|
||||||
|
|
91
bricks/widget.js
Executable file → Normal file
@ -15,6 +15,13 @@ bricks.resize_observer = new ResizeObserver(entries => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
bricks.JsWidget = class {
|
bricks.JsWidget = class {
|
||||||
|
/*
|
||||||
|
popup:{
|
||||||
|
popup_event:
|
||||||
|
popup_desc:
|
||||||
|
popupwindow:false or true
|
||||||
|
}
|
||||||
|
*/
|
||||||
constructor(options){
|
constructor(options){
|
||||||
if (!options){
|
if (!options){
|
||||||
options = {}
|
options = {}
|
||||||
@ -38,9 +45,36 @@ bricks.JsWidget = class {
|
|||||||
var w = bricks.app.tooltip;
|
var w = bricks.app.tooltip;
|
||||||
this.bind('mousemove', w.show.bind(w, this.opts.tip));
|
this.bind('mousemove', w.show.bind(w, this.opts.tip));
|
||||||
this.bind('mouseout', w.hide.bind(w));
|
this.bind('mouseout', w.hide.bind(w));
|
||||||
|
this.bind('click', w.hide.bind(w));
|
||||||
|
}
|
||||||
|
if (this.popup){
|
||||||
|
this.bind(this.popup.popup_event, this.popup_action.bind(this));
|
||||||
}
|
}
|
||||||
bricks.resize_observer.observe(this.dom_element);
|
bricks.resize_observer.observe(this.dom_element);
|
||||||
}
|
}
|
||||||
|
destroy_popup(){
|
||||||
|
this.popup_widget.destroy();
|
||||||
|
this.popup_widget = null;
|
||||||
|
}
|
||||||
|
async popup_action(){
|
||||||
|
if (this.popup_widget){
|
||||||
|
this.popup_widget.destroy();
|
||||||
|
this.popup_widget = null;
|
||||||
|
} else {
|
||||||
|
if (this.popup.popupwindow){
|
||||||
|
this.popup_widget = new bricks.PopupWindow(this.popup.optiosn);
|
||||||
|
} else {
|
||||||
|
this.popup_widget = new bricks.Popup(this.popup.options);
|
||||||
|
}
|
||||||
|
this.popup_widget.bind('dismissed', this.destroy_popup.bind(this));
|
||||||
|
var w = await bricks.widgetBuild(this.popup.popup_desc, this, this.user_data);
|
||||||
|
if (w){
|
||||||
|
this.popup_widget.add_widget(w);
|
||||||
|
this.popup_widget.open();
|
||||||
|
this.popup_widget.popup_from_widget(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
showRectage(){
|
showRectage(){
|
||||||
return this.dom_element.getBoundingClientRect();
|
return this.dom_element.getBoundingClientRect();
|
||||||
}
|
}
|
||||||
@ -65,8 +99,10 @@ bricks.JsWidget = class {
|
|||||||
disabled(flag){
|
disabled(flag){
|
||||||
if(flag){
|
if(flag){
|
||||||
this.dom_element.disabled = true;
|
this.dom_element.disabled = true;
|
||||||
|
this.set_style('pointerEvents', 'none');
|
||||||
} else {
|
} else {
|
||||||
this.dom_element.disabled = false;
|
this.dom_element.disabled = false;
|
||||||
|
this.set_style('pointerEvents', 'auto');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
opts_set_style(){
|
opts_set_style(){
|
||||||
@ -153,6 +189,23 @@ bricks.JsWidget = class {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
enter_fullscreen(){
|
||||||
|
var e = this.dom_element;
|
||||||
|
// 获取要全屏显示的元素
|
||||||
|
// 检查浏览器是否支持Fullscreen API
|
||||||
|
if (e.requestFullscreen) {
|
||||||
|
e.requestFullscreen();
|
||||||
|
} else if (e.mozRequestFullScreen) { // Firefox
|
||||||
|
e.mozRequestFullScreen();
|
||||||
|
} else if (e.webkitRequestFullscreen) { // Chrome, Safari and Opera
|
||||||
|
e.webkitRequestFullscreen();
|
||||||
|
} else if (e.msRequestFullscreen) { // IE/Edge
|
||||||
|
e.msRequestFullscreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exit_fullscreen(){
|
||||||
|
document.exitFullscreen();
|
||||||
|
}
|
||||||
h_center(){
|
h_center(){
|
||||||
this.dom_element.style.marginLeft = 'auto';
|
this.dom_element.style.marginLeft = 'auto';
|
||||||
this.dom_element.style.marginRight = 'auto';
|
this.dom_element.style.marginRight = 'auto';
|
||||||
@ -458,36 +511,22 @@ bricks.Tooltip = class extends bricks.Text {
|
|||||||
this.set_otext(otext);
|
this.set_otext(otext);
|
||||||
this.set_style('zIndex', 999999999);
|
this.set_style('zIndex', 999999999);
|
||||||
this.set_style('display', 'block');
|
this.set_style('display', 'block');
|
||||||
var ex,ey;
|
bricks.relocate_by_eventpos(event, this);
|
||||||
var x,y;
|
|
||||||
var xsize = bricks.Body.dom_element.clientWidth;
|
|
||||||
var ysize = bricks.Body.dom_element.clientHeight;
|
|
||||||
ex = event.clientX;
|
|
||||||
ey = event.clientY;
|
|
||||||
var mxs = this.dom_element.offsetWidth;
|
|
||||||
var mys = this.dom_element.offsetHeight;
|
|
||||||
if (ex < (xsize / 2)) {
|
|
||||||
x = ex + bricks.app.charsize;
|
|
||||||
} else {
|
|
||||||
x = ex - mxs - bricks.app.charsize;
|
|
||||||
}
|
|
||||||
if (ey < (ysize / 2)) {
|
|
||||||
y = ey + bricks.app.charsize;
|
|
||||||
} else {
|
|
||||||
y = ey - mys - bricks.app.charsize;
|
|
||||||
}
|
|
||||||
this.set_style('left', x + 'px');
|
|
||||||
this.set_style('top', y + 'px');
|
|
||||||
if (this.auto_task){
|
|
||||||
this.auto_task.cancel();
|
|
||||||
}
|
|
||||||
this.auto_task = schedule_once(this.hide.bind(this), 30);
|
|
||||||
}
|
|
||||||
hide(){
|
|
||||||
if (this.auto_task){
|
if (this.auto_task){
|
||||||
this.auto_task.cancel();
|
this.auto_task.cancel();
|
||||||
this.auto_task = null;
|
this.auto_task = null;
|
||||||
}
|
}
|
||||||
|
this.auto_task = schedule_once(this.hide.bind(this), 6);
|
||||||
|
}
|
||||||
|
hide(){
|
||||||
|
try {
|
||||||
|
if (this.auto_task){
|
||||||
|
this.auto_task.cancel();
|
||||||
|
this.auto_task = null;
|
||||||
|
}
|
||||||
|
} catch(e){
|
||||||
|
console.log('Exception:', e);
|
||||||
|
}
|
||||||
this.set_style('display', 'none');
|
this.set_style('display', 'none');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,29 +6,58 @@ bricks.Wterm = class extends bricks.JsWidget {
|
|||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
ws_url:
|
ws_url:
|
||||||
host:
|
ping_timeout:19
|
||||||
ssh_port:
|
|
||||||
user:
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
constructor(opts){
|
constructor(opts){
|
||||||
super(opts);
|
super(opts);
|
||||||
|
this.socket = null;
|
||||||
|
this.ping_timeout = opts.ping_timeout || 19;
|
||||||
schedule_once(this.open.bind(this), 0.5);
|
schedule_once(this.open.bind(this), 0.5);
|
||||||
}
|
}
|
||||||
|
charsize_sizing(){
|
||||||
|
var cs = bricks.app.charsize;
|
||||||
|
this.term.setOption('fontSize', cs);
|
||||||
|
}
|
||||||
|
heartbeat(){
|
||||||
|
if (this.socket.readyState != 1) return;
|
||||||
|
this.socket.send('_#_heartbeat_#_');
|
||||||
|
this.heartbeat_task = schedule_once(this.heartbeat.bind(this),
|
||||||
|
this.ping_timeout);
|
||||||
|
}
|
||||||
async open(){
|
async open(){
|
||||||
var term = new Terminal();
|
var term_options = this.term_options || {};
|
||||||
|
var term = new Terminal(term_options);
|
||||||
this.term = term;
|
this.term = term;
|
||||||
term.open(this.dom_element);
|
term.open(this.dom_element);
|
||||||
var ws = new WebSocket(this.opts.ws_url);
|
var ws = new WebSocket(this.opts.ws_url);
|
||||||
bricks.debug('FitAddon=', FitAddon);
|
this.socket = ws;
|
||||||
|
|
||||||
this.fitAddon = new FitAddon.FitAddon()
|
this.fitAddon = new FitAddon.FitAddon()
|
||||||
term.loadAddon(this.fitAddon)
|
term.loadAddon(this.fitAddon)
|
||||||
// this.fitAddon.fit()
|
this.fitAddon.fit();
|
||||||
|
this.charsize_sizing();
|
||||||
this.bind('resize', this.term_resize.bind(this))
|
this.bind('resize', this.term_resize.bind(this))
|
||||||
ws.onmessage = msg => {
|
ws.onmessage = event => {
|
||||||
term.write(JSON.parse(msg.data).data);
|
var msg = JSON.parse(event.data);
|
||||||
|
console.log('ws msg=', msg);
|
||||||
|
if (msg.data == '_#_heartbeat_#_'){
|
||||||
|
console.log('connection alive');
|
||||||
|
} else {
|
||||||
|
term.write(msg.data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ws.onclose = (event) => {
|
||||||
|
console.log('websocket closed:', event.code, '--', event.reason);
|
||||||
|
if (this.heartbeat_task) {
|
||||||
|
this.heartbeat_task.cancel();
|
||||||
|
this.heartbeat_task = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ws.onopen = () => {
|
||||||
|
this.heartbeat_task = schedule_once(this.heartbeat.bind(this),
|
||||||
|
this.ping_timeout);
|
||||||
};
|
};
|
||||||
|
|
||||||
term.onData(function(key) {
|
term.onData(function(key) {
|
||||||
//Enter
|
//Enter
|
||||||
let msg = {
|
let msg = {
|
||||||
@ -38,13 +67,12 @@ bricks.Wterm = class extends bricks.JsWidget {
|
|||||||
ws.send(key);
|
ws.send(key);
|
||||||
});
|
});
|
||||||
term.focus();
|
term.focus();
|
||||||
term.paste("ls -l\n");
|
|
||||||
}
|
}
|
||||||
term_resize(){
|
term_resize(){
|
||||||
try {
|
try {
|
||||||
this.fitAddon.fit();
|
this.fitAddon.fit();
|
||||||
} catch(e){
|
} catch(e){
|
||||||
bricks.debug('resize error', e);
|
console.log('resize error', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
docs/.DS_Store
vendored
@ -39,6 +39,14 @@ bricks的事件处理是在控件描述文件的binds区域中添加事件处理
|
|||||||
### dataparams
|
### dataparams
|
||||||
获取动态参数时需给定的参数, 可选,对象类型,k,v形式给定参数
|
获取动态参数时需给定的参数, 可选,对象类型,k,v形式给定参数
|
||||||
|
|
||||||
|
### popup_options
|
||||||
|
当target为“Popup“或“PopupWindow”时,定义Popup或PopupWindow的参数
|
||||||
|
|
||||||
|
#### dismiss_events
|
||||||
|
字符串数组,每个字符串定义一个Popup, PopupWindow的子控件的事件,这些事件发生时将导致Popup, PopupWindow关闭
|
||||||
|
|
||||||
|
#### eventpos
|
||||||
|
Popup, PopupWindow窗体移动到鼠标位置
|
||||||
|
|
||||||
### 获取动态参数说明
|
### 获取动态参数说明
|
||||||
绑定任务获取实时数据作为参数,需要给定以下属性:
|
绑定任务获取实时数据作为参数,需要给定以下属性:
|
||||||
@ -50,7 +58,15 @@ bricks的事件处理是在控件描述文件的binds区域中添加事件处理
|
|||||||
datamethod 优先datascript,从datawidget控件中通过datamethod
|
datamethod 优先datascript,从datawidget控件中通过datamethod
|
||||||
|
|
||||||
### target
|
### target
|
||||||
字符串或控件实例,目标控件实例,如果是字符串,使用”getWidgetById“函数获得目标控件实例,关于target规则请查看[控件id](widgetid.md)
|
支持一下形式的target定义:
|
||||||
|
* 目标控件实例对象
|
||||||
|
* 字符串,且等于“Popup“
|
||||||
|
* 字符串,且等于”PopupWindow“
|
||||||
|
* 其他字符串(控件对象的id)
|
||||||
|
当actiontype为"urlwidget"时,target应该是一个容器控件,所生成的控件将插入或替代到“target”所代表的对象中,如果actiontype是其他类型,则在此对象中执行方法,脚本,定义函数,或定义事件
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### conform
|
### conform
|
||||||
如果一个事件处理需要用户确认,可以在事件处理中指定一个conform属性来引发,当此事件发生时,会弹出一个确认窗口,用户确认后才会处理此事件,否则不处理
|
如果一个事件处理需要用户确认,可以在事件处理中指定一个conform属性来引发,当此事件发生时,会弹出一个确认窗口,用户确认后才会处理此事件,否则不处理
|
||||||
|
6
examples/alipay_recharge.ui
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"VBox",
|
||||||
|
"options":{
|
||||||
|
"height":"100%"
|
||||||
|
}
|
||||||
|
}
|
14
examples/asr.ui
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"ASRClient",
|
||||||
|
"options":
|
||||||
|
{
|
||||||
|
"ws_url":"{{entire_url('/wss/ws/test.ws')}}?userid={{get_user()}}",
|
||||||
|
"icon_options":{
|
||||||
|
"rate":3
|
||||||
|
},
|
||||||
|
"ws_params":{
|
||||||
|
"kkk":1,
|
||||||
|
"brade":"123"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
examples/camera.ui
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"HBox",
|
||||||
|
"options":{
|
||||||
|
"widht":"100%",
|
||||||
|
"height":"100%"
|
||||||
|
},
|
||||||
|
"subwidgets":[
|
||||||
|
{
|
||||||
|
"widgettype":"Camera",
|
||||||
|
"options":{
|
||||||
|
"width":"50%",
|
||||||
|
"height":"90%",
|
||||||
|
"archor":"cl",
|
||||||
|
"auto_open":true,
|
||||||
|
"fps":60
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype":"Camera",
|
||||||
|
"options":{
|
||||||
|
"width":"50%",
|
||||||
|
"height":"90%",
|
||||||
|
"archor":"cr",
|
||||||
|
"auto_open":true,
|
||||||
|
"fps":30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
36
examples/recharge.ui
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"IconbarPage",
|
||||||
|
"options":{
|
||||||
|
"bar_at":"top",
|
||||||
|
"bar_opts":{
|
||||||
|
"margin":"10px",
|
||||||
|
"rate":1.6,
|
||||||
|
"tools":[
|
||||||
|
{
|
||||||
|
"name":"wechat",
|
||||||
|
"icon":"{{entire_url('/imgs/weixinzhifu.png')}}",
|
||||||
|
"label":"微信充值",
|
||||||
|
"tip":"使用微信为账户充值",
|
||||||
|
"content":{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('wechat_recharge.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"alipay",
|
||||||
|
"icon":"{{entire_url('/imgs/zhifubao.png')}}",
|
||||||
|
"label":"支付宝充值",
|
||||||
|
"tip":"使用支付宝为账户充值",
|
||||||
|
"content":{
|
||||||
|
"widgettype":"urlwidget",
|
||||||
|
"options":{
|
||||||
|
"url":"{{entire_url('alipay_recharge.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
examples/wechat_recharge.ui
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"widgettype":"VBox",
|
||||||
|
"options":{
|
||||||
|
"height":"100%"
|
||||||
|
}
|
||||||
|
}
|