@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
|
@@ -10,37 +10,51 @@
|
|
|
10
10
|
// wrote is the one edited last, which the facts would put first: once a box is checked here the groups keep
|
|
11
11
|
// the order they were drawn in, a document new to the card first). A click on an item's words opens its
|
|
12
12
|
// document there, at the item's block where it has an id, else at the document (context.workspace.open:
|
|
13
|
-
// the workbench goes there); a click on a group's title opens the document. It reads again whenever the
|
|
14
|
-
// a to-do added, checked or taken out in any
|
|
15
|
-
// do (`source`). Its two settings, the card's
|
|
16
|
-
//
|
|
17
|
-
// `
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
//
|
|
13
|
+
// the workbench goes there); a click on a group's title opens the document. It reads again whenever the
|
|
14
|
+
// workspace says its to-dos changed (the `data` signal, "todos": a to-do added, checked or taken out in any
|
|
15
|
+
// document, a document renamed or gone) and when its settings do (`source`). Its two settings, the card's
|
|
16
|
+
// form (the grip at its top right › 设置…), are kept in its data part `settings`, which the board writes and
|
|
17
|
+
// this block only reads: `document` (a document's slug: its to-dos alone) and `done` (the done ones too,
|
|
18
|
+
// checked and struck through). Where the workspace cannot be read (an exported file, where it has no
|
|
19
|
+
// server; a server that does not answer) it says so; where nothing writes it (an exported file: no
|
|
20
|
+
// setTodo) its boxes are only drawn. The words are the page's language (the UI's where Gallery says it,
|
|
21
|
+
// else the page's lang).
|
|
22
|
+
//
|
|
23
|
+
// Its face (the pack's design B, in the kit's card tokens), laid out by the card's cells (`data-layout`, by
|
|
24
|
+
// context.size, read again on `layout`): a head of the chip (a checked list), 我的待办 and its quiet meta;
|
|
25
|
+
// how many are done of all (of the document asked, or of every one); and the list, grouped under each
|
|
26
|
+
// document's icon and title (small, gray, its open count after it), each item a box, its words and, under
|
|
27
|
+
// them (beside them on a wide card), the headings it stands under, faint, but for the document's own
|
|
28
|
+
// title (its first heading, as often), which the group's says; the list fades at its foot while there is
|
|
29
|
+
// more under it. The share done is drawn by the room: on a 4 × 4 card ("default") a line (已完成 19 / 27,
|
|
30
|
+
// the percent at its end) over a row of ticks, one an item (a bar past 48); on a 4 × 6 ("tall") a ring
|
|
31
|
+
// of the share, its percent in the middle, beside the open count large (8 项没完成) and 已完成 19 / 27; on
|
|
32
|
+
// an 8 × 4 ("wide") a ring at the left over a key (已完成, 未完成, 来自文档). The head's meta says how many are
|
|
33
|
+
// open (8 项; 来自 4 篇文档 on a tall card). The face says by `data-state` what it shows: items, every one
|
|
34
|
+
// done (a full green ring with a tick, 待办都完成了), none, or the workspace not read.
|
|
27
35
|
|
|
28
36
|
const WORDS = {
|
|
29
37
|
zh: {
|
|
30
38
|
title: "我的待办",
|
|
31
|
-
empty: "所有文档里的待办会出现在这里",
|
|
39
|
+
empty: ["还没有待办", "所有文档里的待办会出现在这里", "在文档里输入 [] 就能新建一项"],
|
|
40
|
+
noneIn: ["这篇文档里没有待办", "在文档里输入 [] 就能新建一项"],
|
|
32
41
|
allDone: "待办都完成了",
|
|
33
|
-
|
|
34
|
-
offline: "在 Gallery
|
|
35
|
-
failed: "读不到工作区的待办",
|
|
42
|
+
allDoneSaid: (/** @type {number} */ all) => `${all} 项,全都勾掉了`,
|
|
43
|
+
offline: ["在 Gallery 里打开时显示", "现在读不到工作区"],
|
|
44
|
+
failed: ["读不到工作区的待办", "过一会儿会再读"],
|
|
36
45
|
open: (/** @type {string} */ title) => `打开「${title}」`,
|
|
37
46
|
path: (/** @type {string[]} */ path) => path.join(" › "),
|
|
38
47
|
check: "标记为完成",
|
|
39
48
|
uncheck: "标记为未完成",
|
|
40
49
|
done: "已完成",
|
|
41
50
|
left: "未完成",
|
|
51
|
+
from: "来自文档",
|
|
52
|
+
progress: (/** @type {number} */ done, /** @type {number} */ all) => ["已完成 ", String(done), ` / ${all}`],
|
|
53
|
+
openUnit: "项没完成",
|
|
42
54
|
share: (/** @type {number} */ done, /** @type {number} */ all) => `${all} 项待办完成了 ${done} 项`,
|
|
55
|
+
openCount: (/** @type {number} */ count) => `${count} 项`,
|
|
43
56
|
all: (/** @type {number} */ count) => `共 ${count} 项`,
|
|
57
|
+
documents: (/** @type {number} */ count) => `来自 ${count} 篇文档`,
|
|
44
58
|
refused: {
|
|
45
59
|
changed: "这一项刚被改过,已重新读取",
|
|
46
60
|
ambiguous: "文档里有几项一样的待办,请在文档里勾选",
|
|
@@ -53,19 +67,25 @@ const WORDS = {
|
|
|
53
67
|
},
|
|
54
68
|
en: {
|
|
55
69
|
title: "My to-dos",
|
|
56
|
-
empty: "The to-dos of every document
|
|
70
|
+
empty: ["No to-dos yet", "The to-dos of every document show here", "Type [] in a document to make one"],
|
|
71
|
+
noneIn: ["This document has no to-dos", "Type [] in it to make one"],
|
|
57
72
|
allDone: "Every to-do is done",
|
|
58
|
-
|
|
59
|
-
offline: "
|
|
60
|
-
failed: "The workspace's to-dos could not be read",
|
|
73
|
+
allDoneSaid: (/** @type {number} */ all) => `All ${all} checked off`,
|
|
74
|
+
offline: ["Shown when opened in Gallery", "The workspace cannot be read now"],
|
|
75
|
+
failed: ["The workspace's to-dos could not be read", "It reads them again in a while"],
|
|
61
76
|
open: (/** @type {string} */ title) => `Open “${title}”`,
|
|
62
77
|
path: (/** @type {string[]} */ path) => path.join(" › "),
|
|
63
78
|
check: "Mark as done",
|
|
64
79
|
uncheck: "Mark as not done",
|
|
65
80
|
done: "Done",
|
|
66
81
|
left: "Open",
|
|
82
|
+
from: "Documents",
|
|
83
|
+
progress: (/** @type {number} */ done, /** @type {number} */ all) => ["", String(done), ` of ${all} done`],
|
|
84
|
+
openUnit: "open",
|
|
67
85
|
share: (/** @type {number} */ done, /** @type {number} */ all) => `${done} of ${all} to-dos done`,
|
|
86
|
+
openCount: (/** @type {number} */ count) => `${count} open`,
|
|
68
87
|
all: (/** @type {number} */ count) => `${count} in all`,
|
|
88
|
+
documents: (/** @type {number} */ count) => `from ${count} ${count === 1 ? "document" : "documents"}`,
|
|
69
89
|
refused: {
|
|
70
90
|
changed: "This to-do just changed: read again",
|
|
71
91
|
ambiguous: "The document has several to-dos alike: check it in the document",
|
|
@@ -80,6 +100,8 @@ const WORDS = {
|
|
|
80
100
|
|
|
81
101
|
/** How long a line saying why a check was refused stays, in ms. */
|
|
82
102
|
const SAID_FOR = 4000;
|
|
103
|
+
/** The most items the ticks draw one each; past them, a bar. */
|
|
104
|
+
const MOST_TICKS = 48;
|
|
83
105
|
|
|
84
106
|
/** The language the page speaks: the UI's where Gallery says it (data-ge-language), else its lang's. */
|
|
85
107
|
function languageOf(/** @type {HTMLElement} */ root) {
|
|
@@ -97,7 +119,7 @@ function askedOf(settings) {
|
|
|
97
119
|
return { document: typeof table.document === "string" && table.document ? table.document : null, done: table.done === true };
|
|
98
120
|
}
|
|
99
121
|
|
|
100
|
-
/** @typedef {{ ref: DocTodoRef, text: string, done: boolean, slug: string, title: string, path: string[] }} Todo */
|
|
122
|
+
/** @typedef {{ ref: DocTodoRef, text: string, done: boolean, slug: string, title: string, icon?: string | null, path: string[] }} Todo */
|
|
101
123
|
|
|
102
124
|
/**
|
|
103
125
|
* An item by its document, its headings and its words: what names it while the card lives, whether it has
|
|
@@ -108,10 +130,11 @@ const itemKey = (todo) => JSON.stringify([todo.slug, todo.path, todo.text]);
|
|
|
108
130
|
|
|
109
131
|
/**
|
|
110
132
|
* The to-dos (workspace.query("todos")'s data) as the card shows them, of `asked`: { groups, open,
|
|
111
|
-
* all }, groups [{ slug, title, items }] in the order the documents come (the one edited
|
|
112
|
-
* items those shown (not done, or all with `asked.done`, and the ones checked on this card:
|
|
113
|
-
* `open` how many are not done, `all` how many there are of the document asked or of the
|
|
114
|
-
* `order` (the slugs as drawn before, or null):
|
|
133
|
+
* all, documents }, groups [{ slug, title, icon, items }] in the order the documents come (the one edited
|
|
134
|
+
* last first), items those shown (not done, or all with `asked.done`, and the ones checked on this card:
|
|
135
|
+
* `kept`); `open` how many are not done, `all` how many there are of the document asked or of the
|
|
136
|
+
* workspace, `documents` how many documents hold one open. `order` (the slugs as drawn before, or null):
|
|
137
|
+
* the groups keep that order, a document not in it before them.
|
|
115
138
|
* @param {Todo[]} todos
|
|
116
139
|
* @param {{ document: string | null, done: boolean }} asked
|
|
117
140
|
* @param {Set<string>} kept
|
|
@@ -119,21 +142,21 @@ const itemKey = (todo) => JSON.stringify([todo.slug, todo.path, todo.text]);
|
|
|
119
142
|
*/
|
|
120
143
|
function groupsOf(todos, asked, kept, order = null) {
|
|
121
144
|
const mine = todos.filter((todo) => asked.document === null || todo.slug === asked.document);
|
|
122
|
-
/** @type {Map<string, { slug: string, title: string, items: Todo[] }>} */
|
|
145
|
+
/** @type {Map<string, { slug: string, title: string, icon: string | null, items: Todo[] }>} */
|
|
123
146
|
const groups = new Map();
|
|
124
147
|
for (const todo of mine) {
|
|
125
148
|
if (todo.done && !asked.done && !kept.has(itemKey(todo))) continue;
|
|
126
|
-
if (!groups.has(todo.slug)) groups.set(todo.slug, { slug: todo.slug, title: todo.title, items: [] });
|
|
149
|
+
if (!groups.has(todo.slug)) groups.set(todo.slug, { slug: todo.slug, title: todo.title, icon: todo.icon ?? null, items: [] });
|
|
127
150
|
groups.get(todo.slug)?.items.push(todo);
|
|
128
151
|
}
|
|
129
152
|
const placed = [...groups.values()];
|
|
130
153
|
if (order) placed.sort((a, b) => order.indexOf(a.slug) - order.indexOf(b.slug)); // stable: those not in it keep the order they came in
|
|
131
|
-
return { groups: placed, open: mine.filter((todo) => !todo.done).length, all: mine.length };
|
|
154
|
+
return { groups: placed, open: mine.filter((todo) => !todo.done).length, all: mine.length, documents: new Set(mine.filter((todo) => !todo.done).map((todo) => todo.slug)).size };
|
|
132
155
|
}
|
|
133
156
|
|
|
134
157
|
/**
|
|
135
|
-
*
|
|
136
|
-
*
|
|
158
|
+
* What the card says where it shows no item, or null where it shows some: none in the workspace, none in
|
|
159
|
+
* the one document asked, all done.
|
|
137
160
|
* @param {{ groups: unknown[], all: number }} shown
|
|
138
161
|
* @param {{ document: string | null }} asked
|
|
139
162
|
* @param {"zh" | "en"} language
|
|
@@ -142,7 +165,15 @@ function emptyLine(shown, asked, language) {
|
|
|
142
165
|
if (shown.groups.length > 0) return null;
|
|
143
166
|
const words = WORDS[language];
|
|
144
167
|
if (shown.all > 0) return words.allDone;
|
|
145
|
-
return asked.document === null ? words.empty : words.noneIn;
|
|
168
|
+
return asked.document === null ? words.empty[1] : words.noneIn[0];
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** What a document's icon is, as Gallery writes its value: a glyph (/icons/…), a picture of its folder (assets/…), an emoji, or none. @param {string | null | undefined} value */
|
|
172
|
+
function iconKindOf(value) {
|
|
173
|
+
if (typeof value !== "string" || !value) return null;
|
|
174
|
+
if (value.startsWith("/icons/")) return "glyph";
|
|
175
|
+
if (value.startsWith("assets/")) return "image";
|
|
176
|
+
return "emoji";
|
|
146
177
|
}
|
|
147
178
|
|
|
148
179
|
/**
|
|
@@ -159,9 +190,34 @@ function made(tag, kind, text) {
|
|
|
159
190
|
return node;
|
|
160
191
|
}
|
|
161
192
|
|
|
193
|
+
// A document's icon, as the sidebar draws it: its picture from the server's icon route, a glyph masked
|
|
194
|
+
// in the muted color, or none (style.css draws a page).
|
|
195
|
+
function iconFor(/** @type {string} */ slug, /** @type {string | null} */ value) {
|
|
196
|
+
const kind = iconKindOf(value);
|
|
197
|
+
const icon = made("span", "icon");
|
|
198
|
+
icon.setAttribute("aria-hidden", "true");
|
|
199
|
+
if (!kind || value === null) return icon;
|
|
200
|
+
const address = `/__gallery/edit/icon?value=${encodeURIComponent(value)}&slug=${encodeURIComponent(slug)}`;
|
|
201
|
+
if (kind === "glyph") {
|
|
202
|
+
icon.classList.add("gallery-todos-glyph");
|
|
203
|
+
icon.style.setProperty("--gallery-todos-icon", `url("${address}")`);
|
|
204
|
+
return icon;
|
|
205
|
+
}
|
|
206
|
+
const picture = document.createElement("img");
|
|
207
|
+
picture.alt = "";
|
|
208
|
+
picture.src = address;
|
|
209
|
+
picture.decoding = "async";
|
|
210
|
+
icon.classList.add("gallery-todos-picture");
|
|
211
|
+
icon.append(picture);
|
|
212
|
+
return icon;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const CHIP = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><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"/></svg>';
|
|
216
|
+
const TICK = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5.5 12.5l4 4 9-9"/></svg>';
|
|
217
|
+
|
|
162
218
|
DocKit.component({
|
|
163
219
|
id: "gallery/todos",
|
|
164
|
-
on: ["source", "data"],
|
|
220
|
+
on: ["source", "data", "layout"],
|
|
165
221
|
mount(host, context) {
|
|
166
222
|
const language = languageOf(document.documentElement);
|
|
167
223
|
const words = WORDS[language];
|
|
@@ -170,34 +226,58 @@ DocKit.component({
|
|
|
170
226
|
const count = made("span", "count");
|
|
171
227
|
const chip = made("span", "chip");
|
|
172
228
|
chip.setAttribute("aria-hidden", "true");
|
|
173
|
-
chip.innerHTML =
|
|
229
|
+
chip.innerHTML = CHIP;
|
|
174
230
|
head.append(chip, made("span", "title", words.title), count);
|
|
175
|
-
// How many are done of all: a
|
|
231
|
+
// How many are done of all: a line and its ticks, a ring and its percent, the open count large, a key.
|
|
176
232
|
const summary = made("div", "summary");
|
|
177
233
|
summary.hidden = true;
|
|
178
234
|
summary.setAttribute("role", "img");
|
|
235
|
+
const progress = made("p", "progress");
|
|
236
|
+
const progressWords = made("span", "progress-words");
|
|
237
|
+
const sharePercent = made("span", "share");
|
|
238
|
+
progress.append(progressWords, sharePercent);
|
|
239
|
+
const ticks = made("span", "ticks");
|
|
240
|
+
ticks.setAttribute("aria-hidden", "true");
|
|
179
241
|
const ring = made("span", "ring");
|
|
180
|
-
ring.innerHTML = '<svg
|
|
181
|
-
const percent =
|
|
182
|
-
|
|
242
|
+
ring.innerHTML = '<svg aria-hidden="true"><circle class="gallery-todos-track"/><circle class="gallery-todos-arc" pathLength="100"/></svg><span class="gallery-todos-percent"></span>';
|
|
243
|
+
const percent = /** @type {HTMLElement} */ (ring.querySelector(".gallery-todos-percent"));
|
|
244
|
+
const big = made("div", "big");
|
|
245
|
+
const bigLine = made("p", "big-line");
|
|
246
|
+
const openNumber = made("span", "open");
|
|
247
|
+
bigLine.append(openNumber, made("span", "open-unit", words.openUnit));
|
|
248
|
+
const bigDone = made("p", "big-done");
|
|
249
|
+
big.append(bigLine, bigDone);
|
|
183
250
|
const key = made("dl", "key");
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
251
|
+
const keyRow = (/** @type {string} */ kind, /** @type {string} */ name) => {
|
|
252
|
+
const row = made("div", "key-row");
|
|
253
|
+
row.dataset.kind = kind;
|
|
254
|
+
const value = made("dd", "key-count");
|
|
255
|
+
row.append(made("dt", "key-name", name), value);
|
|
256
|
+
key.append(row);
|
|
257
|
+
return value;
|
|
258
|
+
};
|
|
259
|
+
const doneCount = keyRow("done", words.done);
|
|
260
|
+
const leftCount = keyRow("left", words.left);
|
|
261
|
+
const fromCount = keyRow("from", words.from);
|
|
262
|
+
summary.append(progress, ticks, ring, big, key);
|
|
194
263
|
const list = made("div", "list");
|
|
264
|
+
// Where it shows no item: the cards' empty face (a soft square with the list's picture, or the full ring).
|
|
265
|
+
const empty = made("div", "empty");
|
|
266
|
+
const emptyPicture = made("span", "empty-picture");
|
|
267
|
+
emptyPicture.setAttribute("aria-hidden", "true");
|
|
195
268
|
const line = made("p", "line");
|
|
269
|
+
const hint = made("p", "hint");
|
|
270
|
+
empty.append(emptyPicture, line, hint);
|
|
271
|
+
empty.hidden = true;
|
|
196
272
|
const note = made("p", "note");
|
|
197
273
|
note.hidden = true;
|
|
198
274
|
note.setAttribute("role", "status");
|
|
199
|
-
face.append(head, summary, list,
|
|
275
|
+
face.append(head, summary, list, empty, note);
|
|
200
276
|
host.append(face);
|
|
277
|
+
// The list fades at its foot while there is more under it.
|
|
278
|
+
const fade = () => list.toggleAttribute("data-more", list.scrollHeight - list.scrollTop - list.clientHeight > 1);
|
|
279
|
+
list.addEventListener("scroll", fade, { passive: true });
|
|
280
|
+
context.signal?.addEventListener("abort", () => list.removeEventListener("scroll", fade), { once: true });
|
|
201
281
|
const workspace = context.workspace;
|
|
202
282
|
if (!workspace) return void context.fail(new Error("its manifest's needs hold \"workspace\": context.workspace is not there"));
|
|
203
283
|
const open = (/** @type {{ slug: string, block?: string | null }} */ target) => workspace.open(target);
|
|
@@ -212,13 +292,37 @@ DocKit.component({
|
|
|
212
292
|
/** @type {string[] | null} */
|
|
213
293
|
let held = null; // that order as it was when the first box was checked here: the groups keep it from then on
|
|
214
294
|
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
295
|
+
const layoutOf = () => {
|
|
296
|
+
const size = context.size;
|
|
297
|
+
return !size ? "default" : size.w >= 8 ? "wide" : size.h >= 6 ? "tall" : "default";
|
|
298
|
+
};
|
|
299
|
+
// A ring of `size` px, its stroke `width` px, the share done (`share`, 0 to 1).
|
|
300
|
+
const drawRing = (/** @type {number} */ size, /** @type {number} */ width, /** @type {number} */ share) => {
|
|
301
|
+
const svg = /** @type {SVGSVGElement} */ (ring.querySelector("svg"));
|
|
302
|
+
svg.setAttribute("viewBox", `0 0 ${size} ${size}`);
|
|
303
|
+
svg.setAttribute("width", String(size));
|
|
304
|
+
svg.setAttribute("height", String(size));
|
|
305
|
+
for (const circle of svg.querySelectorAll("circle")) {
|
|
306
|
+
circle.setAttribute("cx", String(size / 2));
|
|
307
|
+
circle.setAttribute("cy", String(size / 2));
|
|
308
|
+
circle.setAttribute("r", String((size - width) / 2));
|
|
309
|
+
circle.setAttribute("stroke-width", String(width));
|
|
310
|
+
}
|
|
311
|
+
svg.querySelector(".gallery-todos-arc")?.setAttribute("stroke-dasharray", `${Math.max(0, Math.min(1, share)) * 100} 100`);
|
|
312
|
+
};
|
|
313
|
+
// The empty face: its words, and its picture (the list's, or the full green ring with a tick).
|
|
314
|
+
const sayEmpty = (/** @type {string[] | null} */ said, /** @type {"list" | "done"} */ picture = "list") => {
|
|
315
|
+
empty.hidden = said === null;
|
|
316
|
+
list.hidden = said !== null;
|
|
317
|
+
if (said === null) return;
|
|
318
|
+
empty.dataset.picture = picture;
|
|
319
|
+
emptyPicture.innerHTML = picture === "done" ? `<svg viewBox="0 0 72 72"><circle class="gallery-todos-done-ring" cx="36" cy="36" r="32.5"/></svg>${TICK}` : CHIP;
|
|
320
|
+
line.textContent = said[0];
|
|
321
|
+
hint.replaceChildren(...said.slice(1).flatMap((piece, index) => (index === 0 ? [piece] : [document.createElement("br"), piece])));
|
|
218
322
|
};
|
|
219
323
|
let noteTimer = 0;
|
|
220
|
-
const tell = (/** @type {string} */
|
|
221
|
-
note.textContent =
|
|
324
|
+
const tell = (/** @type {string} */ said) => {
|
|
325
|
+
note.textContent = said;
|
|
222
326
|
note.hidden = false;
|
|
223
327
|
clearTimeout(noteTimer);
|
|
224
328
|
noteTimer = context.timeout(() => { note.hidden = true; }, SAID_FOR);
|
|
@@ -248,29 +352,61 @@ DocKit.component({
|
|
|
248
352
|
|
|
249
353
|
// The list drawn anew of what was read, scrolled where it was.
|
|
250
354
|
const draw = () => {
|
|
355
|
+
const layout = layoutOf();
|
|
356
|
+
face.dataset.layout = layout;
|
|
251
357
|
if (!last) return;
|
|
252
358
|
const asked = lastAsked;
|
|
253
359
|
const shown = groupsOf(last, asked, kept, held);
|
|
254
360
|
order = shown.groups.map((group) => group.slug);
|
|
255
361
|
const top = list.scrollTop;
|
|
256
|
-
count.textContent = shown.all > 0 ? words.all(shown.all) : "";
|
|
257
|
-
// The summary of all the to-dos asked (of one document, or of every one), none where there are none.
|
|
258
362
|
const done = shown.all - shown.open;
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
summary
|
|
363
|
+
const allDone = shown.groups.length === 0 && shown.all > 0;
|
|
364
|
+
count.textContent = shown.all === 0 ? "" : allDone ? words.all(shown.all) : layout === "tall" ? words.documents(shown.documents) : words.openCount(shown.open);
|
|
365
|
+
// The summary of all the to-dos asked (of one document, or of every one), none where there are none.
|
|
366
|
+
summary.hidden = shown.all === 0 || allDone;
|
|
262
367
|
summary.setAttribute("aria-label", words.share(done, shown.all));
|
|
263
|
-
|
|
264
|
-
|
|
368
|
+
const share = shown.all > 0 ? done / shown.all : 0;
|
|
369
|
+
const whole = shown.all > 0 ? String(Math.floor(100 * share)) : "";
|
|
370
|
+
const [before, middle, after] = words.progress(done, shown.all);
|
|
371
|
+
const bold = document.createElement("b");
|
|
372
|
+
bold.textContent = middle;
|
|
373
|
+
progressWords.replaceChildren(before, bold, after);
|
|
374
|
+
sharePercent.textContent = shown.all > 0 ? `${whole}%` : "";
|
|
375
|
+
const value = made("span", "percent-value", whole);
|
|
376
|
+
value.append(made("span", "percent-sign", "%"));
|
|
377
|
+
percent.replaceChildren(value);
|
|
378
|
+
drawRing(layout === "wide" ? 96 : 64, layout === "wide" ? 9 : 7, share);
|
|
379
|
+
openNumber.textContent = String(shown.open);
|
|
380
|
+
const [doneBefore, doneMiddle, doneAfter] = words.progress(done, shown.all);
|
|
381
|
+
bigDone.textContent = `${doneBefore}${doneMiddle}${doneAfter}`;
|
|
265
382
|
doneCount.textContent = String(done);
|
|
266
383
|
leftCount.textContent = String(shown.open);
|
|
384
|
+
fromCount.textContent = String(shown.documents);
|
|
385
|
+
// A tick an item (done first), or one bar past MOST_TICKS.
|
|
386
|
+
if (shown.all > MOST_TICKS) {
|
|
387
|
+
const on = made("i", "tick");
|
|
388
|
+
on.classList.add("gallery-todos-on");
|
|
389
|
+
on.style.flex = String(done);
|
|
390
|
+
const off = made("i", "tick");
|
|
391
|
+
off.style.flex = String(shown.open);
|
|
392
|
+
ticks.replaceChildren(on, off);
|
|
393
|
+
} else {
|
|
394
|
+
ticks.replaceChildren(...Array.from({ length: shown.all }, (_, index) => {
|
|
395
|
+
const tick = made("i", "tick");
|
|
396
|
+
tick.classList.toggle("gallery-todos-on", index < done);
|
|
397
|
+
return tick;
|
|
398
|
+
}));
|
|
399
|
+
}
|
|
267
400
|
face.dataset.state = shown.groups.length > 0 ? "items" : shown.all > 0 ? "done" : "none";
|
|
268
401
|
list.replaceChildren(...shown.groups.map((group) => {
|
|
269
402
|
const section = made("section", "group");
|
|
270
|
-
const title = made("
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
title
|
|
403
|
+
const title = made("div", "group-head");
|
|
404
|
+
const doc = made("button", "doc");
|
|
405
|
+
doc.type = "button";
|
|
406
|
+
doc.title = words.open(group.title);
|
|
407
|
+
doc.append(iconFor(group.slug, group.icon), group.title);
|
|
408
|
+
doc.addEventListener("click", () => open({ slug: group.slug }));
|
|
409
|
+
title.append(doc, made("span", "group-count", String(group.items.filter((todo) => !todo.done).length)));
|
|
274
410
|
const items = made("ul", "items");
|
|
275
411
|
for (const todo of group.items) {
|
|
276
412
|
const item = made("li", "item");
|
|
@@ -289,14 +425,21 @@ DocKit.component({
|
|
|
289
425
|
box.setAttribute("aria-checked", String(todo.done));
|
|
290
426
|
box.title = todo.done ? words.uncheck : words.check;
|
|
291
427
|
box.setAttribute("aria-label", `${todo.done ? words.uncheck : words.check}: ${todo.text}`);
|
|
292
|
-
|
|
428
|
+
const square = made("span", "box");
|
|
429
|
+
if (todo.done) square.innerHTML = TICK;
|
|
430
|
+
box.append(square);
|
|
293
431
|
box.addEventListener("click", (event) => {
|
|
294
432
|
event.stopPropagation();
|
|
295
433
|
check(todo);
|
|
296
434
|
});
|
|
297
435
|
item.append(box);
|
|
298
436
|
button.append(text);
|
|
299
|
-
} else
|
|
437
|
+
} else {
|
|
438
|
+
const square = made("span", "box");
|
|
439
|
+
if (todo.done) square.innerHTML = TICK;
|
|
440
|
+
item.append(square);
|
|
441
|
+
button.append(text);
|
|
442
|
+
}
|
|
300
443
|
// Its headings, but for the document's title the group's title above says (its first heading, as often).
|
|
301
444
|
const path = todo.path[0] === group.title ? todo.path.slice(1) : todo.path;
|
|
302
445
|
if (path.length > 0) button.append(made("span", "path", words.path(path)));
|
|
@@ -308,7 +451,10 @@ DocKit.component({
|
|
|
308
451
|
return section;
|
|
309
452
|
}));
|
|
310
453
|
list.scrollTop = top;
|
|
311
|
-
|
|
454
|
+
if (shown.groups.length > 0) sayEmpty(null);
|
|
455
|
+
else if (shown.all > 0) sayEmpty([words.allDone, words.allDoneSaid(shown.all)], "done");
|
|
456
|
+
else sayEmpty(asked.document === null ? words.empty : words.noneIn);
|
|
457
|
+
fade();
|
|
312
458
|
};
|
|
313
459
|
|
|
314
460
|
let asking = 0; // the last read asked: an older answer that comes after it is dropped
|
|
@@ -327,15 +473,16 @@ DocKit.component({
|
|
|
327
473
|
last = null;
|
|
328
474
|
count.textContent = "";
|
|
329
475
|
summary.hidden = true;
|
|
330
|
-
face.dataset.state = "
|
|
476
|
+
face.dataset.state = "unread";
|
|
331
477
|
list.replaceChildren();
|
|
332
|
-
|
|
478
|
+
sayEmpty(error?.code === "offline" ? words.offline : words.failed);
|
|
333
479
|
});
|
|
334
480
|
};
|
|
335
481
|
read();
|
|
336
482
|
return {
|
|
337
483
|
update(reason, detail) {
|
|
338
484
|
if (reason === "source" || (reason === "data" && detail === "todos")) read();
|
|
485
|
+
else if (reason === "layout") draw();
|
|
339
486
|
},
|
|
340
487
|
};
|
|
341
488
|
},
|
|
@@ -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="60.5" y="6.5" width="119" height="107" rx="8" fill="#ffffff" stroke="#e6e6e3"/><rect x="70" y="14" width="10" height="10" rx="3" fill="#efefed"/><rect x="84" y="16.5" width="30" height="5" rx="2.5" fill="#37352f"/><rect x="118" y="16.5" width="12" height="5" rx="2.5" fill="#d4d3cf"/><rect x="70" y="32" width="34" height="4" rx="2" fill="#a6a5a1"/><rect x="70" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="77.2" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="84.4" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="91.6" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="98.8" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="106" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="113.2" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="120.4" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="127.6" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="134.8" y="40" width="6" height="3" rx="1.5" fill="#4084cf"/><rect x="142" y="40" width="6" height="3" rx="1.5" fill="#e7e7e5"/><rect x="149.2" y="40" width="6" height="3" rx="1.5" fill="#e7e7e5"/><rect x="156.4" y="40" width="6" height="3" rx="1.5" fill="#e7e7e5"/><rect x="163.60000000000002" y="40" width="6" height="3" rx="1.5" fill="#e7e7e5"/><rect x="70" y="52" width="50" height="4" rx="2" fill="#a6a5a1"/><rect x="70.5" y="62.5" width="7" height="7" rx="2" fill="none" stroke="#bdbcb8"/><rect x="82" y="63" width="56" height="5" rx="2.5" fill="#37352f"/><rect x="82" y="71" width="30" height="3" rx="1.5" fill="#d4d3cf"/><rect x="70.5" y="78.5" width="7" height="7" rx="2" fill="none" stroke="#bdbcb8"/><rect x="82" y="79" width="44" height="5" rx="2.5" fill="#37352f"/><rect x="82" y="87" width="22" height="3" rx="1.5" fill="#d4d3cf"/><rect x="70.5" y="94.5" width="7" height="7" rx="2" fill="#4084cf" stroke="#4084cf"/><rect x="82" y="95" width="50" height="5" rx="2.5" fill="#d4d3cf"/><rect x="82" y="103" width="26" height="3" rx="1.5" fill="#d4d3cf"/></svg>
|