diff --git a/bricks/camera.js b/bricks/camera.js index 90c09eb..c4820d1 100644 --- a/bricks/camera.js +++ b/bricks/camera.js @@ -52,6 +52,10 @@ bricks.Camera = class extends bricks.Popup { this.task = schedule_once(this.show_picture.bind(this), this.task_period); } take_picture(){ + if (this.task){ + task.cancel(); + } + this.task = null; var d = this.imgw.base64(); this.dispatch('shot', d); // Create a blob from the canvas data URL diff --git a/bricks/docxviewer.js b/bricks/docxviewer.js new file mode 100644 index 0000000..d990187 --- /dev/null +++ b/bricks/docxviewer.js @@ -0,0 +1,119 @@ +/* need mammoth module + +*/ +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) { + // 正则表达式匹配和之间的内容 + const regex = /]*>([\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); diff --git a/bricks/input.js b/bricks/input.js index 05b00f7..2cbf42e 100644 --- a/bricks/input.js +++ b/bricks/input.js @@ -372,16 +372,17 @@ bricks.UiImage =class extends bricks.VBox { "height":"90%", "width":"90%" }); - camera.bind('shot', function(d){ - if (this.imgw){ - this.remove_widget(this.imgw); - } - this.imgw = new bricks.Image({ - url:d, - width:'100%' - }); - this.add_widget(this.imgw); + camera.bind('shot', this.accept_photo.bind(this)); + } + accept_photo(url){ + if (this.imgw){ + this.remove_widget(this.imgw); + } + this.imgw = new bricks.Image({ + url:url, + width:'100%' }); + this.add_widget(this.imgw); } handleFileSelect(event){ const file = event.target.files[0]; diff --git a/bricks/period.js b/bricks/period.js new file mode 100644 index 0000000..3c00802 --- /dev/null +++ b/bricks/period.js @@ -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);