@jant/core 0.5.4 → 0.6.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/bin/commands/telegram/register-webhooks.js +93 -0
- package/dist/app-CMSW_AYG.js +6 -0
- package/dist/{app-BtNdUAqz.js → app-DYQdDMs8.js} +2249 -387
- package/dist/client/.vite/manifest.json +3 -3
- package/dist/client/_assets/client-BRTh1ii1.js +274 -0
- package/dist/client/_assets/client-CO4b-RKd.css +2 -0
- package/dist/client/_assets/{client-auth-DJ_5wx9N.js → client-auth-CSNcTJwP.js} +81 -81
- package/dist/{env-CgaH9Mut.js → env-C7e2Nlnt.js} +30 -1
- package/dist/{export-CR9Megtb.js → export-Bbn86HmS.js} +1 -1
- package/dist/{github-sync-DYZq9rQp.js → github-sync-CBQPRZ8H.js} +1 -1
- package/dist/{github-sync-8Vv06aCr.js → github-sync-dXsiZa_e.js} +2 -2
- package/dist/index.js +4 -4
- package/dist/node.js +61 -5
- package/package.json +2 -1
- package/src/__tests__/helpers/app.ts +15 -2
- package/src/app.tsx +3 -0
- package/src/client/thread-context.ts +146 -2
- package/src/client/tiptap/__tests__/link-toolbar.test.ts +1 -1
- package/src/client/tiptap/bubble-menu.ts +1 -16
- package/src/client/tiptap/extensions.ts +2 -6
- package/src/client/tiptap/link-toolbar.ts +0 -21
- package/src/client/tiptap/toolbar-mode.ts +0 -43
- package/src/db/migrations/0022_old_gressill.sql +24 -0
- package/src/db/migrations/0023_broad_terror.sql +20 -0
- package/src/db/migrations/0024_red_the_twelve.sql +3 -0
- package/src/db/migrations/0025_exotic_wendell_rand.sql +1 -0
- package/src/db/migrations/meta/0022_snapshot.json +2267 -0
- package/src/db/migrations/meta/0023_snapshot.json +2396 -0
- package/src/db/migrations/meta/0024_snapshot.json +2417 -0
- package/src/db/migrations/meta/0025_snapshot.json +2424 -0
- package/src/db/migrations/meta/_journal.json +28 -0
- package/src/db/migrations/pg/0020_bizarre_smasher.sql +24 -0
- package/src/db/migrations/pg/0021_sharp_puppet_master.sql +20 -0
- package/src/db/migrations/pg/0022_blushing_blue_shield.sql +3 -0
- package/src/db/migrations/pg/0023_organic_zemo.sql +1 -0
- package/src/db/migrations/pg/meta/0020_snapshot.json +2904 -0
- package/src/db/migrations/pg/meta/0021_snapshot.json +3060 -0
- package/src/db/migrations/pg/meta/0022_snapshot.json +3078 -0
- package/src/db/migrations/pg/meta/0023_snapshot.json +3084 -0
- package/src/db/migrations/pg/meta/_journal.json +28 -0
- package/src/db/pg/schema.ts +82 -0
- package/src/db/schema.ts +90 -0
- package/src/i18n/coverage.generated.ts +2 -2
- package/src/i18n/locales/public/en.po +8 -0
- package/src/i18n/locales/public/zh-Hans.po +8 -0
- package/src/i18n/locales/public/zh-Hant.po +8 -0
- package/src/i18n/locales/settings/en.po +135 -0
- package/src/i18n/locales/settings/en.ts +1 -1
- package/src/i18n/locales/settings/zh-Hans.po +136 -1
- package/src/i18n/locales/settings/zh-Hans.ts +1 -1
- package/src/i18n/locales/settings/zh-Hant.po +136 -1
- package/src/i18n/locales/settings/zh-Hant.ts +1 -1
- package/src/lib/__tests__/image-dimensions.test.ts +314 -0
- package/src/lib/__tests__/telegram-entities.test.ts +180 -0
- package/src/lib/__tests__/telegram-pool-webhooks.test.ts +127 -0
- package/src/lib/env.ts +45 -0
- package/src/lib/ids.ts +3 -0
- package/src/lib/image-dimensions.ts +258 -0
- package/src/lib/telegram-entities.ts +240 -0
- package/src/lib/telegram-pool-webhooks.ts +86 -0
- package/src/lib/telegram-settings-status.tsx +109 -0
- package/src/lib/telegram.ts +363 -0
- package/src/node/runtime.ts +6 -0
- package/src/routes/api/__tests__/telegram.test.ts +612 -0
- package/src/routes/api/telegram.ts +782 -0
- package/src/routes/api/upload-multipart.ts +34 -12
- package/src/routes/api/upload.ts +23 -2
- package/src/routes/dash/settings.tsx +131 -1
- package/src/routes/pages/__tests__/post-page-title.test.ts +70 -0
- package/src/routes/pages/page.tsx +3 -2
- package/src/runtime/cloudflare.ts +20 -9
- package/src/runtime/node.ts +20 -9
- package/src/runtime/site.ts +2 -1
- package/src/services/__tests__/telegram.test.ts +148 -0
- package/src/services/index.ts +9 -0
- package/src/services/telegram.ts +613 -0
- package/src/services/upload-session.ts +39 -12
- package/src/styles/tokens.css +1 -0
- package/src/styles/ui.css +117 -38
- package/src/types/app-context.ts +6 -0
- package/src/types/bindings.ts +3 -0
- package/src/types/config.ts +40 -0
- package/src/ui/dash/settings/SettingsRootContent.tsx +48 -17
- package/src/ui/dash/settings/TelegramContent.tsx +549 -0
- package/src/ui/feed/ThreadPreview.tsx +90 -38
- package/src/ui/feed/__tests__/thread-preview.test.ts +66 -5
- package/src/ui/pages/PostPage.tsx +77 -15
- package/dist/app-DLINgGBd.js +0 -6
- package/dist/client/_assets/client-BErXNT6k.css +0 -2
- package/dist/client/_assets/client-CtAgWT8i.js +0 -274
package/src/styles/tokens.css
CHANGED
package/src/styles/ui.css
CHANGED
|
@@ -2624,6 +2624,113 @@
|
|
|
2624
2624
|
var(--site-thread-dot-ring);
|
|
2625
2625
|
}
|
|
2626
2626
|
|
|
2627
|
+
/* Collapsible ancestor context wrapper.
|
|
2628
|
+
Server-rendered with `data-collapsed`. Crop and fade are always active
|
|
2629
|
+
while data-collapsed is set; JS only toggles the Show more/less button
|
|
2630
|
+
visibility based on real overflow. Negative left margin + matching
|
|
2631
|
+
padding extends the shell's box past the content edge so the dot
|
|
2632
|
+
markers (which live at left:-31.5px on desktop) survive
|
|
2633
|
+
`overflow: hidden`. `box-sizing: content-box` keeps the inner content
|
|
2634
|
+
width identical to before. */
|
|
2635
|
+
.thread-context-shell {
|
|
2636
|
+
position: relative;
|
|
2637
|
+
box-sizing: content-box;
|
|
2638
|
+
margin-left: -40px;
|
|
2639
|
+
padding-left: 40px;
|
|
2640
|
+
transition: max-height 0.32s cubic-bezier(0.4, 0, 0.2, 1);
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2643
|
+
.thread-context-shell[data-collapsed] {
|
|
2644
|
+
max-height: var(--site-thread-context-max-height);
|
|
2645
|
+
overflow: hidden;
|
|
2646
|
+
/* Soft fade at the bottom edge so the cap doesn't make a hard cut
|
|
2647
|
+
through text when content barely overflows. Combined with the
|
|
2648
|
+
shell's opacity:0.5 this produces a smooth "context drifts off"
|
|
2649
|
+
look instead of a guillotine slice right above the toggle. */
|
|
2650
|
+
-webkit-mask-image: linear-gradient(
|
|
2651
|
+
to bottom,
|
|
2652
|
+
black 0%,
|
|
2653
|
+
black 60%,
|
|
2654
|
+
transparent 100%
|
|
2655
|
+
);
|
|
2656
|
+
mask-image: linear-gradient(
|
|
2657
|
+
to bottom,
|
|
2658
|
+
black 0%,
|
|
2659
|
+
black 60%,
|
|
2660
|
+
transparent 100%
|
|
2661
|
+
);
|
|
2662
|
+
}
|
|
2663
|
+
|
|
2664
|
+
/* Push ancestor context slightly into the background — enough to feel
|
|
2665
|
+
secondary to the focused post but not so much that text becomes gray
|
|
2666
|
+
and hard to read. Combined with the mask-image bottom fade this gives
|
|
2667
|
+
a "context drifts into the background" effect without dimming the
|
|
2668
|
+
whole shell to the point of illegibility. */
|
|
2669
|
+
.thread-context-shell {
|
|
2670
|
+
opacity: 0.6;
|
|
2671
|
+
transition: opacity 0.22s ease;
|
|
2672
|
+
}
|
|
2673
|
+
|
|
2674
|
+
.thread-context-shell:not([data-collapsed]) {
|
|
2675
|
+
opacity: 1;
|
|
2676
|
+
}
|
|
2677
|
+
|
|
2678
|
+
/* Tighter padding for context items inside the shell so a single-line
|
|
2679
|
+
root post doesn't leave 64px of empty padding pushing the toggle
|
|
2680
|
+
button far below the visible text. Items outside the shell (hero,
|
|
2681
|
+
descendants on detail pages) keep the default --site-thread-item-spacing
|
|
2682
|
+
so the focused post still gets generous breathing room. */
|
|
2683
|
+
.thread-context-shell .thread-item {
|
|
2684
|
+
padding-top: 16px;
|
|
2685
|
+
padding-bottom: 16px;
|
|
2686
|
+
}
|
|
2687
|
+
|
|
2688
|
+
.thread-context-toggle[hidden] {
|
|
2689
|
+
display: none;
|
|
2690
|
+
}
|
|
2691
|
+
|
|
2692
|
+
.thread-context-toggle {
|
|
2693
|
+
display: inline-flex;
|
|
2694
|
+
align-items: center;
|
|
2695
|
+
gap: 0.3rem;
|
|
2696
|
+
margin: 0 0 6px;
|
|
2697
|
+
padding: 0.3rem 0;
|
|
2698
|
+
border: 0;
|
|
2699
|
+
background: transparent;
|
|
2700
|
+
color: var(--site-text-secondary);
|
|
2701
|
+
font-size: var(--type-thread-context-meta);
|
|
2702
|
+
line-height: 1.2;
|
|
2703
|
+
cursor: pointer;
|
|
2704
|
+
transition: color 0.18s ease;
|
|
2705
|
+
}
|
|
2706
|
+
|
|
2707
|
+
.thread-context-toggle:hover {
|
|
2708
|
+
color: var(--site-text-primary);
|
|
2709
|
+
}
|
|
2710
|
+
|
|
2711
|
+
.thread-context-toggle:focus-visible {
|
|
2712
|
+
outline: 2px solid var(--site-accent);
|
|
2713
|
+
outline-offset: 4px;
|
|
2714
|
+
border-radius: 2px;
|
|
2715
|
+
}
|
|
2716
|
+
|
|
2717
|
+
.thread-context-toggle-chevron {
|
|
2718
|
+
width: 10px;
|
|
2719
|
+
height: 10px;
|
|
2720
|
+
opacity: 0.7;
|
|
2721
|
+
transition:
|
|
2722
|
+
transform 0.2s ease,
|
|
2723
|
+
opacity 0.18s ease;
|
|
2724
|
+
}
|
|
2725
|
+
|
|
2726
|
+
.thread-context-toggle:hover .thread-context-toggle-chevron {
|
|
2727
|
+
opacity: 1;
|
|
2728
|
+
}
|
|
2729
|
+
|
|
2730
|
+
.thread-context-toggle[aria-expanded="true"] .thread-context-toggle-chevron {
|
|
2731
|
+
transform: rotate(180deg);
|
|
2732
|
+
}
|
|
2733
|
+
|
|
2627
2734
|
.thread-item-gap {
|
|
2628
2735
|
padding-top: 0.15rem;
|
|
2629
2736
|
padding-bottom: 0.35rem;
|
|
@@ -2701,6 +2808,16 @@
|
|
|
2701
2808
|
scroll-margin-top: 80px;
|
|
2702
2809
|
}
|
|
2703
2810
|
|
|
2811
|
+
/* When a child post has an ancestor shell above it (toggle button sits
|
|
2812
|
+
directly before the current post), leave enough room above the scroll
|
|
2813
|
+
landing so the user can see the Show more button + a peek of the
|
|
2814
|
+
faded shell on initial load. Otherwise everything above is hidden in
|
|
2815
|
+
the viewport and the user has to discover it by scrolling up. Sized
|
|
2816
|
+
for the ghost-style toggle (~28px) + a glimpse of the faded shell. */
|
|
2817
|
+
.thread-context-toggle + .thread-detail-item {
|
|
2818
|
+
scroll-margin-top: 120px;
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2704
2821
|
.thread-group-detail .thread-item-current::before {
|
|
2705
2822
|
background-color: var(--site-accent);
|
|
2706
2823
|
box-shadow:
|
|
@@ -9681,19 +9798,6 @@
|
|
|
9681
9798
|
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.15);
|
|
9682
9799
|
}
|
|
9683
9800
|
|
|
9684
|
-
.tiptap-bubble-menu-docked {
|
|
9685
|
-
left: 50% !important;
|
|
9686
|
-
top: auto !important;
|
|
9687
|
-
bottom: calc(
|
|
9688
|
-
env(safe-area-inset-bottom) + var(--tiptap-docked-offset, 16px)
|
|
9689
|
-
);
|
|
9690
|
-
transform: translateX(-50%);
|
|
9691
|
-
gap: 4px;
|
|
9692
|
-
padding: 6px;
|
|
9693
|
-
border-radius: 12px;
|
|
9694
|
-
max-width: calc(100vw - 24px);
|
|
9695
|
-
}
|
|
9696
|
-
|
|
9697
9801
|
.tiptap-bubble-menu::after {
|
|
9698
9802
|
content: "";
|
|
9699
9803
|
position: absolute;
|
|
@@ -9705,10 +9809,6 @@
|
|
|
9705
9809
|
border-top: 5px solid var(--color-foreground);
|
|
9706
9810
|
}
|
|
9707
9811
|
|
|
9708
|
-
.tiptap-bubble-menu-docked::after {
|
|
9709
|
-
display: none;
|
|
9710
|
-
}
|
|
9711
|
-
|
|
9712
9812
|
.tiptap-bubble-btn {
|
|
9713
9813
|
display: flex;
|
|
9714
9814
|
align-items: center;
|
|
@@ -9765,11 +9865,6 @@
|
|
|
9765
9865
|
flex: 1;
|
|
9766
9866
|
}
|
|
9767
9867
|
|
|
9768
|
-
.tiptap-link-input-docked .tiptap-link-input-fields {
|
|
9769
|
-
min-width: 0;
|
|
9770
|
-
width: 100%;
|
|
9771
|
-
}
|
|
9772
|
-
|
|
9773
9868
|
.tiptap-link-input-text {
|
|
9774
9869
|
border: none;
|
|
9775
9870
|
outline: none;
|
|
@@ -9785,17 +9880,6 @@
|
|
|
9785
9880
|
color: var(--color-muted-foreground);
|
|
9786
9881
|
}
|
|
9787
9882
|
|
|
9788
|
-
.tiptap-link-input-docked {
|
|
9789
|
-
left: 50% !important;
|
|
9790
|
-
top: auto !important;
|
|
9791
|
-
bottom: calc(
|
|
9792
|
-
env(safe-area-inset-bottom) + var(--tiptap-docked-offset, 16px)
|
|
9793
|
-
);
|
|
9794
|
-
transform: translateX(-50%);
|
|
9795
|
-
width: min(calc(100vw - 24px), 420px);
|
|
9796
|
-
max-width: calc(100vw - 24px);
|
|
9797
|
-
}
|
|
9798
|
-
|
|
9799
9883
|
.tiptap-link-input::before {
|
|
9800
9884
|
content: "";
|
|
9801
9885
|
position: absolute;
|
|
@@ -9818,11 +9902,6 @@
|
|
|
9818
9902
|
border-top: 5px solid var(--color-background);
|
|
9819
9903
|
}
|
|
9820
9904
|
|
|
9821
|
-
.tiptap-link-input-docked::before,
|
|
9822
|
-
.tiptap-link-input-docked::after {
|
|
9823
|
-
display: none;
|
|
9824
|
-
}
|
|
9825
|
-
|
|
9826
9905
|
.tiptap-link-input-field {
|
|
9827
9906
|
border: none;
|
|
9828
9907
|
outline: none;
|
package/src/types/app-context.ts
CHANGED
|
@@ -24,6 +24,12 @@ export type AppSession = Awaited<ReturnType<Auth["api"]["getSession"]>>;
|
|
|
24
24
|
|
|
25
25
|
export interface AppVariables {
|
|
26
26
|
services: Services;
|
|
27
|
+
/**
|
|
28
|
+
* Builds a `Services` object scoped to an arbitrary site. Used by
|
|
29
|
+
* host-agnostic handlers (e.g. the Telegram webhook) that resolve the
|
|
30
|
+
* target site from request data rather than the hostname.
|
|
31
|
+
*/
|
|
32
|
+
servicesForSite: (siteId: string) => Services;
|
|
27
33
|
hostedHandoff: HostedHandoffService;
|
|
28
34
|
auth: Auth;
|
|
29
35
|
currentSite: Site;
|
package/src/types/bindings.ts
CHANGED
|
@@ -53,6 +53,9 @@ export interface Bindings {
|
|
|
53
53
|
HOSTED_CONTROL_PLANE_PROVIDER_NAME?: EnvBindingValue;
|
|
54
54
|
HOSTED_CONTROL_PLANE_SSO_SECRET?: EnvBindingValue;
|
|
55
55
|
HOSTED_CONTROL_PLANE_INTERNAL_TOKEN?: EnvBindingValue;
|
|
56
|
+
// Telegram bot integration
|
|
57
|
+
TELEGRAM_BOT_TOKENS?: EnvBindingValue;
|
|
58
|
+
TELEGRAM_WEBHOOK_SECRET?: EnvBindingValue;
|
|
56
59
|
// Timeline
|
|
57
60
|
PAGE_SIZE?: EnvBindingValue;
|
|
58
61
|
SEARCH_PAGE_SIZE?: EnvBindingValue;
|
package/src/types/config.ts
CHANGED
|
@@ -396,6 +396,46 @@ export const CONFIG_FIELDS = {
|
|
|
396
396
|
envOnly: true,
|
|
397
397
|
envKeys: ["GITHUB_APP_WEBHOOK_SECRET"],
|
|
398
398
|
},
|
|
399
|
+
|
|
400
|
+
// Telegram bot pool (env-only). When TELEGRAM_BOT_TOKENS is set the bot
|
|
401
|
+
// tokens are platform-managed (hosted, or a single-site operator who opts
|
|
402
|
+
// in) and the settings UI hides the token field. Comma-separated list of
|
|
403
|
+
// `<bot_id>:<secret>` tokens; TELEGRAM_WEBHOOK_SECRET is the shared
|
|
404
|
+
// `secret_token` used when registering every pool bot's webhook.
|
|
405
|
+
TELEGRAM_BOT_TOKENS: {
|
|
406
|
+
defaultValue: "",
|
|
407
|
+
envOnly: true,
|
|
408
|
+
envKeys: ["TELEGRAM_BOT_TOKENS"],
|
|
409
|
+
},
|
|
410
|
+
TELEGRAM_WEBHOOK_SECRET: {
|
|
411
|
+
defaultValue: "",
|
|
412
|
+
envOnly: true,
|
|
413
|
+
envKeys: ["TELEGRAM_WEBHOOK_SECRET"],
|
|
414
|
+
},
|
|
415
|
+
|
|
416
|
+
// Telegram bring-your-own bot (DB-only, single-site, managed via the
|
|
417
|
+
// Telegram settings page when TELEGRAM_BOT_TOKENS is not set).
|
|
418
|
+
TELEGRAM_BOT_TOKEN: {
|
|
419
|
+
defaultValue: "",
|
|
420
|
+
envOnly: false,
|
|
421
|
+
internal: true,
|
|
422
|
+
},
|
|
423
|
+
TELEGRAM_BOT_ID: {
|
|
424
|
+
defaultValue: "",
|
|
425
|
+
envOnly: false,
|
|
426
|
+
internal: true,
|
|
427
|
+
},
|
|
428
|
+
TELEGRAM_BOT_USERNAME: {
|
|
429
|
+
defaultValue: "",
|
|
430
|
+
envOnly: false,
|
|
431
|
+
internal: true,
|
|
432
|
+
},
|
|
433
|
+
/** Per-site `secret_token` for a bring-your-own bot's webhook. */
|
|
434
|
+
TELEGRAM_BOT_WEBHOOK_SECRET: {
|
|
435
|
+
defaultValue: "",
|
|
436
|
+
envOnly: false,
|
|
437
|
+
internal: true,
|
|
438
|
+
},
|
|
399
439
|
} as const satisfies Record<string, ConfigField>;
|
|
400
440
|
|
|
401
441
|
export type ConfigKey = keyof typeof CONFIG_FIELDS;
|
|
@@ -24,6 +24,7 @@ const ICONS = {
|
|
|
24
24
|
key: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4"/><path d="m21 2-9.6 9.6"/><circle cx="7.5" cy="15.5" r="5.5"/></svg>`,
|
|
25
25
|
shield: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/></svg>`,
|
|
26
26
|
gitBranch: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" x2="6" y1="3" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>`,
|
|
27
|
+
send: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"/><path d="m21.854 2.147-10.94 10.939"/></svg>`,
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
export function SettingsRootContent({
|
|
@@ -114,23 +115,6 @@ export function SettingsRootContent({
|
|
|
114
115
|
}),
|
|
115
116
|
)}
|
|
116
117
|
/>
|
|
117
|
-
<SettingsDirectoryLink
|
|
118
|
-
href={toPublicPath("/settings/github-sync", sitePathPrefix)}
|
|
119
|
-
icon={ICONS.gitBranch}
|
|
120
|
-
tone="subtle"
|
|
121
|
-
name={i18n._(
|
|
122
|
-
msg({
|
|
123
|
-
message: "GitHub Sync",
|
|
124
|
-
comment: "@context: Settings item — GitHub sync settings",
|
|
125
|
-
}),
|
|
126
|
-
)}
|
|
127
|
-
description={i18n._(
|
|
128
|
-
msg({
|
|
129
|
-
message: "Back up and sync content with a GitHub repository",
|
|
130
|
-
comment: "@context: Settings item description for GitHub sync",
|
|
131
|
-
}),
|
|
132
|
-
)}
|
|
133
|
-
/>
|
|
134
118
|
</SettingsDirectorySection>
|
|
135
119
|
|
|
136
120
|
<SettingsDirectorySection
|
|
@@ -225,6 +209,53 @@ export function SettingsRootContent({
|
|
|
225
209
|
/>
|
|
226
210
|
</SettingsDirectorySection>
|
|
227
211
|
|
|
212
|
+
<SettingsDirectorySection
|
|
213
|
+
title={i18n._(
|
|
214
|
+
msg({
|
|
215
|
+
message: "Integrations",
|
|
216
|
+
comment:
|
|
217
|
+
"@context: Settings group label for third-party integrations",
|
|
218
|
+
}),
|
|
219
|
+
)}
|
|
220
|
+
>
|
|
221
|
+
<SettingsDirectoryLink
|
|
222
|
+
href={toPublicPath("/settings/github-sync", sitePathPrefix)}
|
|
223
|
+
icon={ICONS.gitBranch}
|
|
224
|
+
tone="subtle"
|
|
225
|
+
name={i18n._(
|
|
226
|
+
msg({
|
|
227
|
+
message: "GitHub Sync",
|
|
228
|
+
comment: "@context: Settings item — GitHub sync settings",
|
|
229
|
+
}),
|
|
230
|
+
)}
|
|
231
|
+
description={i18n._(
|
|
232
|
+
msg({
|
|
233
|
+
message: "Back up and sync content with a GitHub repository",
|
|
234
|
+
comment: "@context: Settings item description for GitHub sync",
|
|
235
|
+
}),
|
|
236
|
+
)}
|
|
237
|
+
/>
|
|
238
|
+
<SettingsDirectoryLink
|
|
239
|
+
href={toPublicPath("/settings/telegram", sitePathPrefix)}
|
|
240
|
+
icon={ICONS.send}
|
|
241
|
+
tone="subtle"
|
|
242
|
+
name={i18n._(
|
|
243
|
+
msg({
|
|
244
|
+
message: "Telegram",
|
|
245
|
+
comment:
|
|
246
|
+
"@context: Settings item — Telegram integration settings",
|
|
247
|
+
}),
|
|
248
|
+
)}
|
|
249
|
+
description={i18n._(
|
|
250
|
+
msg({
|
|
251
|
+
message: "Post notes by messaging a Telegram bot",
|
|
252
|
+
comment:
|
|
253
|
+
"@context: Settings item description for Telegram integration",
|
|
254
|
+
}),
|
|
255
|
+
)}
|
|
256
|
+
/>
|
|
257
|
+
</SettingsDirectorySection>
|
|
258
|
+
|
|
228
259
|
<SettingsDirectorySection
|
|
229
260
|
title={i18n._(
|
|
230
261
|
msg({
|