@heycys/gallery 0.1.2 → 0.2.0
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/icons.mjs +3 -0
- 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/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/emoji/line-icons.mjs +37 -0
- package/browser/shared/http.mjs +9 -0
- package/browser/shared/i18n/en.mjs +40 -17
- package/browser/shared/outline.mjs +30 -2
- 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/dist/chunk-2OHANJ6Q.mjs +2 -0
- package/dist/{chunk-QOUEFUCH.mjs → chunk-3MBRL2PM.mjs} +1 -1
- package/dist/{chunk-NWR2LT5B.mjs → chunk-4OKWZY5E.mjs} +1 -1
- package/dist/{chunk-RMECZA2K.mjs → chunk-5K44HLTZ.mjs} +1 -1
- package/dist/{chunk-NFMCP2HI.mjs → chunk-5XA2ZBAE.mjs} +2 -2
- package/dist/{chunk-OUUP3WKT.mjs → chunk-67N2QJYT.mjs} +1 -1
- package/dist/chunk-6KBYRA2C.mjs +2 -0
- package/dist/{chunk-SX4LJYT6.mjs → chunk-6N3PX4XX.mjs} +1 -1
- package/dist/{chunk-RFDZXFJF.mjs → chunk-7JDX4E65.mjs} +1 -1
- package/dist/chunk-7M2BQQGZ.mjs +2 -0
- package/dist/{chunk-ZUNVAXLH.mjs → chunk-7OG26PGF.mjs} +1 -1
- package/dist/{chunk-B4P2CM2J.mjs → chunk-AHN3NFKJ.mjs} +1 -1
- package/dist/chunk-ALZ6ZENZ.mjs +3 -0
- package/dist/{chunk-UGWYKHBL.mjs → chunk-AR5D57ZD.mjs} +2 -2
- package/dist/{chunk-W3BGBJQW.mjs → chunk-BFJGHSQN.mjs} +1 -1
- package/dist/{chunk-HLYV7RIH.mjs → chunk-CMA72MAG.mjs} +1 -1
- package/dist/{chunk-D4CKRD3V.mjs → chunk-DAZL73VK.mjs} +2 -2
- package/dist/{chunk-6VTU6KEO.mjs → chunk-DJISHPUL.mjs} +1 -1
- package/dist/{chunk-BPL64HGA.mjs → chunk-EAIFITAV.mjs} +1 -1
- package/dist/chunk-EP25HDAJ.mjs +2 -0
- package/dist/{chunk-6EZ7FNIK.mjs → chunk-F4ZA6JRZ.mjs} +1 -1
- package/dist/{chunk-3KJHLHUO.mjs → chunk-F6HVDZR4.mjs} +1 -1
- package/dist/{chunk-3NJACR4W.mjs → chunk-FDMAXMQA.mjs} +1 -1
- package/dist/chunk-FETSREUN.mjs +5 -0
- package/dist/{chunk-RKPWLGZ3.mjs → chunk-GHOYKMQ3.mjs} +1 -1
- package/dist/chunk-HDWTZ763.mjs +12 -0
- package/dist/{chunk-VTKNEYT3.mjs → chunk-HPOI4ZX7.mjs} +1 -1
- package/dist/{chunk-OW5NWPOJ.mjs → chunk-HXG7EOPJ.mjs} +1 -1
- package/dist/{chunk-V6RIYQZZ.mjs → chunk-ITOH5EGO.mjs} +1 -1
- package/dist/{chunk-ZWPMCK7P.mjs → chunk-IV64FFI4.mjs} +1 -1
- package/dist/chunk-J43Z6LSS.mjs +2 -0
- package/dist/chunk-J5PUIV3Y.mjs +4 -0
- package/dist/{chunk-KTKHRC6H.mjs → chunk-JA7G53PC.mjs} +1 -1
- package/dist/{chunk-NWFBE2YA.mjs → chunk-JLTZF4LA.mjs} +1 -1
- package/dist/{chunk-GY3FAUVM.mjs → chunk-JZT7I2OJ.mjs} +1 -1
- package/dist/{chunk-QKXMPUXC.mjs → chunk-K5XATEOO.mjs} +1 -1
- package/dist/chunk-L2SUIS5S.mjs +2 -0
- package/dist/{chunk-TEZAWDSQ.mjs → chunk-LM4XFQHZ.mjs} +1 -1
- package/dist/{chunk-5ZJA7CXT.mjs → chunk-MN7BZL4R.mjs} +1 -1
- package/dist/chunk-MTYYHM2G.mjs +15 -0
- package/dist/{chunk-HMYTM3GT.mjs → chunk-MXUBKDRO.mjs} +1 -1
- package/dist/{chunk-MHW7ZKOU.mjs → chunk-OEXWRJME.mjs} +1 -1
- package/dist/{chunk-CRJEG7MT.mjs → chunk-OFHXGWOX.mjs} +1 -1
- package/dist/chunk-ORID3AE7.mjs +166 -0
- package/dist/{chunk-32ZUEFZ7.mjs → chunk-PGDE24N5.mjs} +1 -1
- package/dist/{chunk-UNOYVIYR.mjs → chunk-POTA2FV4.mjs} +1 -1
- package/dist/{chunk-N7AZZLGT.mjs → chunk-QE5RG76S.mjs} +18 -17
- package/dist/{chunk-N76HWBA3.mjs → chunk-R2ZDLJYT.mjs} +1 -1
- package/dist/chunk-SWUTTZCN.mjs +2 -0
- package/dist/{chunk-POQSE4C2.mjs → chunk-TR7TWGHB.mjs} +1 -1
- package/dist/chunk-U5XL7D6A.mjs +3 -0
- package/dist/{chunk-PVER7LSC.mjs → chunk-U7NZI6N4.mjs} +2 -2
- package/dist/{chunk-Q47PLKIJ.mjs → chunk-UGWMMEJ5.mjs} +1 -1
- package/dist/chunk-UJQJKNGK.mjs +2 -0
- package/dist/chunk-UYVCQK3H.mjs +22 -0
- package/dist/{chunk-FJYN7RTH.mjs → chunk-VFX2KNHP.mjs} +1 -1
- package/dist/{chunk-UBBRTJ2R.mjs → chunk-VS7JIGJW.mjs} +1 -1
- package/dist/{chunk-NVRNLK25.mjs → chunk-W7665ZEC.mjs} +2 -2
- package/dist/{chunk-NG375ILQ.mjs → chunk-WQDQWCX5.mjs} +1 -1
- package/dist/chunk-YLPSMDIS.mjs +5 -0
- package/dist/{chunk-VXACTLO3.mjs → chunk-YNAWBAYN.mjs} +1 -1
- package/dist/{chunk-ZB4H7ZN4.mjs → chunk-YROX2O22.mjs} +1 -1
- package/dist/{chunk-YQGT4AB2.mjs → chunk-ZDLPUOAG.mjs} +1 -1
- package/dist/chunk-ZQS6H473.mjs +16 -0
- package/dist/{chunk-OJKMINIU.mjs → chunk-ZWWC4KLF.mjs} +15 -15
- 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/report.css +120 -41
- 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 +9 -9
- package/skill/SKILL.md +12 -12
- package/skill/references/building-blocks.md +4 -4
- package/skill/references/pages-and-data.md +13 -9
- package/skill/references/writing-html.md +2 -0
- package/web/assets/index-BM_K-Auu.css +1 -0
- package/web/assets/index-DRslOBiv.js +15 -0
- package/web/index.html +2 -2
- package/dist/chunk-2NRBY6AJ.mjs +0 -2
- package/dist/chunk-35NQ4PLQ.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-JVHHHGEA.mjs +0 -3
- package/dist/chunk-PZDLJJTJ.mjs +0 -3
- package/dist/chunk-SXHBYZST.mjs +0 -16
- 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
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
// gallery/recent (最近编辑): the workspace's documents edited last, the last first, read through
|
|
2
|
-
// context.workspace.query("recent") (its manifest's needs hold "workspace"
|
|
3
|
-
//
|
|
4
|
-
// (the
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
2
|
+
// context.workspace.query("recent") (its manifest's needs hold "workspace"; and "stats", for how many
|
|
3
|
+
// there are in all): each its page icon, its title and when it was edited. A click opens the document
|
|
4
|
+
// (context.workspace.open: the workbench goes there). It reads again whenever the workspace says the list
|
|
5
|
+
// changed (the `data` signal, "recent": a document written, renamed, given another icon, made or gone), and
|
|
6
|
+
// says the times again each minute (the kit's clock). It holds no part and writes nothing: all it shows is
|
|
7
|
+
// drawn (the manifest's `runtime`). Where the workspace cannot be read (an exported file, where it has no
|
|
8
|
+
// server; a server that does not answer) it says so. The words are the page's language (the UI's where
|
|
9
|
+
// Gallery says it, else the page's lang).
|
|
10
|
+
//
|
|
11
|
+
// Its face (the pack's design B, in the kit's card tokens): a head of the chip (a clock), 最近编辑 and how
|
|
12
|
+
// many of them were edited today, its quiet meta (今天 3 篇); then rows like the sidebar's, grouped by
|
|
13
|
+
// when (今天, 昨天, 本周, 更早: `groupOf`), each its icon, its title and its time at its end, said by its
|
|
14
|
+
// group (`whenOf`: today's 12 分钟前, or the hour once an hour has gone, 08:05; yesterday's its hour; this
|
|
15
|
+
// week's its weekday, 周二; earlier ones the date, 11月7日); under them, faint, how many more there are (还有
|
|
16
|
+
// 20 篇). The card shows whole rows only, as many as the room under its head holds with their groups'
|
|
17
|
+
// titles (`fit`, measured again as the card changes size: its own ResizeObserver on the face). A card two
|
|
18
|
+
// cells high (`data-layout` "short", by context.size) lists the last three, no groups, their times as a
|
|
19
|
+
// person says them (昨天, 周二). No document yet: the cards' empty face.
|
|
15
20
|
//
|
|
16
21
|
// A document's icon is drawn as Gallery's sidebar draws it, from the server that shows the page (its icon
|
|
17
22
|
// route, /__gallery/edit/icon, one picture of any icon's value): an emoji or a picture of its folder as a
|
|
@@ -21,35 +26,40 @@
|
|
|
21
26
|
const WORDS = {
|
|
22
27
|
zh: {
|
|
23
28
|
title: "最近编辑",
|
|
24
|
-
empty: "还没有文档",
|
|
25
|
-
offline: "在 Gallery
|
|
26
|
-
failed: "读不到工作区的文档",
|
|
29
|
+
empty: ["还没有文档", "新建一篇,或者让 Agent 写一篇"],
|
|
30
|
+
offline: ["在 Gallery 里打开时显示", "这里会列出最近改过的文档"],
|
|
31
|
+
failed: ["读不到工作区的文档", "过一会儿会再读"],
|
|
27
32
|
more: (/** @type {number} */ count) => `还有 ${count} 篇`,
|
|
28
33
|
today: (/** @type {number} */ count) => `今天 ${count} 篇`,
|
|
29
34
|
open: (/** @type {string} */ title) => `打开「${title}」`,
|
|
35
|
+
groups: { today: "今天", yesterday: "昨天", week: "本周", earlier: "更早" },
|
|
30
36
|
now: "刚刚",
|
|
31
37
|
minutes: (/** @type {number} */ count) => `${count} 分钟前`,
|
|
32
|
-
hours: (/** @type {number} */ count) => `${count} 小时前`,
|
|
33
38
|
yesterday: "昨天",
|
|
34
|
-
|
|
39
|
+
weekdays: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
|
|
35
40
|
date: (/** @type {Date} */ date, /** @type {boolean} */ thisYear) => (thisYear ? `${date.getMonth() + 1}月${date.getDate()}日` : `${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日`),
|
|
36
41
|
},
|
|
37
42
|
en: {
|
|
38
43
|
title: "Recently edited",
|
|
39
|
-
empty: "No documents yet",
|
|
40
|
-
offline: "
|
|
41
|
-
failed: "The workspace's documents could not be read",
|
|
44
|
+
empty: ["No documents yet", "Make one, or ask your Agent to write one"],
|
|
45
|
+
offline: ["Shown when opened in Gallery", "The documents edited last show here"],
|
|
46
|
+
failed: ["The workspace's documents could not be read", "It reads them again in a while"],
|
|
42
47
|
more: (/** @type {number} */ count) => `${count} more`,
|
|
43
48
|
today: (/** @type {number} */ count) => `${count} today`,
|
|
44
49
|
open: (/** @type {string} */ title) => `Open “${title}”`,
|
|
50
|
+
groups: { today: "Today", yesterday: "Yesterday", week: "This week", earlier: "Earlier" },
|
|
45
51
|
now: "just now",
|
|
46
52
|
minutes: (/** @type {number} */ count) => `${count} min ago`,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
days: (/** @type {number} */ count) => `${count} days ago`,
|
|
53
|
+
yesterday: "Yesterday",
|
|
54
|
+
weekdays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
|
50
55
|
date: (/** @type {Date} */ date, /** @type {boolean} */ thisYear) => `${["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][date.getMonth()]} ${date.getDate()}${thisYear ? "" : `, ${date.getFullYear()}`}`,
|
|
51
56
|
},
|
|
52
57
|
};
|
|
58
|
+
/** The documents it asks for: as many as the tallest card shows, and more. */
|
|
59
|
+
const LIMIT = 50;
|
|
60
|
+
/** A group's title and a row, in px (style.css). */
|
|
61
|
+
const GROUP_HEIGHT = 26;
|
|
62
|
+
const ROW_HEIGHT = 30;
|
|
53
63
|
|
|
54
64
|
/** The language the page speaks: the UI's where Gallery says it (data-ge-language), else its lang's. */
|
|
55
65
|
function languageOf(/** @type {HTMLElement} */ root) {
|
|
@@ -57,26 +67,43 @@ function languageOf(/** @type {HTMLElement} */ root) {
|
|
|
57
67
|
return (ui !== null ? ui === "en" : /^en(?:-|$)/i.test(root.lang)) ? "en" : "zh";
|
|
58
68
|
}
|
|
59
69
|
|
|
70
|
+
/** A local day, as a number of days. @param {Date} date */
|
|
71
|
+
const dayNumber = (date) => Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) / 86_400_000;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Which group a document edited at `edited` (an ISO time) is in, from `now` (the reader's clock): "today",
|
|
75
|
+
* "yesterday", "week" (earlier this week, from its Monday) or "earlier".
|
|
76
|
+
* @param {string} edited
|
|
77
|
+
* @param {Date} now
|
|
78
|
+
*/
|
|
79
|
+
function groupOf(edited, now) {
|
|
80
|
+
const then = new Date(edited);
|
|
81
|
+
const days = dayNumber(now) - dayNumber(then);
|
|
82
|
+
if (days <= 0) return "today";
|
|
83
|
+
if (days === 1) return "yesterday";
|
|
84
|
+
return days <= (now.getDay() + 6) % 7 ? "week" : "earlier";
|
|
85
|
+
}
|
|
86
|
+
|
|
60
87
|
/**
|
|
61
|
-
* When `edited` (an ISO time) was, from `now` (the reader's clock),
|
|
62
|
-
*
|
|
63
|
-
*
|
|
88
|
+
* When `edited` (an ISO time) was, from `now` (the reader's clock), in `language`: within the hour 刚刚
|
|
89
|
+
* and N 分钟前, then today's hour (08:05); yesterday's hour where its group says yesterday (`grouped`),
|
|
90
|
+
* else 昨天; a day earlier this week its weekday (周二); else its date, the year said when it is another.
|
|
64
91
|
* @param {string} edited
|
|
65
92
|
* @param {Date} now
|
|
66
93
|
* @param {"zh" | "en"} language
|
|
94
|
+
* @param {boolean} [grouped]
|
|
67
95
|
*/
|
|
68
|
-
function whenOf(edited, now, language) {
|
|
96
|
+
function whenOf(edited, now, language, grouped = true) {
|
|
69
97
|
const words = WORDS[language];
|
|
70
98
|
const then = new Date(edited);
|
|
71
99
|
const minutes = Math.floor((now.getTime() - then.getTime()) / 60_000);
|
|
72
100
|
if (!Number.isFinite(minutes)) return "";
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
if (
|
|
78
|
-
if (
|
|
79
|
-
if (days < 7) return words.days(days);
|
|
101
|
+
const two = (/** @type {number} */ value) => String(value).padStart(2, "0");
|
|
102
|
+
const hour = `${two(then.getHours())}:${two(then.getMinutes())}`;
|
|
103
|
+
const group = groupOf(edited, now);
|
|
104
|
+
if (group === "today") return minutes < 1 ? words.now : minutes < 60 ? words.minutes(minutes) : hour;
|
|
105
|
+
if (group === "yesterday") return grouped ? hour : words.yesterday;
|
|
106
|
+
if (group === "week") return words.weekdays[then.getDay()];
|
|
80
107
|
return words.date(then, then.getFullYear() === now.getFullYear());
|
|
81
108
|
}
|
|
82
109
|
|
|
@@ -124,79 +151,94 @@ function iconFor(/** @type {string} */ slug, /** @type {string | null} */ value)
|
|
|
124
151
|
|
|
125
152
|
DocKit.component({
|
|
126
153
|
id: "gallery/recent",
|
|
127
|
-
on: ["data", "clock"],
|
|
154
|
+
on: ["data", "clock", "layout"],
|
|
128
155
|
mount(host, context) {
|
|
129
156
|
const language = languageOf(document.documentElement);
|
|
130
157
|
const words = WORDS[language];
|
|
131
158
|
const face = made("div", "face");
|
|
132
159
|
const list = made("ul", "list");
|
|
133
|
-
const line = made("p", "line");
|
|
134
160
|
const head = made("div", "head");
|
|
135
161
|
const chip = made("span", "chip");
|
|
136
162
|
chip.setAttribute("aria-hidden", "true");
|
|
137
|
-
chip.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><
|
|
138
|
-
// Its quiet meta
|
|
163
|
+
chip.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="8.5"/><path d="M12 7.5V12l3 1.8"/></svg>';
|
|
164
|
+
// Its quiet meta after the title: how many of the documents were edited today.
|
|
139
165
|
const meta = made("span", "meta");
|
|
140
166
|
head.append(chip, made("span", "title", words.title), meta);
|
|
141
167
|
const more = made("p", "more");
|
|
142
168
|
more.hidden = true;
|
|
143
|
-
|
|
169
|
+
// No document, or no workspace: the cards' empty face.
|
|
170
|
+
const empty = made("div", "empty");
|
|
171
|
+
const emptyPicture = made("span", "empty-picture");
|
|
172
|
+
emptyPicture.setAttribute("aria-hidden", "true");
|
|
173
|
+
emptyPicture.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><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"/></svg>';
|
|
174
|
+
const line = made("p", "line");
|
|
175
|
+
const hint = made("p", "hint");
|
|
176
|
+
empty.append(emptyPicture, line, hint);
|
|
177
|
+
empty.hidden = true;
|
|
178
|
+
face.append(head, list, more, empty);
|
|
144
179
|
host.append(face);
|
|
145
|
-
// How many rows are below what the list shows (one cut off counted), said under it, or nothing.
|
|
146
|
-
const recount = () => {
|
|
147
|
-
const bottom = list.scrollTop + list.clientHeight;
|
|
148
|
-
let below = 0;
|
|
149
|
-
for (const row of /** @type {HTMLCollectionOf<HTMLElement>} */ (list.children)) if (row.offsetTop + row.offsetHeight > bottom + 1) below++;
|
|
150
|
-
const said = below > 0 ? words.more(below) : "";
|
|
151
|
-
if (more.textContent !== said) more.textContent = said;
|
|
152
|
-
more.hidden = below === 0;
|
|
153
|
-
};
|
|
154
|
-
// The list as high as the whole rows that fit the room under the head (with the line of more under it
|
|
155
|
-
// where they are not all shown), so that no row is cut at the card's bottom; the rest of the room under it.
|
|
156
|
-
const fit = () => {
|
|
157
|
-
list.style.maxHeight = "";
|
|
158
|
-
const rows = /** @type {HTMLCollectionOf<HTMLElement>} */ (list.children);
|
|
159
|
-
if (rows.length === 0 || list.clientHeight === 0) return void recount();
|
|
160
|
-
const pitch = rows[0].getBoundingClientRect().height;
|
|
161
|
-
more.hidden = true;
|
|
162
|
-
if (list.scrollHeight <= list.clientHeight + 1 || !(pitch > 0)) return void recount();
|
|
163
|
-
more.textContent = words.more(rows.length);
|
|
164
|
-
more.hidden = false;
|
|
165
|
-
const shown = Math.max(1, Math.floor((list.clientHeight + 0.5) / pitch));
|
|
166
|
-
list.style.maxHeight = `${shown * pitch}px`;
|
|
167
|
-
recount();
|
|
168
|
-
};
|
|
169
|
-
list.addEventListener("scroll", recount, { passive: true });
|
|
170
|
-
const watch = typeof ResizeObserver === "function" ? new ResizeObserver(() => fit()) : null;
|
|
171
|
-
watch?.observe(face);
|
|
172
|
-
context.signal?.addEventListener("abort", () => {
|
|
173
|
-
list.removeEventListener("scroll", recount);
|
|
174
|
-
watch?.disconnect();
|
|
175
|
-
}, { once: true });
|
|
176
180
|
const workspace = context.workspace;
|
|
177
181
|
if (!workspace) return void context.fail(new Error("its manifest's needs hold \"workspace\": context.workspace is not there"));
|
|
182
|
+
/** @type {Array<{ slug: string, title: string, icon: string | null, edited: string }> | null} */
|
|
183
|
+
let documents = null;
|
|
184
|
+
let total = 0;
|
|
178
185
|
/** @type {Array<{ node: HTMLElement, edited: string }>} */
|
|
179
186
|
let times = [];
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
187
|
+
let shown = -1;
|
|
188
|
+
const short = () => Boolean(context.size && context.size.h <= 2);
|
|
189
|
+
const say = (/** @type {string[] | null} */ said) => {
|
|
190
|
+
empty.hidden = said === null;
|
|
191
|
+
list.hidden = said !== null;
|
|
192
|
+
if (said === null) return;
|
|
193
|
+
line.textContent = said[0];
|
|
194
|
+
hint.textContent = said[1] ?? "";
|
|
183
195
|
};
|
|
184
196
|
// Each time said again, only where its words are others; the head's count of today's too.
|
|
185
197
|
const retime = () => {
|
|
186
198
|
const now = new Date();
|
|
187
|
-
let today = 0;
|
|
188
199
|
for (const { node, edited } of times) {
|
|
189
|
-
const said = whenOf(edited, now, language);
|
|
200
|
+
const said = whenOf(edited, now, language, !short());
|
|
190
201
|
if (node.textContent !== said) node.textContent = said;
|
|
191
|
-
const then = new Date(edited);
|
|
192
|
-
if (then.getFullYear() === now.getFullYear() && then.getMonth() === now.getMonth() && then.getDate() === now.getDate()) today++;
|
|
193
202
|
}
|
|
203
|
+
const today = (documents ?? []).filter(({ edited }) => groupOf(edited, now) === "today").length;
|
|
194
204
|
const counted = today > 0 ? words.today(today) : "";
|
|
195
205
|
if (meta.textContent !== counted) meta.textContent = counted;
|
|
196
206
|
};
|
|
197
|
-
|
|
207
|
+
// The rows the room under the head holds, whole, with their groups' titles (none on a short card), and
|
|
208
|
+
// a line of how many more there are: drawn again only when that is another number.
|
|
209
|
+
const fit = (/** @type {boolean} */ again = false) => {
|
|
210
|
+
if (!documents) return;
|
|
211
|
+
const layout = short() ? "short" : "full";
|
|
212
|
+
face.dataset.layout = layout;
|
|
213
|
+
const now = new Date();
|
|
214
|
+
// The room: the face's height under the head and the line of more (none measured where nothing lays it out: every row).
|
|
215
|
+
const room = face.clientHeight > 0 ? face.clientHeight - head.offsetHeight - (layout === "short" ? 4 : 6) - (layout === "short" ? 0 : 24) : Infinity;
|
|
216
|
+
let count = 0;
|
|
217
|
+
if (layout === "short") count = Math.min(3, documents.length);
|
|
218
|
+
else {
|
|
219
|
+
let used = 0;
|
|
220
|
+
let group = "";
|
|
221
|
+
for (const entry of documents) {
|
|
222
|
+
const next = groupOf(entry.edited, now);
|
|
223
|
+
const cost = (next !== group ? GROUP_HEIGHT : 0) + ROW_HEIGHT;
|
|
224
|
+
if (used + cost > room) break;
|
|
225
|
+
used += cost;
|
|
226
|
+
group = next;
|
|
227
|
+
count++;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
const key = `${layout}:${count}`;
|
|
231
|
+
if (!again && String(shown) === key) return;
|
|
232
|
+
shown = /** @type {any} */ (key);
|
|
198
233
|
times = [];
|
|
199
|
-
|
|
234
|
+
let group = "";
|
|
235
|
+
list.replaceChildren(...documents.slice(0, count).flatMap((entry) => {
|
|
236
|
+
const rows = [];
|
|
237
|
+
const next = groupOf(entry.edited, now);
|
|
238
|
+
if (layout === "full" && next !== group) {
|
|
239
|
+
rows.push(made("li", "group", words.groups[/** @type {keyof typeof words.groups} */ (next)]));
|
|
240
|
+
group = next;
|
|
241
|
+
}
|
|
200
242
|
const item = made("li", "item");
|
|
201
243
|
const button = made("button", "document");
|
|
202
244
|
button.type = "button";
|
|
@@ -207,24 +249,36 @@ DocKit.component({
|
|
|
207
249
|
button.append(iconFor(entry.slug, entry.icon), made("span", "name", entry.title), when);
|
|
208
250
|
button.addEventListener("click", () => workspace.open({ slug: entry.slug }));
|
|
209
251
|
item.append(button);
|
|
210
|
-
|
|
252
|
+
rows.push(item);
|
|
253
|
+
return rows;
|
|
211
254
|
}));
|
|
255
|
+
const below = Math.max(0, total - count);
|
|
256
|
+
more.hidden = below === 0 || layout === "short";
|
|
257
|
+
more.textContent = below > 0 ? words.more(below) : "";
|
|
212
258
|
retime();
|
|
213
|
-
say(documents.length === 0 ? words.empty : null);
|
|
214
|
-
fit();
|
|
215
259
|
};
|
|
260
|
+
const watch = typeof ResizeObserver === "function" ? new ResizeObserver(() => fit()) : null;
|
|
261
|
+
watch?.observe(face);
|
|
262
|
+
context.signal?.addEventListener("abort", () => watch?.disconnect(), { once: true });
|
|
216
263
|
let asking = 0; // the last read asked: an older answer that comes after it is dropped
|
|
217
264
|
const read = () => {
|
|
218
265
|
const ticket = ++asking;
|
|
219
|
-
workspace.query("
|
|
220
|
-
|
|
266
|
+
const counted = workspace.query("stats").then(({ data }) => data?.documents ?? null, () => null);
|
|
267
|
+
workspace.query("recent", { limit: LIMIT }).then(async ({ data }) => {
|
|
268
|
+
const all = await counted;
|
|
269
|
+
if (ticket !== asking || context.signal.aborted) return;
|
|
270
|
+
documents = data;
|
|
271
|
+
total = typeof all === "number" ? Math.max(all, data.length) : data.length;
|
|
272
|
+
say(data.length === 0 ? words.empty : null);
|
|
273
|
+
fit(true);
|
|
221
274
|
}, (/** @type {any} */ error) => {
|
|
222
275
|
if (ticket !== asking || context.signal.aborted) return;
|
|
276
|
+
documents = null;
|
|
223
277
|
times = [];
|
|
224
278
|
meta.textContent = "";
|
|
225
279
|
list.replaceChildren();
|
|
280
|
+
more.hidden = true;
|
|
226
281
|
say(error?.code === "offline" ? words.offline : words.failed);
|
|
227
|
-
fit();
|
|
228
282
|
});
|
|
229
283
|
};
|
|
230
284
|
read();
|
|
@@ -232,6 +286,7 @@ DocKit.component({
|
|
|
232
286
|
update(reason, detail) {
|
|
233
287
|
if (reason === "data" && detail === "recent") read();
|
|
234
288
|
else if (reason === "clock") retime();
|
|
289
|
+
else if (reason === "layout") fit();
|
|
235
290
|
},
|
|
236
291
|
};
|
|
237
292
|
},
|
|
@@ -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="16" height="5" rx="2.5" fill="#d4d3cf"/><rect x="70" y="32" width="12" height="4" rx="2" fill="#a6a5a1"/><rect x="70" y="41" width="7" height="7" rx="2" fill="#f6c264"/><rect x="81" y="42" width="52" height="5" rx="2.5" fill="#37352f"/><rect x="158" y="42.5" width="12" height="4" rx="2" fill="#d4d3cf"/><rect x="70" y="54" width="7" height="7" rx="2" fill="#e8a3a3"/><rect x="81" y="55" width="44" height="5" rx="2.5" fill="#37352f"/><rect x="158" y="55.5" width="12" height="4" rx="2" fill="#d4d3cf"/><rect x="70" y="67" width="7" height="7" rx="2" fill="#9fc3ef"/><rect x="81" y="68" width="38" height="5" rx="2.5" fill="#37352f"/><rect x="158" y="68.5" width="12" height="4" rx="2" fill="#d4d3cf"/><rect x="70" y="88" width="7" height="7" rx="2" fill="#b8d79a"/><rect x="81" y="89" width="48" height="5" rx="2.5" fill="#37352f"/><rect x="158" y="89.5" width="12" height="4" rx="2" fill="#d4d3cf"/><rect x="70" y="101" width="7" height="7" rx="2" fill="#c9b3ec"/><rect x="81" y="102" width="36" height="5" rx="2.5" fill="#37352f"/><rect x="158" y="102.5" width="12" height="4" rx="2" fill="#d4d3cf"/><rect x="70" y="79" width="12" height="4" rx="2" fill="#a6a5a1"/></svg>
|
|
@@ -1,158 +1,85 @@
|
|
|
1
1
|
/* Every selector starts at the instance and goes down a step at a time (>), so that nothing here
|
|
2
|
-
reaches the rest of the page. The
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
reaches the rest of the page. The pack's design B, in the kit's card tokens: the head (the chip, a
|
|
3
|
+
clock, 最近编辑 and how many were edited today, faint), its end clear of the card's grip; rows like the
|
|
4
|
+
sidebar's (30px, out to the face's edges by 6px so that a row's hover fill has room), each its icon, its
|
|
5
|
+
title and its time at its end, faint; the groups' titles (今天, 昨天, 本周, 更早) small, faint and 600; and
|
|
6
|
+
under them how many more there are, faint. A short card (data-layout "short") lists three, no groups.
|
|
7
|
+
No document: the cards' empty face in the middle. A document's icon as the sidebar draws it (a picture,
|
|
8
|
+
a glyph masked in the faint color, or a page drawn here). Light and dark. */
|
|
9
9
|
[data-doc-component="gallery/recent"] {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
box-sizing: border-box;
|
|
16
|
-
height: 100%;
|
|
17
|
-
min-height: 0;
|
|
18
|
-
color: var(--gallery-text);
|
|
19
|
-
font-size: 14px;
|
|
20
|
-
line-height: 1.45;
|
|
21
|
-
}
|
|
10
|
+
font-family: var(--gallery-font);
|
|
11
|
+
font-size: 13px;
|
|
12
|
+
line-height: 1.5;
|
|
13
|
+
color: var(--gallery-text);
|
|
14
|
+
> .gallery-recent-face { display: flex; flex-direction: column; box-sizing: border-box; min-height: 0; }
|
|
22
15
|
> .gallery-recent-face > .gallery-recent-head {
|
|
23
16
|
display: flex;
|
|
24
17
|
align-items: center;
|
|
25
18
|
gap: 8px;
|
|
26
19
|
flex: none;
|
|
20
|
+
height: 20px;
|
|
27
21
|
min-width: 0;
|
|
28
22
|
padding-inline-end: var(--gallery-grip-room, 0px);
|
|
29
23
|
}
|
|
30
24
|
> .gallery-recent-face > .gallery-recent-head > .gallery-recent-chip {
|
|
31
25
|
flex: none;
|
|
32
|
-
display:
|
|
33
|
-
|
|
34
|
-
justify-content: center;
|
|
26
|
+
display: grid;
|
|
27
|
+
place-items: center;
|
|
35
28
|
width: var(--gallery-chip-size);
|
|
36
29
|
height: var(--gallery-chip-size);
|
|
37
30
|
border-radius: var(--gallery-chip-radius);
|
|
38
|
-
background: var(--gallery-
|
|
39
|
-
color: var(--gallery-
|
|
40
|
-
}
|
|
41
|
-
> .gallery-recent-face > .gallery-recent-head > .gallery-recent-chip > svg { width: var(--gallery-chip-icon); height: var(--gallery-chip-icon); }
|
|
42
|
-
> .gallery-recent-face > .gallery-recent-head > .gallery-recent-title {
|
|
43
|
-
flex: 1 1 auto;
|
|
44
|
-
min-width: 0;
|
|
45
|
-
overflow: hidden;
|
|
46
|
-
white-space: nowrap;
|
|
47
|
-
text-overflow: ellipsis;
|
|
48
|
-
font-size: var(--gallery-title-size);
|
|
49
|
-
line-height: var(--gallery-title-line);
|
|
50
|
-
font-weight: 600;
|
|
51
|
-
color: var(--gallery-text-strong);
|
|
52
|
-
}
|
|
53
|
-
> .gallery-recent-face > .gallery-recent-head > .gallery-recent-meta { flex: none; font-size: var(--gallery-meta-size); color: var(--doc-muted); white-space: nowrap; font-variant-numeric: tabular-nums; margin-inline-end: calc(-1 * var(--gallery-grip-room, 0px)); opacity: calc(1 - var(--gallery-grip-shown, 0)); transition: opacity .12s ease-out; }
|
|
54
|
-
> .gallery-recent-face > .gallery-recent-list {
|
|
55
|
-
flex: 1 1 auto;
|
|
56
|
-
min-height: 0;
|
|
57
|
-
margin: -2px -6px 0;
|
|
58
|
-
padding: 0;
|
|
59
|
-
list-style: none;
|
|
60
|
-
position: relative;
|
|
61
|
-
overflow-y: auto;
|
|
62
|
-
overscroll-behavior: contain;
|
|
63
|
-
scrollbar-width: thin;
|
|
31
|
+
background: var(--gallery-fill);
|
|
32
|
+
color: var(--gallery-muted);
|
|
64
33
|
}
|
|
34
|
+
> .gallery-recent-face > .gallery-recent-head > .gallery-recent-chip > svg { display: block; width: var(--gallery-chip-icon); height: var(--gallery-chip-icon); }
|
|
35
|
+
> .gallery-recent-face > .gallery-recent-head > .gallery-recent-title { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: var(--gallery-title-size); line-height: var(--gallery-title-line); font-weight: 600; color: var(--gallery-text); }
|
|
36
|
+
> .gallery-recent-face > .gallery-recent-head > .gallery-recent-meta { flex: none; font-size: var(--gallery-meta-size); color: var(--gallery-faint); white-space: nowrap; }
|
|
37
|
+
> .gallery-recent-face > .gallery-recent-list { flex: 1 1 auto; min-height: 0; margin: 6px -6px 0; padding: 0; overflow: hidden; list-style: none; }
|
|
38
|
+
> .gallery-recent-face[data-layout="short"] > .gallery-recent-list { margin-top: 4px; }
|
|
39
|
+
> .gallery-recent-face > .gallery-recent-list[hidden] { display: none; }
|
|
40
|
+
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-group { padding: 8px 6px 2px; font-size: 11.5px; line-height: 16px; font-weight: 600; color: var(--gallery-faint); }
|
|
65
41
|
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-item > .gallery-recent-document {
|
|
66
42
|
display: flex;
|
|
67
43
|
align-items: center;
|
|
68
|
-
gap:
|
|
44
|
+
gap: 8px;
|
|
69
45
|
box-sizing: border-box;
|
|
70
46
|
width: 100%;
|
|
71
|
-
|
|
72
|
-
padding: 6px;
|
|
47
|
+
height: 30px;
|
|
48
|
+
padding: 0 6px;
|
|
73
49
|
border: 0;
|
|
74
50
|
border-radius: 6px;
|
|
75
|
-
background:
|
|
51
|
+
background: none;
|
|
76
52
|
font: inherit;
|
|
77
53
|
color: inherit;
|
|
78
54
|
text-align: start;
|
|
79
55
|
cursor: pointer;
|
|
80
56
|
}
|
|
81
|
-
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-item > .gallery-recent-document:hover { background: var(--
|
|
82
|
-
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-item > .gallery-recent-document
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
width: 18px;
|
|
88
|
-
height: 18px;
|
|
89
|
-
color: var(--doc-muted);
|
|
90
|
-
}
|
|
91
|
-
/* A document with no icon: a page, drawn as the sidebar's (a folded corner), in the muted color. */
|
|
92
|
-
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-item > .gallery-recent-document > .gallery-recent-icon:empty:not(.gallery-recent-glyph)::before {
|
|
93
|
-
content: "";
|
|
94
|
-
display: block;
|
|
95
|
-
width: 13px;
|
|
96
|
-
height: 16px;
|
|
97
|
-
background: currentColor;
|
|
98
|
-
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 13 16'%3E%3Cpath d='M2 .75h6.2l4.05 4.05V14A1.25 1.25 0 0 1 11 15.25H2A1.25 1.25 0 0 1 .75 14V2A1.25 1.25 0 0 1 2 .75z M8 1v3.5a.75.75 0 0 0 .75.75H12' fill='none' stroke='black' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
|
|
99
|
-
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 13 16'%3E%3Cpath d='M2 .75h6.2l4.05 4.05V14A1.25 1.25 0 0 1 11 15.25H2A1.25 1.25 0 0 1 .75 14V2A1.25 1.25 0 0 1 2 .75z M8 1v3.5a.75.75 0 0 0 .75.75H12' fill='none' stroke='black' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
|
|
100
|
-
}
|
|
101
|
-
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-item > .gallery-recent-document > .gallery-recent-glyph {
|
|
102
|
-
background: currentColor;
|
|
103
|
-
-webkit-mask: var(--gallery-recent-icon) center / 16px no-repeat;
|
|
104
|
-
mask: var(--gallery-recent-icon) center / 16px no-repeat;
|
|
105
|
-
}
|
|
106
|
-
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-item > .gallery-recent-document > .gallery-recent-picture > img { display: block; width: 16px; height: 16px; object-fit: contain; border-radius: 3px; }
|
|
107
|
-
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-item > .gallery-recent-document > .gallery-recent-name {
|
|
108
|
-
flex: 1 1 auto;
|
|
109
|
-
min-width: 0;
|
|
110
|
-
overflow: hidden;
|
|
111
|
-
white-space: nowrap;
|
|
112
|
-
text-overflow: ellipsis;
|
|
113
|
-
}
|
|
114
|
-
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-item > .gallery-recent-document > .gallery-recent-when { flex: none; font-size: var(--gallery-meta-size); color: var(--doc-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
|
|
115
|
-
/* What it says where it lists nothing: in the middle of what the card has left, muted, a quiet
|
|
116
|
-
picture of a page over it. */
|
|
117
|
-
> .gallery-recent-face > .gallery-recent-line {
|
|
118
|
-
flex: 1 1 auto;
|
|
119
|
-
display: flex;
|
|
120
|
-
flex-direction: column;
|
|
121
|
-
align-items: center;
|
|
122
|
-
justify-content: center;
|
|
123
|
-
gap: 8px;
|
|
124
|
-
margin: 0;
|
|
125
|
-
padding: 8px 12px;
|
|
126
|
-
font-size: 13px;
|
|
127
|
-
color: var(--doc-muted);
|
|
128
|
-
text-align: center;
|
|
129
|
-
}
|
|
130
|
-
> .gallery-recent-face > .gallery-recent-line::before {
|
|
57
|
+
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-item > .gallery-recent-document:hover { background: var(--gallery-hover); }
|
|
58
|
+
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-item > .gallery-recent-document:focus-visible { outline: 2px solid var(--gallery-accent-wash); outline-offset: -2px; }
|
|
59
|
+
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-item > .gallery-recent-document > .gallery-recent-icon { flex: none; display: grid; place-items: center; width: 18px; height: 18px; }
|
|
60
|
+
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-item > .gallery-recent-document > .gallery-recent-picture > img { display: block; width: 15px; height: 15px; object-fit: contain; }
|
|
61
|
+
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-item > .gallery-recent-document > .gallery-recent-glyph::before { content: ""; width: 15px; height: 15px; background: var(--gallery-faint); -webkit-mask: var(--gallery-recent-icon) center / contain no-repeat; mask: var(--gallery-recent-icon) center / contain no-repeat; }
|
|
62
|
+
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-item > .gallery-recent-document > .gallery-recent-icon:empty::before {
|
|
131
63
|
content: "";
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 44 44'%3E%3Ccircle cx='22' cy='22' r='22' fill-opacity='.14'/%3E%3Cg transform='translate(11 11) scale(.9167)' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 3v4a1 1 0 0 0 1 1h4'/%3E%3Cpath d='M17 21H7a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7l5 5v11a2 2 0 0 1-2 2z'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
|
|
138
|
-
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 44 44'%3E%3Ccircle cx='22' cy='22' r='22' fill-opacity='.14'/%3E%3Cg transform='translate(11 11) scale(.9167)' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 3v4a1 1 0 0 0 1 1h4'/%3E%3Cpath d='M17 21H7a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7l5 5v11a2 2 0 0 1-2 2z'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
|
|
139
|
-
}
|
|
140
|
-
> .gallery-recent-face > .gallery-recent-line[hidden] { display: none; }
|
|
141
|
-
/* How many more are below what the list shows. */
|
|
142
|
-
> .gallery-recent-face > .gallery-recent-more {
|
|
143
|
-
flex: none;
|
|
144
|
-
margin: -2px 0 0;
|
|
145
|
-
font-size: var(--gallery-meta-size);
|
|
146
|
-
line-height: 16px;
|
|
147
|
-
color: var(--doc-muted);
|
|
64
|
+
width: 15px;
|
|
65
|
+
height: 15px;
|
|
66
|
+
background: var(--gallery-faint);
|
|
67
|
+
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath 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'/%3E%3Cpath d='M13.5 3.5V8H18'/%3E%3C/svg%3E") center / contain no-repeat;
|
|
68
|
+
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath 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'/%3E%3Cpath d='M13.5 3.5V8H18'/%3E%3C/svg%3E") center / contain no-repeat;
|
|
148
69
|
}
|
|
70
|
+
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-item > .gallery-recent-document > .gallery-recent-name { flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 13px; color: var(--gallery-text); }
|
|
71
|
+
> .gallery-recent-face > .gallery-recent-list > .gallery-recent-item > .gallery-recent-document > .gallery-recent-when { flex: none; font-size: 12px; color: var(--gallery-faint); white-space: nowrap; font-variant-numeric: tabular-nums; }
|
|
72
|
+
> .gallery-recent-face > .gallery-recent-more { flex: none; margin: 0; padding-top: 6px; font-size: 12px; line-height: 18px; color: var(--gallery-faint); }
|
|
149
73
|
> .gallery-recent-face > .gallery-recent-more[hidden] { display: none; }
|
|
74
|
+
/* No document, or no workspace: the cards' empty face in the middle. */
|
|
75
|
+
> .gallery-recent-face > .gallery-recent-empty { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; min-height: 0; text-align: center; }
|
|
76
|
+
> .gallery-recent-face > .gallery-recent-empty[hidden] { display: none; }
|
|
77
|
+
> .gallery-recent-face > .gallery-recent-empty > p { margin: 0; }
|
|
78
|
+
> .gallery-recent-face > .gallery-recent-empty > .gallery-recent-empty-picture { display: grid; place-items: center; width: 28px; height: 28px; margin-bottom: 6px; border-radius: 8px; background: var(--gallery-fill); color: var(--gallery-faint); }
|
|
79
|
+
> .gallery-recent-face > .gallery-recent-empty > .gallery-recent-empty-picture > svg { width: 16px; height: 16px; }
|
|
80
|
+
> .gallery-recent-face > .gallery-recent-empty > .gallery-recent-line { font-size: 13.5px; line-height: 20px; font-weight: 600; color: var(--gallery-text); }
|
|
81
|
+
> .gallery-recent-face > .gallery-recent-empty > .gallery-recent-hint { font-size: 12px; line-height: 18px; color: var(--gallery-faint); }
|
|
150
82
|
}
|
|
151
|
-
/* On a custom page the face
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
.gallery-card > [data-doc-component="gallery/recent"] { height: 100%; container-type: size; }
|
|
155
|
-
@container (max-height: 150px) {
|
|
156
|
-
[data-doc-component="gallery/recent"] > .gallery-recent-face > .gallery-recent-line { padding-block: 0; }
|
|
157
|
-
[data-doc-component="gallery/recent"] > .gallery-recent-face > .gallery-recent-line::before { display: none; }
|
|
158
|
-
}
|
|
83
|
+
/* On a custom page the face fills the card the board frames. */
|
|
84
|
+
.gallery-card > [data-doc-component="gallery/recent"] { height: 100%; }
|
|
85
|
+
.gallery-card > [data-doc-component="gallery/recent"] > .gallery-recent-face { height: 100%; }
|
|
@@ -4,7 +4,7 @@ A card for a custom page (its places are `page`, its needs `workspace`): the doc
|
|
|
4
4
|
|
|
5
5
|
## How to write it
|
|
6
6
|
|
|
7
|
-
Put it on a custom page as a card of its board, `<section class="gallery-card" data-card-id="…" data-x data-y data-w data-h>`, holding one instance, after `gallery block add recent`: the instance is empty, `<div data-doc-component="gallery/recent"></div>`, everything on it drawn by its script. It has no settings and holds no data: there is nothing to fill in and nothing it writes. Sizes: 4 ×
|
|
7
|
+
Put it on a custom page as a card of its board, `<section class="gallery-card" data-card-id="…" data-x data-y data-w data-h>`, holding one instance, after `gallery block add recent`: the instance is empty, `<div data-doc-component="gallery/recent"></div>`, everything on it drawn by its script. It has no settings and holds no data: there is nothing to fill in and nothing it writes. Sizes: 4 × 4 (the default), 4 × 2 (the last three, no groups) and 4 × 6 are the ones its menu lists; it is 4 wide and any height from 2 to 8 cells. As many whole rows as the card holds, and how many more there are under them.
|
|
8
8
|
|
|
9
9
|
## What the user does
|
|
10
10
|
|
|
@@ -12,4 +12,4 @@ Clicks a document: it opens. The list follows by itself: a document written, ren
|
|
|
12
12
|
|
|
13
13
|
## How it looks
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
In Gallery 风格's look (the kit's card tokens, light and dark): a head of a small gray chip and a title, its end clear of the card's grip; one hero; the rest small and gray; the accent on the data and on today alone. Its head is a clock's chip, 最近编辑 and how many were edited today; then rows like the sidebar's, grouped as 今天, 昨天, 本周 and 更早, each the document's icon, its title and its time at its end (12 分钟前, then the hour; yesterday's hour; this week's weekday, 周二; earlier ones the date). A row under the pointer takes the hover's gray. No document yet: it says so in the middle.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "gallery/static",
|
|
3
3
|
"apiVersion": 1,
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.0",
|
|
5
5
|
"name": { "zh": "静态卡片", "en": "Static card" },
|
|
6
6
|
"description": { "zh": "放一段任意的 HTML,只展示,不能在页面上改", "en": "Any HTML, shown as it is: nothing on it changes in the page" },
|
|
7
7
|
"words": "jingtaikapian jingtai kapian static html card 静态 卡片 展示 内容",
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
"content": { "at": ":scope > div", "edit": "none" }
|
|
10
10
|
},
|
|
11
11
|
"places": ["page"],
|
|
12
|
-
"card": { "sizes": [[4,
|
|
12
|
+
"card": { "sizes": [[4, 4], [4, 2], [8, 2], [2, 2], [4, 1], [2, 1]], "min": { "w": 1, "h": 1 }, "max": { "w": 12, "h": 24 }, "resize": true }
|
|
13
13
|
}
|