@jant/core 0.5.3 → 0.6.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/bin/commands/telegram/register-webhooks.js +93 -0
- package/dist/{app-C481ssbr.js → app-BIkkbVQk.js} +2252 -383
- package/dist/app-Bcr5_wZI.js +6 -0
- package/dist/client/.vite/manifest.json +3 -3
- package/dist/client/_assets/client-Bo7sKkAQ.js +274 -0
- package/dist/client/_assets/client-QHRvzZwk.css +2 -0
- package/dist/client/_assets/{client-auth-CfBiCAB7.js → client-auth-D1jDQgbH.js} +49 -49
- 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/components/jant-compose-editor.ts +72 -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/paste-media.ts +49 -33
- package/src/client/tiptap/toolbar-mode.ts +0 -43
- package/src/client/video-processor.ts +9 -0
- 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__/mp4-track-flags.test.ts +117 -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/mp4-track-flags.ts +71 -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 +134 -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 +91 -38
- package/src/ui/feed/__tests__/thread-preview.test.ts +67 -5
- package/src/ui/pages/PostPage.tsx +78 -15
- package/dist/app-BgMwEN-M.js +0 -6
- package/dist/client/_assets/client-CJQYvkEx.js +0 -274
- package/dist/client/_assets/client-CQvi1Buw.css +0 -2
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 into the visual background so the focused post
|
|
2665
|
+
below the shell (latest reply on the home feed, anchor post on the
|
|
2666
|
+
detail page) reads as the primary content. Opacity works on both real
|
|
2667
|
+
painted content AND empty space, sidestepping the gradient-on-empty
|
|
2668
|
+
visibility problem. The dots inside the shell get muted along with
|
|
2669
|
+
the content, which actually reinforces the "this is background" feel
|
|
2670
|
+
— the rail line itself lives on `.thread-group::before` and stays at
|
|
2671
|
+
full strength. */
|
|
2672
|
+
.thread-context-shell {
|
|
2673
|
+
opacity: 0.5;
|
|
2674
|
+
transition: opacity 0.22s ease;
|
|
2675
|
+
}
|
|
2676
|
+
|
|
2677
|
+
/* When the user expands the shell, restore full strength — they've
|
|
2678
|
+
opted in to reading the context. */
|
|
2679
|
+
.thread-context-shell:not([data-collapsed]) {
|
|
2680
|
+
opacity: 1;
|
|
2681
|
+
}
|
|
2682
|
+
|
|
2683
|
+
/* Hide the legacy gradient-overlay element — opacity replaces it. */
|
|
2684
|
+
.thread-context-fade {
|
|
2685
|
+
display: none;
|
|
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,15 @@
|
|
|
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. */
|
|
2816
|
+
.thread-context-toggle + .thread-detail-item {
|
|
2817
|
+
scroll-margin-top: 152px;
|
|
2818
|
+
}
|
|
2819
|
+
|
|
2704
2820
|
.thread-group-detail .thread-item-current::before {
|
|
2705
2821
|
background-color: var(--site-accent);
|
|
2706
2822
|
box-shadow:
|
|
@@ -4432,6 +4548,24 @@
|
|
|
4432
4548
|
position: relative;
|
|
4433
4549
|
}
|
|
4434
4550
|
|
|
4551
|
+
jant-compose-editor.compose-editor-dragover {
|
|
4552
|
+
position: relative;
|
|
4553
|
+
}
|
|
4554
|
+
|
|
4555
|
+
jant-compose-editor.compose-editor-dragover::after {
|
|
4556
|
+
content: "";
|
|
4557
|
+
position: absolute;
|
|
4558
|
+
inset: 6px;
|
|
4559
|
+
z-index: 5;
|
|
4560
|
+
pointer-events: none;
|
|
4561
|
+
border-radius: 14px;
|
|
4562
|
+
background: color-mix(in srgb, var(--site-accent) 4%, transparent);
|
|
4563
|
+
box-shadow:
|
|
4564
|
+
inset 0 0 0 1.5px color-mix(in srgb, var(--site-accent) 45%, transparent),
|
|
4565
|
+
inset 0 0 28px -12px
|
|
4566
|
+
color-mix(in srgb, var(--site-accent) 45%, transparent);
|
|
4567
|
+
}
|
|
4568
|
+
|
|
4435
4569
|
.compose-edit-loading {
|
|
4436
4570
|
display: flex;
|
|
4437
4571
|
flex: 1;
|
|
@@ -9663,19 +9797,6 @@
|
|
|
9663
9797
|
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.15);
|
|
9664
9798
|
}
|
|
9665
9799
|
|
|
9666
|
-
.tiptap-bubble-menu-docked {
|
|
9667
|
-
left: 50% !important;
|
|
9668
|
-
top: auto !important;
|
|
9669
|
-
bottom: calc(
|
|
9670
|
-
env(safe-area-inset-bottom) + var(--tiptap-docked-offset, 16px)
|
|
9671
|
-
);
|
|
9672
|
-
transform: translateX(-50%);
|
|
9673
|
-
gap: 4px;
|
|
9674
|
-
padding: 6px;
|
|
9675
|
-
border-radius: 12px;
|
|
9676
|
-
max-width: calc(100vw - 24px);
|
|
9677
|
-
}
|
|
9678
|
-
|
|
9679
9800
|
.tiptap-bubble-menu::after {
|
|
9680
9801
|
content: "";
|
|
9681
9802
|
position: absolute;
|
|
@@ -9687,10 +9808,6 @@
|
|
|
9687
9808
|
border-top: 5px solid var(--color-foreground);
|
|
9688
9809
|
}
|
|
9689
9810
|
|
|
9690
|
-
.tiptap-bubble-menu-docked::after {
|
|
9691
|
-
display: none;
|
|
9692
|
-
}
|
|
9693
|
-
|
|
9694
9811
|
.tiptap-bubble-btn {
|
|
9695
9812
|
display: flex;
|
|
9696
9813
|
align-items: center;
|
|
@@ -9747,11 +9864,6 @@
|
|
|
9747
9864
|
flex: 1;
|
|
9748
9865
|
}
|
|
9749
9866
|
|
|
9750
|
-
.tiptap-link-input-docked .tiptap-link-input-fields {
|
|
9751
|
-
min-width: 0;
|
|
9752
|
-
width: 100%;
|
|
9753
|
-
}
|
|
9754
|
-
|
|
9755
9867
|
.tiptap-link-input-text {
|
|
9756
9868
|
border: none;
|
|
9757
9869
|
outline: none;
|
|
@@ -9767,17 +9879,6 @@
|
|
|
9767
9879
|
color: var(--color-muted-foreground);
|
|
9768
9880
|
}
|
|
9769
9881
|
|
|
9770
|
-
.tiptap-link-input-docked {
|
|
9771
|
-
left: 50% !important;
|
|
9772
|
-
top: auto !important;
|
|
9773
|
-
bottom: calc(
|
|
9774
|
-
env(safe-area-inset-bottom) + var(--tiptap-docked-offset, 16px)
|
|
9775
|
-
);
|
|
9776
|
-
transform: translateX(-50%);
|
|
9777
|
-
width: min(calc(100vw - 24px), 420px);
|
|
9778
|
-
max-width: calc(100vw - 24px);
|
|
9779
|
-
}
|
|
9780
|
-
|
|
9781
9882
|
.tiptap-link-input::before {
|
|
9782
9883
|
content: "";
|
|
9783
9884
|
position: absolute;
|
|
@@ -9800,11 +9901,6 @@
|
|
|
9800
9901
|
border-top: 5px solid var(--color-background);
|
|
9801
9902
|
}
|
|
9802
9903
|
|
|
9803
|
-
.tiptap-link-input-docked::before,
|
|
9804
|
-
.tiptap-link-input-docked::after {
|
|
9805
|
-
display: none;
|
|
9806
|
-
}
|
|
9807
|
-
|
|
9808
9904
|
.tiptap-link-input-field {
|
|
9809
9905
|
border: none;
|
|
9810
9906
|
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({
|