@heycys/gallery 0.1.2 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD-PARTY-NOTICES.md +2 -2
- package/browser/editor/components/align.mjs +58 -0
- package/browser/editor/components/code/index.mjs +1 -1
- package/browser/editor/components/embed/page.mjs +1 -1
- package/browser/editor/components/file/page.mjs +4 -4
- package/browser/editor/components/heading/index.mjs +7 -6
- package/browser/editor/components/icon/page.mjs +6 -4
- package/browser/editor/components/icons.mjs +5 -2
- package/browser/editor/components/image/index.mjs +2 -0
- package/browser/editor/components/image/page.mjs +172 -90
- package/browser/editor/components/installed/index.mjs +6 -2
- package/browser/editor/components/installed/page.mjs +80 -13
- package/browser/editor/components/media/icons.mjs +13 -8
- package/browser/editor/components/media/page.mjs +5 -3
- package/browser/editor/components/media/toolbar.mjs +12 -3
- package/browser/editor/components/paragraph/index.mjs +4 -3
- package/browser/editor/components/registry.mjs +17 -5
- package/browser/editor/components/table/index.mjs +4 -2
- package/browser/editor/page/after/index.mjs +288 -0
- package/browser/editor/page/align.mjs +91 -0
- package/browser/editor/page/beside.mjs +5 -6
- package/browser/editor/page/block-menu/index.mjs +6 -3
- package/browser/editor/page/blocks.mjs +3 -1
- package/browser/editor/page/board/hint.mjs +64 -27
- package/browser/editor/page/board/index.mjs +160 -71
- package/browser/editor/page/board/motion.mjs +177 -0
- package/browser/editor/page/board/settings.mjs +4 -3
- package/browser/editor/page/clipboard/import/read.mjs +20 -2
- package/browser/editor/page/clipboard/index.mjs +10 -3
- package/browser/editor/page/clipboard/own/blocks.mjs +3 -4
- package/browser/editor/page/clipboard/own/describe.mjs +6 -2
- package/browser/editor/page/commit.mjs +2 -2
- package/browser/editor/page/core.mjs +3 -1
- package/browser/editor/page/custom-page.mjs +15 -11
- package/browser/editor/page/editor.mjs +31 -14
- package/browser/editor/page/history.mjs +19 -4
- package/browser/editor/page/insert/index.mjs +20 -22
- package/browser/editor/page/menu.mjs +15 -7
- package/browser/editor/page/page-objects.mjs +3 -7
- package/browser/editor/page/present-links.mjs +5 -4
- package/browser/editor/page/present-shell.mjs +63 -0
- package/browser/editor/page/selection/index.mjs +10 -2
- package/browser/editor/page/table/binding.mjs +87 -0
- package/browser/editor/page/table/icons.mjs +0 -2
- package/browser/editor/page/table/index.mjs +10 -14
- package/browser/editor/page/table/views.mjs +5 -52
- package/browser/editor/page/table/widths.mjs +82 -10
- package/browser/editor/page/typing/index.mjs +44 -12
- package/browser/editor/page/typing/leave.mjs +19 -5
- package/browser/shared/block-packs.mjs +23 -8
- package/browser/shared/component-catalog.mjs +15 -8
- package/browser/shared/component-source.mjs +3 -1
- package/browser/shared/components/heading.mjs +2 -1
- package/browser/shared/components/installed.mjs +1 -1
- package/browser/shared/components/page.mjs +2 -0
- package/browser/shared/components/paragraph.mjs +8 -1
- package/browser/shared/components/table.mjs +1 -0
- package/browser/shared/document-copy.mjs +43 -0
- package/browser/shared/drafts.mjs +10 -3
- package/browser/shared/emoji/icon-value.mjs +2 -2
- package/browser/shared/emoji/line-icons.mjs +37 -0
- package/browser/shared/extensions.mjs +83 -7
- package/browser/shared/http.mjs +9 -0
- package/browser/shared/i18n/en.mjs +50 -17
- package/browser/shared/outline-shape.mjs +6 -0
- package/browser/shared/outline.mjs +165 -12
- package/browser/shared/pack-manifest.mjs +12 -1
- package/browser/shared/pages.mjs +169 -57
- package/browser/shared/pinyin.mjs +92 -0
- package/browser/shared/present-step.mjs +17 -0
- package/browser/shared/sidebar-head.mjs +70 -0
- package/browser/shared/web-links.mjs +5 -0
- package/browser/shared/workspace-columns.mjs +11 -7
- package/dist/{chunk-N7AZZLGT.mjs → chunk-2GKGEVMR.mjs} +29 -24
- package/dist/chunk-2OHANJ6Q.mjs +2 -0
- package/dist/{chunk-HYMEEXKN.mjs → chunk-2RKIHJI2.mjs} +1 -1
- package/dist/{chunk-742D2WWJ.mjs → chunk-36FIRJIF.mjs} +2 -2
- package/dist/{chunk-BPL64HGA.mjs → chunk-3A5I2GJK.mjs} +1 -1
- package/dist/{chunk-RFDZXFJF.mjs → chunk-3OFXMN6N.mjs} +1 -1
- package/dist/chunk-46ACXOU5.mjs +2 -0
- package/dist/{chunk-PUOQ65NC.mjs → chunk-4AMTKWDO.mjs} +1 -1
- package/dist/{chunk-VTKNEYT3.mjs → chunk-4DNHHJSL.mjs} +1 -1
- package/dist/chunk-5DPABPBI.mjs +2 -0
- package/dist/chunk-5IIH335D.mjs +3 -0
- package/dist/chunk-5L26JUYA.mjs +2 -0
- package/dist/{chunk-3NJACR4W.mjs → chunk-5MEXZ2UF.mjs} +1 -1
- package/dist/{chunk-ZHEHPMBK.mjs → chunk-6MPKCH3P.mjs} +1 -1
- package/dist/{chunk-C564NU2H.mjs → chunk-74RPP2M2.mjs} +1 -1
- package/dist/chunk-7M2BQQGZ.mjs +2 -0
- package/dist/{chunk-VXACTLO3.mjs → chunk-7M7UPWU6.mjs} +1 -1
- package/dist/{chunk-ZB4H7ZN4.mjs → chunk-7N2LPG33.mjs} +1 -1
- package/dist/{chunk-UBBRTJ2R.mjs → chunk-7XDYK3UC.mjs} +1 -1
- package/dist/chunk-AEMVZYZQ.mjs +166 -0
- package/dist/{chunk-POQSE4C2.mjs → chunk-AFGUR7SY.mjs} +1 -1
- package/dist/{chunk-QKXMPUXC.mjs → chunk-AMDGVDNV.mjs} +1 -1
- package/dist/{chunk-KTKHRC6H.mjs → chunk-ASAXY2DJ.mjs} +1 -1
- package/dist/{chunk-NVRNLK25.mjs → chunk-BYSF5UMM.mjs} +2 -2
- package/dist/{chunk-U3SSPL4K.mjs → chunk-CCSGFCLZ.mjs} +1 -1
- package/dist/{chunk-NWFBE2YA.mjs → chunk-CG3UHDKH.mjs} +1 -1
- package/dist/chunk-CPS4SRPF.mjs +5 -0
- package/dist/{chunk-B4P2CM2J.mjs → chunk-CZ5KJSGK.mjs} +1 -1
- package/dist/chunk-DAMVDXR3.mjs +2 -0
- package/dist/{chunk-NG375ILQ.mjs → chunk-DH6GMDNN.mjs} +1 -1
- package/dist/chunk-DHB7UZ7F.mjs +3 -0
- package/dist/{chunk-MHW7ZKOU.mjs → chunk-DKR7LFIY.mjs} +1 -1
- package/dist/chunk-DLFZJJEE.mjs +2 -0
- package/dist/{chunk-6EZ7FNIK.mjs → chunk-F4ZA6JRZ.mjs} +1 -1
- package/dist/{chunk-6VTU6KEO.mjs → chunk-FCK6NXON.mjs} +1 -1
- package/dist/{chunk-ZWPMCK7P.mjs → chunk-FX42XU6J.mjs} +1 -1
- package/dist/chunk-FXQBADMN.mjs +5 -0
- package/dist/{chunk-W3BGBJQW.mjs → chunk-G4YP7GVC.mjs} +1 -1
- package/dist/{chunk-V6XZ4VIR.mjs → chunk-GWOYMENX.mjs} +1 -1
- package/dist/chunk-HATA2W7X.mjs +2 -0
- package/dist/{chunk-YI43RG4P.mjs → chunk-HBAUKKQH.mjs} +1 -1
- package/dist/{chunk-MAFIGVXY.mjs → chunk-HM4E43VM.mjs} +1 -1
- package/dist/{chunk-CRJEG7MT.mjs → chunk-JI6T3A4Y.mjs} +1 -1
- package/dist/{chunk-NFMCP2HI.mjs → chunk-JJNRIFND.mjs} +2 -2
- package/dist/chunk-JL6R4FG4.mjs +4 -0
- package/dist/{chunk-UMHUSOPJ.mjs → chunk-JXLSHVJ2.mjs} +1 -1
- package/dist/{chunk-FJYN7RTH.mjs → chunk-KFZBYDIS.mjs} +1 -1
- package/dist/{chunk-ZTHICSSF.mjs → chunk-KH24LWAT.mjs} +1 -1
- package/dist/{chunk-RKPWLGZ3.mjs → chunk-KUILYI7H.mjs} +1 -1
- package/dist/{chunk-RMECZA2K.mjs → chunk-L7W624FD.mjs} +1 -1
- package/dist/chunk-LE44MD3O.mjs +4 -0
- package/dist/{chunk-4K5KC6V2.mjs → chunk-LV24RY2E.mjs} +1 -1
- package/dist/{chunk-43B75J5T.mjs → chunk-MKTX5PGV.mjs} +1 -1
- package/dist/{chunk-LKX55H76.mjs → chunk-NAGMRVW4.mjs} +1 -1
- package/dist/{chunk-D4CKRD3V.mjs → chunk-NFABH3QW.mjs} +2 -2
- package/dist/{chunk-PVER7LSC.mjs → chunk-NIW7F7LU.mjs} +2 -2
- package/dist/{chunk-PAREWQGB.mjs → chunk-NWRZXELO.mjs} +1 -1
- package/dist/{chunk-OJKMINIU.mjs → chunk-OU3S466R.mjs} +15 -15
- package/dist/{chunk-5ZJA7CXT.mjs → chunk-PAFSFVYB.mjs} +1 -1
- package/dist/chunk-QCEATQC4.mjs +2 -0
- package/dist/{chunk-Y34NR5JL.mjs → chunk-QJ3TFJLQ.mjs} +1 -1
- package/dist/{chunk-IA4PSIMD.mjs → chunk-QK3VISCA.mjs} +1 -1
- package/dist/{chunk-ZUNVAXLH.mjs → chunk-QXVNUASA.mjs} +1 -1
- package/dist/{chunk-GRAXKKG4.mjs → chunk-QZ35UAB4.mjs} +1 -1
- package/dist/{chunk-UGWYKHBL.mjs → chunk-S2Y7VI4H.mjs} +2 -2
- package/dist/{chunk-OW5NWPOJ.mjs → chunk-SAHS56QM.mjs} +1 -1
- package/dist/{chunk-QOUEFUCH.mjs → chunk-SOD23RGL.mjs} +1 -1
- package/dist/chunk-TDWJKOLN.mjs +2 -0
- package/dist/{chunk-V6RIYQZZ.mjs → chunk-TOE6DPLH.mjs} +1 -1
- package/dist/chunk-UGO5N3EI.mjs +15 -0
- package/dist/{chunk-Q47PLKIJ.mjs → chunk-UGWMMEJ5.mjs} +1 -1
- package/dist/{chunk-NWR2LT5B.mjs → chunk-V5JRSGZF.mjs} +1 -1
- package/dist/{chunk-BZ5RAF7L.mjs → chunk-VA3KAQZD.mjs} +1 -1
- package/dist/chunk-VG5JEIUQ.mjs +12 -0
- package/dist/{chunk-UNOYVIYR.mjs → chunk-VGTMLQWZ.mjs} +1 -1
- package/dist/chunk-VKSRM7EY.mjs +22 -0
- package/dist/{chunk-YQGT4AB2.mjs → chunk-VNUWREXU.mjs} +1 -1
- package/dist/{chunk-AGDILNWB.mjs → chunk-VPVOAJ7X.mjs} +1 -1
- package/dist/{chunk-HLYV7RIH.mjs → chunk-WCWYNFDF.mjs} +1 -1
- package/dist/chunk-WTEGUPFG.mjs +16 -0
- package/dist/{chunk-N76HWBA3.mjs → chunk-XKOHV4H6.mjs} +1 -1
- package/dist/{chunk-HMYTM3GT.mjs → chunk-XMKHCUI6.mjs} +1 -1
- package/dist/{chunk-OUUP3WKT.mjs → chunk-XQRUG4G3.mjs} +1 -1
- package/dist/{chunk-32ZUEFZ7.mjs → chunk-YBB5LWZK.mjs} +1 -1
- package/dist/{chunk-SX4LJYT6.mjs → chunk-YFJU3O7G.mjs} +1 -1
- package/dist/chunk-YPPJVDQI.mjs +2 -0
- package/dist/chunk-ZANMKAWS.mjs +2 -0
- package/dist/{chunk-6QBHU4DF.mjs → chunk-ZCP7BTOZ.mjs} +1 -1
- package/dist/{chunk-ERLAIBOA.mjs → chunk-ZEY2RLBT.mjs} +2 -2
- package/dist/{chunk-SQ6Y2ZMA.mjs → chunk-ZO7SFB2E.mjs} +2 -2
- package/dist/cli.mjs +1 -1
- package/dist/server.mjs +1 -1
- package/dist/worker.mjs +1 -1
- package/kit/board.css +5 -5
- package/kit/code.js +15 -15
- package/kit/math.js +1 -1
- package/kit/report.css +123 -44
- package/kit/runtime.js +45 -7
- package/kit/tables.js +2 -0
- package/kit/ui.js +2 -0
- package/package.json +1 -1
- package/packs/gallery/chart-view/kit.js +3 -3
- package/packs/gallery/chart-view/writing.md +1 -1
- package/packs/gallery/countdown/component.json +1 -1
- package/packs/gallery/countdown/kit.js +89 -29
- package/packs/gallery/countdown/preview.svg +1 -1
- package/packs/gallery/countdown/style.css +88 -100
- package/packs/gallery/countdown/writing.md +2 -2
- package/packs/gallery/habit/component.json +3 -3
- package/packs/gallery/habit/kit.js +114 -75
- package/packs/gallery/habit/preview.svg +1 -1
- package/packs/gallery/habit/style.css +133 -205
- package/packs/gallery/habit/writing.md +2 -2
- package/packs/gallery/heatmap/component.json +2 -2
- package/packs/gallery/heatmap/kit.js +335 -173
- package/packs/gallery/heatmap/preview.svg +1 -1
- package/packs/gallery/heatmap/style.css +158 -170
- package/packs/gallery/heatmap/writing.md +2 -2
- package/packs/gallery/kanban/kit.js +3 -3
- package/packs/gallery/kanban/writing.md +1 -1
- package/packs/gallery/metric/kit.js +3 -3
- package/packs/gallery/metric/writing.md +1 -1
- package/packs/gallery/note/component.json +3 -3
- package/packs/gallery/note/kit.js +40 -13
- package/packs/gallery/note/preview.svg +1 -1
- package/packs/gallery/note/style.css +51 -30
- package/packs/gallery/note/writing.md +2 -2
- package/packs/gallery/recent/component.json +2 -2
- package/packs/gallery/recent/kit.js +141 -86
- package/packs/gallery/recent/preview.svg +1 -1
- package/packs/gallery/recent/style.css +53 -126
- package/packs/gallery/recent/writing.md +2 -2
- package/packs/gallery/static/component.json +2 -2
- package/packs/gallery/static/preview.svg +1 -1
- package/packs/gallery/static/style.css +99 -66
- package/packs/gallery/static/writing.md +2 -2
- package/packs/gallery/stats/component.json +3 -3
- package/packs/gallery/stats/kit.js +253 -72
- package/packs/gallery/stats/preview.svg +1 -1
- package/packs/gallery/stats/style.css +64 -142
- package/packs/gallery/stats/writing.md +2 -2
- package/packs/gallery/today/component.json +2 -2
- package/packs/gallery/today/kit.js +62 -27
- package/packs/gallery/today/preview.svg +1 -1
- package/packs/gallery/today/style.css +101 -72
- package/packs/gallery/today/writing.md +2 -2
- package/packs/gallery/todos/component.json +1 -1
- package/packs/gallery/todos/kit.js +218 -71
- package/packs/gallery/todos/preview.svg +1 -1
- package/packs/gallery/todos/style.css +170 -223
- package/packs/gallery/todos/writing.md +1 -1
- package/packs/gallery/weather/component.json +2 -2
- package/packs/gallery/weather/kit.js +165 -90
- package/packs/gallery/weather/preview.svg +1 -1
- package/packs/gallery/weather/style.css +100 -218
- package/packs/gallery/weather/writing.md +1 -1
- package/packs/gallery-soft/countdown/component.json +18 -0
- package/packs/gallery-soft/countdown/example.html +3 -0
- package/packs/gallery-soft/countdown/kit.js +206 -0
- package/packs/gallery-soft/countdown/preview.svg +1 -0
- package/packs/gallery-soft/countdown/style.css +211 -0
- package/packs/gallery-soft/countdown/template.html +3 -0
- package/packs/gallery-soft/countdown/writing.md +24 -0
- package/packs/gallery-soft/habit/component.json +14 -0
- package/packs/gallery-soft/habit/example.html +3 -0
- package/packs/gallery-soft/habit/kit.js +366 -0
- package/packs/gallery-soft/habit/preview.svg +1 -0
- package/packs/gallery-soft/habit/style.css +251 -0
- package/packs/gallery-soft/habit/template.html +3 -0
- package/packs/gallery-soft/habit/writing.md +23 -0
- package/packs/gallery-soft/heatmap/component.json +18 -0
- package/packs/gallery-soft/heatmap/example.html +3 -0
- package/packs/gallery-soft/heatmap/kit.js +498 -0
- package/packs/gallery-soft/heatmap/preview.svg +1 -0
- package/packs/gallery-soft/heatmap/style.css +181 -0
- package/packs/gallery-soft/heatmap/template.html +3 -0
- package/packs/gallery-soft/heatmap/writing.md +23 -0
- package/packs/gallery-soft/note/component.json +14 -0
- package/packs/gallery-soft/note/example.html +3 -0
- package/packs/gallery-soft/note/kit.js +162 -0
- package/packs/gallery-soft/note/preview.svg +1 -0
- package/packs/gallery-soft/note/style.css +148 -0
- package/packs/gallery-soft/note/template.html +3 -0
- package/packs/gallery-soft/note/writing.md +20 -0
- package/packs/gallery-soft/recent/component.json +13 -0
- package/packs/gallery-soft/recent/example.html +1 -0
- package/packs/gallery-soft/recent/kit.js +335 -0
- package/packs/gallery-soft/recent/preview.svg +1 -0
- package/packs/gallery-soft/recent/style.css +160 -0
- package/packs/gallery-soft/recent/template.html +1 -0
- package/packs/gallery-soft/recent/writing.md +17 -0
- package/packs/gallery-soft/static/component.json +13 -0
- package/packs/gallery-soft/static/example.html +12 -0
- package/packs/gallery-soft/static/preview.svg +1 -0
- package/packs/gallery-soft/static/style.css +186 -0
- package/packs/gallery-soft/static/template.html +1 -0
- package/packs/gallery-soft/static/writing.md +20 -0
- package/packs/gallery-soft/stats/component.json +13 -0
- package/packs/gallery-soft/stats/example.html +1 -0
- package/packs/gallery-soft/stats/kit.js +341 -0
- package/packs/gallery-soft/stats/preview.svg +1 -0
- package/packs/gallery-soft/stats/style.css +119 -0
- package/packs/gallery-soft/stats/template.html +1 -0
- package/packs/gallery-soft/stats/writing.md +13 -0
- package/packs/gallery-soft/today/component.json +12 -0
- package/packs/gallery-soft/today/example.html +1 -0
- package/packs/gallery-soft/today/kit.js +222 -0
- package/packs/gallery-soft/today/preview.svg +1 -0
- package/packs/gallery-soft/today/style.css +178 -0
- package/packs/gallery-soft/today/template.html +1 -0
- package/packs/gallery-soft/today/writing.md +16 -0
- package/packs/gallery-soft/todos/component.json +19 -0
- package/packs/gallery-soft/todos/example.html +3 -0
- package/packs/gallery-soft/todos/kit.js +527 -0
- package/packs/gallery-soft/todos/preview.svg +1 -0
- package/packs/gallery-soft/todos/style.css +212 -0
- package/packs/gallery-soft/todos/template.html +3 -0
- package/packs/gallery-soft/todos/writing.md +32 -0
- package/packs/gallery-soft/weather/component.json +19 -0
- package/packs/gallery-soft/weather/example.html +3 -0
- package/packs/gallery-soft/weather/kit.js +411 -0
- package/packs/gallery-soft/weather/preview.svg +1 -0
- package/packs/gallery-soft/weather/style.css +185 -0
- package/packs/gallery-soft/weather/template.html +3 -0
- package/packs/gallery-soft/weather/writing.md +28 -0
- package/release.json +10 -10
- package/skill/SKILL.md +15 -14
- package/skill/references/building-blocks.md +4 -4
- package/skill/references/extensions.md +11 -7
- package/skill/references/pages-and-data.md +13 -9
- package/skill/references/writing-html.md +2 -0
- package/web/assets/index-BHC5ZOMh.js +15 -0
- package/web/assets/index-xP0uw3a0.css +1 -0
- package/web/index.html +2 -2
- package/dist/chunk-2NRBY6AJ.mjs +0 -2
- package/dist/chunk-35NQ4PLQ.mjs +0 -2
- package/dist/chunk-3KJHLHUO.mjs +0 -2
- package/dist/chunk-4AV456RQ.mjs +0 -2
- package/dist/chunk-5XYHDBJ5.mjs +0 -2
- package/dist/chunk-6A53MZYZ.mjs +0 -2
- package/dist/chunk-6EXH3ORZ.mjs +0 -166
- package/dist/chunk-BVEFGE4B.mjs +0 -2
- package/dist/chunk-D4EURAX4.mjs +0 -4
- package/dist/chunk-DQCE7TJY.mjs +0 -5
- package/dist/chunk-FWNRPMCJ.mjs +0 -12
- package/dist/chunk-FWW4CSAZ.mjs +0 -2
- package/dist/chunk-GY3FAUVM.mjs +0 -2
- package/dist/chunk-JVHHHGEA.mjs +0 -3
- package/dist/chunk-L7UP52JO.mjs +0 -2
- package/dist/chunk-NAMN3RAF.mjs +0 -2
- package/dist/chunk-PZDLJJTJ.mjs +0 -3
- package/dist/chunk-SXHBYZST.mjs +0 -16
- package/dist/chunk-TEZAWDSQ.mjs +0 -2
- package/dist/chunk-UFNYFFKO.mjs +0 -20
- package/dist/chunk-UKSHDZZ6.mjs +0 -2
- package/dist/chunk-VJPFVNNW.mjs +0 -15
- package/dist/chunk-VS3ZMVGX.mjs +0 -5
- package/web/assets/index-BK2e_07w.js +0 -13
- package/web/assets/index-CWFI83mF.css +0 -1
- /package/dist/{chunk-YEY3RSFQ.mjs → chunk-5MMN3N5J.mjs} +0 -0
- /package/dist/{chunk-UH4SIXTR.mjs → chunk-74UW7QSL.mjs} +0 -0
- /package/dist/{chunk-W7XHE4CT.mjs → chunk-EKGYYOSP.mjs} +0 -0
- /package/dist/{chunk-QAIHRH3I.mjs → chunk-KNZJT4ET.mjs} +0 -0
- /package/dist/{chunk-A55HN5OK.mjs → chunk-N3DSBH5S.mjs} +0 -0
- /package/dist/{chunk-QR6A54KJ.mjs → chunk-ZW2A6GBW.mjs} +0 -0
|
@@ -1,42 +1,70 @@
|
|
|
1
|
-
// gallery/stats (工作区统计): four numbers of the workspace,
|
|
2
|
-
// (its manifest's needs hold "workspace"):
|
|
3
|
-
// documents
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
// the
|
|
1
|
+
// gallery/stats (工作区统计): four numbers of the workspace, each over a small picture of itself, read
|
|
2
|
+
// through context.workspace.query("stats") and query("activity") (its manifest's needs hold "workspace"):
|
|
3
|
+
// its documents (a square a document, those edited this week, since Monday 0:00, in the accent), the
|
|
4
|
+
// words of all its documents (and, from the record of edits, how they grew over the last 30 days: a line
|
|
5
|
+
// of the total at the end of each day, and the words added in all), its to-dos done of all (a bar), and
|
|
6
|
+
// the edits made this week (the record's, the reader's and the Agent's: a bar a day, Monday to Sunday,
|
|
7
|
+
// today's in the accent, the days to come a stub; and against the same days of the week before, 比上周同期
|
|
8
|
+
// +14%). A workspace with none of them shows each 0 and says what each waits for. It reads again whenever
|
|
9
|
+
// the workspace says they changed (the `data` signal, "stats" or "activity": a document written, a to-do
|
|
10
|
+
// checked, a document made or gone) and as a day begins (the kit's clock: a new week starts on a Monday).
|
|
11
|
+
// It holds no part and writes nothing: all it shows is drawn (the manifest's `runtime`). Where the
|
|
12
|
+
// workspace cannot be read (an exported file, where it has no server; a server that does not answer) each
|
|
13
|
+
// number is a dash and a line says why. The words are the page's language (the UI's where Gallery says
|
|
14
|
+
// it, else the page's lang); a big number of words is said short (12.4万, 124K).
|
|
15
|
+
//
|
|
16
|
+
// Its face (the pack's design B, in the kit's card tokens) has no head: the four labels, each after a
|
|
17
|
+
// small picture of what it counts, are its titles; four cells in a row a hairline apart (an 8 × 2 card,
|
|
18
|
+
// the default, and a 12 × 2 one, `data-layout` "row" and "wide", by context.size), or two by two (a 4 × 4
|
|
19
|
+
// card, "square"), each its label, its number (28px, 32px on a wide card), its picture and a faint line
|
|
20
|
+
// under it.
|
|
14
21
|
|
|
15
22
|
const WORDS = {
|
|
16
23
|
zh: {
|
|
17
|
-
title: "工作区统计",
|
|
18
24
|
documents: "文档",
|
|
19
|
-
todos: "待办完成",
|
|
20
25
|
words: "总字数",
|
|
26
|
+
todos: "待办完成",
|
|
21
27
|
week: "本周编辑",
|
|
22
28
|
pieces: "篇",
|
|
29
|
+
times: "次",
|
|
30
|
+
wordUnit: "字",
|
|
31
|
+
tenThousand: "万字",
|
|
32
|
+
editedWeek: (/** @type {number} */ count) => ["", String(count), " 篇本周改过"],
|
|
33
|
+
month: (/** @type {string} */ added) => ["近 30 天 ", added, ""],
|
|
34
|
+
left: (/** @type {number} */ percent, /** @type {number} */ open) => [`${percent}%`, ` · 还剩 ${open} 项`],
|
|
35
|
+
allDone: "全部完成",
|
|
36
|
+
against: (/** @type {string} */ delta) => ["比上周同期 ", delta, ""],
|
|
37
|
+
lastNone: "上周同期没有编辑",
|
|
38
|
+
zero: { documents: "新建一篇就从这里开始", todos: "还没有待办", week: "这周还没动过" },
|
|
23
39
|
offline: "在 Gallery 里打开时显示",
|
|
24
40
|
failed: "读不到工作区的统计",
|
|
25
41
|
locale: "zh-CN",
|
|
26
42
|
},
|
|
27
43
|
en: {
|
|
28
|
-
title: "Workspace",
|
|
29
44
|
documents: "Documents",
|
|
30
|
-
todos: "To-dos done",
|
|
31
45
|
words: "Words",
|
|
32
|
-
|
|
46
|
+
todos: "To-dos done",
|
|
47
|
+
week: "Edits this week",
|
|
33
48
|
pieces: "",
|
|
49
|
+
times: "",
|
|
50
|
+
wordUnit: "",
|
|
51
|
+
tenThousand: "",
|
|
52
|
+
editedWeek: (/** @type {number} */ count) => ["", String(count), " edited this week"],
|
|
53
|
+
month: (/** @type {string} */ added) => ["", added, " in 30 days"],
|
|
54
|
+
left: (/** @type {number} */ percent, /** @type {number} */ open) => [`${percent}%`, ` · ${open} left`],
|
|
55
|
+
allDone: "All done",
|
|
56
|
+
against: (/** @type {string} */ delta) => ["", delta, " on last week"],
|
|
57
|
+
lastNone: "None this time last week",
|
|
58
|
+
zero: { documents: "Make one to start", todos: "No to-dos yet", week: "Nothing yet this week" },
|
|
34
59
|
offline: "Shown when opened in Gallery",
|
|
35
60
|
failed: "The workspace's numbers could not be read",
|
|
36
61
|
locale: "en",
|
|
37
62
|
},
|
|
38
63
|
};
|
|
39
64
|
|
|
65
|
+
/** The days of the record it reads: 30 for the words, and this week and the one before for the edits. */
|
|
66
|
+
const DAYS = 37;
|
|
67
|
+
|
|
40
68
|
/** The language the page speaks: the UI's where Gallery says it (data-ge-language), else its lang's. */
|
|
41
69
|
function languageOf(/** @type {HTMLElement} */ root) {
|
|
42
70
|
const ui = root.getAttribute("data-ge-language");
|
|
@@ -54,23 +82,159 @@ function countOf(value, language) {
|
|
|
54
82
|
return new Intl.NumberFormat(WORDS[language].locale, big ? { notation: "compact", maximumFractionDigits: 1 } : { maximumFractionDigits: 0 }).format(value);
|
|
55
83
|
}
|
|
56
84
|
|
|
85
|
+
/**
|
|
86
|
+
* The words of the workspace as the card's number says them: { value, unit }: in Chinese 万字 from
|
|
87
|
+
* 10,000 (12.4 万字), else 字; in English 12.4K from 10,000.
|
|
88
|
+
* @param {number} words
|
|
89
|
+
* @param {"zh" | "en"} language
|
|
90
|
+
*/
|
|
91
|
+
function wordsOf(words, language) {
|
|
92
|
+
const said = WORDS[language];
|
|
93
|
+
if (Math.abs(words) < 10_000) return { value: countOf(words, language), unit: said.wordUnit };
|
|
94
|
+
if (language === "zh") return { value: (words / 10_000).toFixed(1), unit: said.tenThousand };
|
|
95
|
+
return { value: `${(words / 1000).toFixed(1)}K`, unit: "" };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** A change of words, signed and short (+6万, +5,432, −120). @param {number} value @param {"zh" | "en"} language */
|
|
99
|
+
function addedOf(value, language) {
|
|
100
|
+
const sign = value > 0 ? "+" : value < 0 ? "−" : "+";
|
|
101
|
+
const size = Math.abs(value);
|
|
102
|
+
if (size < 10_000) return `${sign}${countOf(size, language)}`;
|
|
103
|
+
const short = (Math.round(size / 1000) / 10).toFixed(1).replace(/\.0$/, "");
|
|
104
|
+
return `${sign}${language === "zh" ? `${short}万` : `${(Math.round(size / 100) / 10).toFixed(1).replace(/\.0$/, "")}K`}`;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const two = (/** @type {number} */ value) => String(value).padStart(2, "0");
|
|
108
|
+
/** A local day as the record writes it, YYYY-MM-DD. @param {Date} date */
|
|
109
|
+
const dayOf = (date) => `${date.getFullYear()}-${two(date.getMonth() + 1)}-${two(date.getDate())}`;
|
|
110
|
+
/** The day `count` days after `date` (before, negative), at noon. @param {Date} date @param {number} count */
|
|
111
|
+
const after = (date, count) => new Date(date.getFullYear(), date.getMonth(), date.getDate() + count, 12);
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* What the record of edits says for the card (`days`: query("activity")'s data, [{ date, edits, words }];
|
|
115
|
+
* `total`: the words of the workspace now; `today`: a Date): `curve`, the words in all at the end of each
|
|
116
|
+
* of the last 30 days, oldest first (a day before the record started taken as no change), none below 0;
|
|
117
|
+
* `added`, the words those days added, never more than the total (the record counts each edit's change,
|
|
118
|
+
* and a document deleted takes its words out of the total and none out of the record, so that the days
|
|
119
|
+
* before it would read as fewer words than none); `week`, the edits of each day Monday to Sunday (null for a day to come); `edits`,
|
|
120
|
+
* this week's; `last`, those of the week before up to the same weekday; `delta`, their change in percent
|
|
121
|
+
* (null where the week before had none).
|
|
122
|
+
* @param {Array<{ date: string, edits: number, words: number }>} days
|
|
123
|
+
* @param {number} total
|
|
124
|
+
* @param {Date} today
|
|
125
|
+
*/
|
|
126
|
+
function trendOf(days, total, today) {
|
|
127
|
+
const by = new Map(days.map((day) => [day.date, day]));
|
|
128
|
+
const curve = [];
|
|
129
|
+
let words = total;
|
|
130
|
+
for (let back = 0; back < 30; back++) {
|
|
131
|
+
curve.unshift(Math.max(0, words));
|
|
132
|
+
words -= by.get(dayOf(after(today, -back)))?.words ?? 0;
|
|
133
|
+
}
|
|
134
|
+
const added = total - Math.max(0, words);
|
|
135
|
+
const weekday = (today.getDay() + 6) % 7;
|
|
136
|
+
/** @type {Array<number | null>} */
|
|
137
|
+
const week = Array.from({ length: 7 }, (_, index) => (index > weekday ? null : by.get(dayOf(after(today, index - weekday)))?.edits ?? 0));
|
|
138
|
+
let edits = 0;
|
|
139
|
+
for (const value of week) edits += value ?? 0;
|
|
140
|
+
let last = 0;
|
|
141
|
+
for (let index = 0; index <= weekday; index++) last += by.get(dayOf(after(today, index - weekday - 7)))?.edits ?? 0;
|
|
142
|
+
return { curve, added, week, edits, last, delta: last > 0 ? Math.round((edits / last - 1) * 100) : null };
|
|
143
|
+
}
|
|
144
|
+
|
|
57
145
|
/**
|
|
58
146
|
* The four cells the card shows of `stats` (workspace.query("stats")'s data), or of none (null: a dash
|
|
59
|
-
* each), in `language`: [{ key, label, value, unit
|
|
147
|
+
* each), and of the record's `trend` (trendOf's, or null), in `language`: [{ key, label, value, unit, of,
|
|
148
|
+
* caption: [before, bold, after] }].
|
|
60
149
|
* @param {{ documents: number, todos: { done: number, total: number }, words: number, editedThisWeek: number } | null} stats
|
|
150
|
+
* @param {ReturnType<typeof trendOf> | null} trend
|
|
61
151
|
* @param {"zh" | "en"} language
|
|
62
152
|
*/
|
|
63
|
-
function cellsOf(stats, language) {
|
|
64
|
-
const
|
|
65
|
-
const dash = "
|
|
153
|
+
function cellsOf(stats, trend, language) {
|
|
154
|
+
const said = WORDS[language];
|
|
155
|
+
const dash = "—";
|
|
156
|
+
if (!stats) return ["documents", "words", "todos", "week"].map((key) => ({ key, label: said[/** @type {"documents"} */ (key)], value: dash, unit: "", of: "", caption: ["", "", ""] }));
|
|
157
|
+
const open = stats.todos.total - stats.todos.done;
|
|
158
|
+
const percent = stats.todos.total > 0 ? Math.round((100 * stats.todos.done) / stats.todos.total) : 0;
|
|
159
|
+
const words = wordsOf(stats.words, language);
|
|
160
|
+
const edits = trend?.edits ?? 0;
|
|
161
|
+
const delta = trend?.delta;
|
|
66
162
|
return [
|
|
67
|
-
{ key: "documents", label:
|
|
68
|
-
{ key: "
|
|
69
|
-
{ key: "
|
|
70
|
-
{ key: "week", label:
|
|
163
|
+
{ key: "documents", label: said.documents, value: countOf(stats.documents, language), unit: said.pieces, of: "", caption: stats.documents === 0 ? ["", "", said.zero.documents] : said.editedWeek(stats.editedThisWeek) },
|
|
164
|
+
{ key: "words", label: said.words, value: words.value, unit: words.unit, of: "", caption: said.month(addedOf(trend?.added ?? 0, language)) },
|
|
165
|
+
{ key: "todos", label: said.todos, value: countOf(stats.todos.done, language), unit: "", of: `/ ${countOf(stats.todos.total, language)}`, caption: stats.todos.total === 0 ? ["", "", said.zero.todos] : open === 0 ? ["", "100%", ` · ${said.allDone}`] : ["", ...said.left(percent, open)] },
|
|
166
|
+
{ key: "week", label: said.week, value: countOf(edits, language), unit: said.times, of: "", caption: edits === 0 ? ["", "", said.zero.week] : delta === null || delta === undefined ? ["", "", said.lastNone] : said.against(`${delta > 0 ? "+" : delta < 0 ? "−" : ""}${Math.abs(delta)}%`) },
|
|
71
167
|
];
|
|
72
168
|
}
|
|
73
169
|
|
|
170
|
+
// The cells' small pictures, of lines, 24 x 24.
|
|
171
|
+
const ICONS = {
|
|
172
|
+
documents: '<path d="M7 3.5h6.5L18 8v11a1.5 1.5 0 0 1-1.5 1.5h-9.5A1.5 1.5 0 0 1 5.5 19V5A1.5 1.5 0 0 1 7 3.5z"/><path d="M13.5 3.5V8H18"/>',
|
|
173
|
+
words: '<path d="M5 6.5h14M5 12h14M5 17.5h9"/>',
|
|
174
|
+
todos: '<rect x="3.5" y="4" width="6.5" height="6.5" rx="1.8"/><path d="M5.2 7.3l1.3 1.3 2-2.1"/><rect x="3.5" y="13.5" width="6.5" height="6.5" rx="1.8"/><path d="M13.5 7.2h7M13.5 16.8h7"/>',
|
|
175
|
+
week: '<path d="M5 19.5v-6M10 19.5v-13M15 19.5v-9M20 19.5v-4"/>',
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
/** The pictures' sizes by the card's layout: the line's and the bars' width and height, and the squares' columns, side and gap. */
|
|
179
|
+
const SIZES = {
|
|
180
|
+
row: { width: 112, height: 24, columns: 11, side: 6, gap: 2 },
|
|
181
|
+
wide: { width: 190, height: 24, columns: 16, side: 8, gap: 3 },
|
|
182
|
+
square: { width: 104, height: 40, columns: 8, side: 8, gap: 3 },
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
let made_ = 0; // the gradients' ids, one each
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* The documents as squares, `lit` of them (those edited this week) in the accent: at most three rows of
|
|
189
|
+
* `columns`, a square standing for more than one document past that; the rows as even as they can be
|
|
190
|
+
* (12 in two rows of 6, 23 in 8, 8 and 7), so that no square is left alone on a row of its own.
|
|
191
|
+
* @param {number} count @param {number} lit @param {{ columns: number, side: number, gap: number }} size
|
|
192
|
+
*/
|
|
193
|
+
function squares(count, lit, { columns, side, gap }) {
|
|
194
|
+
const most = columns * 3;
|
|
195
|
+
const shown = Math.min(count, most);
|
|
196
|
+
const on = count > most ? Math.round((lit / count) * shown) : Math.min(lit, shown);
|
|
197
|
+
const rows = Math.max(1, Math.ceil(shown / columns));
|
|
198
|
+
const across = Math.max(1, Math.ceil(shown / rows));
|
|
199
|
+
let drawn = "";
|
|
200
|
+
for (let index = 0; index < shown; index++) {
|
|
201
|
+
drawn += `<rect x="${(index % across) * (side + gap)}" y="${Math.floor(index / across) * (side + gap)}" width="${side}" height="${side}" rx="${side > 6 ? 2 : 1.6}" class="gallery-stats-${index < on ? "on" : "off"}"/>`;
|
|
202
|
+
}
|
|
203
|
+
if (shown === 0) drawn = `<rect width="${columns * (side + gap) - gap}" height="6" rx="3" class="gallery-stats-empty"/>`;
|
|
204
|
+
const height = shown === 0 ? 6 : rows * (side + gap) - gap;
|
|
205
|
+
return `<svg width="${columns * (side + gap) - gap}" height="${height}" aria-hidden="true">${drawn}</svg>`;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** The words over 30 days as a line, its area fading under it and a dot at its end. @param {number[]} values @param {{ width: number, height: number }} size */
|
|
209
|
+
function curveOf(values, { width, height }) {
|
|
210
|
+
const low = Math.min(...values);
|
|
211
|
+
const high = Math.max(...values);
|
|
212
|
+
if (high === low) return `<svg width="${width}" height="${height}" aria-hidden="true"><line x1="0" x2="${width}" y1="${height - 2}" y2="${height - 2}" class="gallery-stats-flat" stroke-width="1.8" stroke-linecap="round"/></svg>`;
|
|
213
|
+
const step = width / (values.length - 1);
|
|
214
|
+
const y = (/** @type {number} */ value) => height - 3 - ((value - low) / (high - low)) * (height - 7);
|
|
215
|
+
const points = values.map((value, index) => [index * step, y(value)]);
|
|
216
|
+
const line = points.map(([x, at], index) => `${index ? "L" : "M"}${x.toFixed(1)} ${at.toFixed(1)}`).join("");
|
|
217
|
+
const [endX, endY] = points[points.length - 1];
|
|
218
|
+
const id = `gallery-stats-fade-${++made_}`;
|
|
219
|
+
return `<svg width="${width}" height="${height}" aria-hidden="true"><defs><linearGradient id="${id}" x1="0" x2="0" y1="0" y2="1"><stop offset="0" class="gallery-stats-stop" stop-opacity=".22"/><stop offset="1" class="gallery-stats-stop" stop-opacity="0"/></linearGradient></defs><path d="${line}L${width} ${height}L0 ${height}Z" fill="url(#${id})"/><path d="${line}" fill="none" class="gallery-stats-line" stroke-width="1.8" stroke-linejoin="round" stroke-linecap="round"/><circle cx="${endX}" cy="${endY}" r="3.2" class="gallery-stats-end" stroke-width="2"/></svg>`;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** This week's edits, a bar a day, today's in the accent, a day to come a stub. @param {Array<number | null>} values @param {number} today @param {{ width: number, height: number }} size */
|
|
223
|
+
function barsOf(values, today, { width, height }) {
|
|
224
|
+
const most = Math.max(1, ...values.filter((value) => value !== null));
|
|
225
|
+
const bar = Math.min(12, (width - 30) / 7);
|
|
226
|
+
const gap = (width - 7 * bar) / 6;
|
|
227
|
+
const none = values.every((value) => !value);
|
|
228
|
+
let drawn = "";
|
|
229
|
+
values.forEach((value, index) => {
|
|
230
|
+
const x = index * (bar + gap);
|
|
231
|
+
if (value === null || none) return void (drawn += `<rect x="${x}" y="${height - 2}" width="${bar}" height="2" rx="1" class="gallery-stats-stub"/>`);
|
|
232
|
+
const tall = Math.max(3, (value / most) * height);
|
|
233
|
+
drawn += `<path d="M${x} ${height}V${height - tall + 3}a3 3 0 0 1 3-3h${bar - 6}a3 3 0 0 1 3 3V${height}Z" class="gallery-stats-${index === today ? "today" : "day"}"/>`;
|
|
234
|
+
});
|
|
235
|
+
return `<svg width="${width}" height="${height}" aria-hidden="true">${drawn}</svg>`;
|
|
236
|
+
}
|
|
237
|
+
|
|
74
238
|
/**
|
|
75
239
|
* An element of the face, of `kind` (its class).
|
|
76
240
|
* @template {keyof HTMLElementTagNameMap} K
|
|
@@ -87,79 +251,96 @@ function made(tag, kind, text) {
|
|
|
87
251
|
|
|
88
252
|
DocKit.component({
|
|
89
253
|
id: "gallery/stats",
|
|
90
|
-
on: ["data", "clock"],
|
|
254
|
+
on: ["data", "clock", "layout"],
|
|
91
255
|
mount(host, context) {
|
|
92
256
|
const language = languageOf(document.documentElement);
|
|
93
257
|
const words = WORDS[language];
|
|
94
258
|
const face = made("div", "face");
|
|
95
|
-
const head = made("div", "head");
|
|
96
|
-
const chip = made("span", "chip");
|
|
97
|
-
chip.setAttribute("aria-hidden", "true");
|
|
98
|
-
chip.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 19.5h15M7.5 15.5v-5M12 15.5V4.5M16.5 15.5V8"/></svg>';
|
|
99
|
-
head.append(chip, made("span", "title", words.title));
|
|
100
259
|
const grid = made("dl", "grid");
|
|
101
260
|
const line = made("p", "line");
|
|
102
261
|
line.hidden = true;
|
|
103
|
-
face.append(
|
|
262
|
+
face.append(grid, line);
|
|
104
263
|
host.append(face);
|
|
105
264
|
const workspace = context.workspace;
|
|
106
265
|
if (!workspace) return void context.fail(new Error("its manifest's needs hold \"workspace\": context.workspace is not there"));
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
266
|
+
/** @type {Parameters<typeof cellsOf>[0]} */
|
|
267
|
+
let stats = null;
|
|
268
|
+
/** @type {Array<{ date: string, edits: number, words: number }>} */
|
|
269
|
+
let days = [];
|
|
270
|
+
let drawnKey = "";
|
|
271
|
+
// The cells, each its label over its number, its picture and its line, drawn again only when what they say is another.
|
|
272
|
+
const draw = () => {
|
|
273
|
+
const size = context.size;
|
|
274
|
+
const layout = !size ? "row" : size.w >= 12 ? "wide" : size.w <= 4 ? "square" : "row";
|
|
275
|
+
face.dataset.layout = layout;
|
|
276
|
+
face.toggleAttribute("data-unread", !stats);
|
|
277
|
+
const now = new Date();
|
|
278
|
+
const trend = stats ? trendOf(days, stats.words, now) : null;
|
|
279
|
+
const cells = cellsOf(stats, trend, language);
|
|
280
|
+
const key = JSON.stringify([layout, cells, trend, dayOf(now)]);
|
|
281
|
+
if (key === drawnKey) return;
|
|
282
|
+
drawnKey = key;
|
|
283
|
+
const sizes = SIZES[/** @type {keyof typeof SIZES} */ (layout)];
|
|
284
|
+
grid.replaceChildren(...cells.map(({ key: kind, label, value, unit, of, caption }) => {
|
|
285
|
+
const cell = made("div", "cell");
|
|
286
|
+
cell.dataset.stat = kind;
|
|
287
|
+
const name = made("dt", "label");
|
|
288
|
+
name.innerHTML = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${ICONS[/** @type {keyof typeof ICONS} */ (kind)]}</svg>`;
|
|
289
|
+
name.append(made("span", "label-words", label));
|
|
290
|
+
const number = made("dd", "value");
|
|
291
|
+
number.append(made("span", "number", value));
|
|
292
|
+
if (unit) number.append(made("span", "unit", unit));
|
|
293
|
+
if (of) number.append(made("span", "of", of));
|
|
294
|
+
const picture = made("dd", "picture");
|
|
295
|
+
if (stats && trend) {
|
|
296
|
+
if (kind === "documents") picture.innerHTML = squares(stats.documents, stats.editedThisWeek, sizes);
|
|
297
|
+
if (kind === "words") picture.innerHTML = curveOf(trend.curve, sizes);
|
|
298
|
+
if (kind === "todos") {
|
|
117
299
|
const bar = made("span", "bar");
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
300
|
+
const fill = made("span", "fill");
|
|
301
|
+
fill.style.width = `${stats.todos.total > 0 ? (100 * stats.todos.done) / stats.todos.total : 0}%`;
|
|
302
|
+
bar.append(fill);
|
|
303
|
+
picture.append(bar);
|
|
121
304
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
put(".gallery-stats-unit", unit);
|
|
135
|
-
});
|
|
136
|
-
// The bar of the to-dos: the share done, none drawn where nothing is known or there is none.
|
|
137
|
-
const bar = /** @type {HTMLElement | null} */ (grid.querySelector(".gallery-stats-bar"));
|
|
138
|
-
if (bar) {
|
|
139
|
-
const share = stats && stats.todos.total > 0 ? stats.todos.done / stats.todos.total : null;
|
|
140
|
-
bar.hidden = share === null;
|
|
141
|
-
bar.style.setProperty("--share", String(share ?? 0));
|
|
142
|
-
}
|
|
305
|
+
if (kind === "week") picture.innerHTML = barsOf(trend.week, (now.getDay() + 6) % 7, sizes);
|
|
306
|
+
}
|
|
307
|
+
const foot = made("dd", "caption");
|
|
308
|
+
if (kind === "documents" && stats && stats.documents > 0) foot.append(made("i", "mark"));
|
|
309
|
+
const [before, bold, after_] = caption;
|
|
310
|
+
if (before) foot.append(before);
|
|
311
|
+
if (bold) foot.append(made("b", "strong", bold));
|
|
312
|
+
if (after_) foot.append(after_);
|
|
313
|
+
if (!stats) foot.textContent = " ";
|
|
314
|
+
cell.append(name, number, picture, foot);
|
|
315
|
+
return cell;
|
|
316
|
+
}));
|
|
143
317
|
};
|
|
144
318
|
let asking = 0; // the last read asked: an older answer that comes after it is dropped
|
|
145
319
|
const read = () => {
|
|
146
320
|
const ticket = ++asking;
|
|
147
|
-
workspace.query("
|
|
321
|
+
const record = workspace.query("activity", { days: DAYS }).then(({ data }) => data, () => []);
|
|
322
|
+
workspace.query("stats").then(async ({ data }) => {
|
|
323
|
+
const kept = await record;
|
|
148
324
|
if (ticket !== asking || context.signal.aborted) return;
|
|
149
325
|
line.hidden = true;
|
|
150
|
-
|
|
326
|
+
stats = data;
|
|
327
|
+
days = Array.isArray(kept) ? kept : [];
|
|
328
|
+
draw();
|
|
151
329
|
}, (/** @type {any} */ error) => {
|
|
152
330
|
if (ticket !== asking || context.signal.aborted) return;
|
|
153
|
-
|
|
331
|
+
stats = null;
|
|
332
|
+
days = [];
|
|
333
|
+
draw();
|
|
154
334
|
line.hidden = false;
|
|
155
335
|
line.textContent = error?.code === "offline" ? words.offline : words.failed;
|
|
156
336
|
});
|
|
157
337
|
};
|
|
158
|
-
draw(
|
|
338
|
+
draw();
|
|
159
339
|
read();
|
|
160
340
|
return {
|
|
161
341
|
update(reason, detail) {
|
|
162
|
-
if ((reason === "data" && detail === "stats") || (reason === "clock" && detail === "day")) read();
|
|
342
|
+
if ((reason === "data" && (detail === "stats" || detail === "activity")) || (reason === "clock" && detail === "day")) read();
|
|
343
|
+
else if (reason === "layout") draw();
|
|
163
344
|
},
|
|
164
345
|
};
|
|
165
346
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 120"><rect width="240" height="120" rx="8" fill="#f3f3f1"/><rect x="
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 120"><rect width="240" height="120" rx="8" fill="#f3f3f1"/><rect x="10.5" y="30.5" width="219" height="59" rx="8" fill="#ffffff" stroke="#e6e6e3"/><rect x="18" y="38" width="22" height="4" rx="2" fill="#a6a5a1"/><rect x="18" y="46" width="18" height="11" rx="3" fill="#1d1d1b"/><line x1="68" x2="68" y1="38" y2="82" stroke="#efefed"/><rect x="72" y="38" width="22" height="4" rx="2" fill="#a6a5a1"/><rect x="72" y="46" width="18" height="11" rx="3" fill="#1d1d1b"/><line x1="122" x2="122" y1="38" y2="82" stroke="#efefed"/><rect x="126" y="38" width="22" height="4" rx="2" fill="#a6a5a1"/><rect x="126" y="46" width="18" height="11" rx="3" fill="#1d1d1b"/><line x1="176" x2="176" y1="38" y2="82" stroke="#efefed"/><rect x="180" y="38" width="22" height="4" rx="2" fill="#a6a5a1"/><rect x="180" y="46" width="18" height="11" rx="3" fill="#1d1d1b"/><rect x="18" y="66" width="4" height="4" rx="1" fill="#4084cf"/><rect x="24" y="66" width="4" height="4" rx="1" fill="#4084cf"/><rect x="30" y="66" width="4" height="4" rx="1" fill="#4084cf"/><rect x="36" y="66" width="4" height="4" rx="1" fill="#4084cf"/><rect x="42" y="66" width="4" height="4" rx="1" fill="#e7e7e5"/><rect x="48" y="66" width="4" height="4" rx="1" fill="#e7e7e5"/><rect x="18" y="72" width="4" height="4" rx="1" fill="#e7e7e5"/><rect x="24" y="72" width="4" height="4" rx="1" fill="#e7e7e5"/><rect x="30" y="72" width="4" height="4" rx="1" fill="#e7e7e5"/><rect x="36" y="72" width="4" height="4" rx="1" fill="#e7e7e5"/><rect x="42" y="72" width="4" height="4" rx="1" fill="#e7e7e5"/><rect x="48" y="72" width="4" height="4" rx="1" fill="#e7e7e5"/><path d="M72 80l8-3 8 1 8-4 8-1 8-5" fill="none" stroke="#4084cf" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/><rect x="126" y="74" width="40" height="4" rx="2" fill="#e7e7e5"/><rect x="126" y="74" width="28" height="4" rx="2" fill="#4084cf"/><rect x="180" y="72" width="6" height="10" rx="3" fill="#b0cbeb"/><rect x="189" y="76" width="6" height="6" rx="3" fill="#b0cbeb"/><rect x="198" y="73" width="6" height="9" rx="3" fill="#b0cbeb"/><rect x="207" y="79" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="214" y="81" width="5" height="1.5" rx="0.75" fill="#e7e7e5"/><rect x="221" y="81" width="5" height="1.5" rx="0.75" fill="#e7e7e5"/><rect x="228" y="81" width="5" height="1.5" rx="0.75" fill="#e7e7e5"/></svg>
|