From a4477753386e423ac986682621f9f3e02b303f11 Mon Sep 17 00:00:00 2001 From: snipsnipsnip Date: Sat, 18 Oct 2025 22:10:17 +0900 Subject: [PATCH 1/7] docs: add some comments --- src/app-background/compose_action_notifier.ts | 1 + src/app-background/menu_handler.ts | 2 ++ src/thunderbird/background_util/alarm_heart.ts | 6 ++++++ 3 files changed, 9 insertions(+) diff --git a/src/app-background/compose_action_notifier.ts b/src/app-background/compose_action_notifier.ts index e964f5d..14828a4 100644 --- a/src/app-background/compose_action_notifier.ts +++ b/src/app-background/compose_action_notifier.ts @@ -1,6 +1,7 @@ import type { EmailEditorFactory, IComposeWindow, IGhostServerPort } from "src/ghosttext-adaptor" import type { GhostTextStarter } from "src/ghosttext-runner" +/** Responsible for interacting with compose windows */ export class ComposeActionNotifier { static isSingleton = true private readonly runners = new Map() diff --git a/src/app-background/menu_handler.ts b/src/app-background/menu_handler.ts index 1e77d8c..a740e2f 100644 --- a/src/app-background/menu_handler.ts +++ b/src/app-background/menu_handler.ts @@ -16,6 +16,8 @@ export class MenuHandler { // Compare the shown menu with menuItems and (re-)initialize the menu if necessary console.debug(info) + // We've tried more sophisticated logic here, but corner cases like users changing their UI language often + // make it fail, so we ended up with a simple check: We (re-)initialize the menu when the user first opens the menu. if (!this.buttonMenu.isInitialized()) { console.debug("Initializing menu") return this.buttonMenu.initItems(this.menuItems, info) diff --git a/src/thunderbird/background_util/alarm_heart.ts b/src/thunderbird/background_util/alarm_heart.ts index a8bb9b2..5b378f4 100644 --- a/src/thunderbird/background_util/alarm_heart.ts +++ b/src/thunderbird/background_util/alarm_heart.ts @@ -1,11 +1,17 @@ import type { IHeart } from "src/ghosttext-runner" +import type { Alarm } from "src/thunderbird" +/** Tries to prevent background script from MV3 suspension of the background script */ export class AlarmHeart implements IHeart { /** Should be set if the onAlarm listener has been registered */ private isListenerReady = false constructor(readonly messenger: typeof globalThis.messenger) {} + /** + * Should be called after the onAlarm listener has been registered. + * Due to MV3 restriction, the event listener must be registered at the toplevel. + */ assumeReady(): void { this.isListenerReady = true } From 88a9dd3cf8aa6a1a58a684e26b62dce2f01e41c4 Mon Sep 17 00:00:00 2001 From: snipsnipsnip Date: Sat, 18 Oct 2025 22:13:37 +0900 Subject: [PATCH 2/7] refactor: add a check when enabling the alarm utility --- src/root/background.ts | 12 +++++++++--- src/root/startup/startup_background.ts | 3 --- src/thunderbird/background_util/alarm_heart.ts | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/root/background.ts b/src/root/background.ts index 81083e4..3e47198 100644 --- a/src/root/background.ts +++ b/src/root/background.ts @@ -4,6 +4,7 @@ */ import type { BackgroundEventRouter, MenuItem, MenuShownInfo } from "src/app-background" +import type { Alarm } from "src/thunderbird" import { type LazyThen, makeLazyThen } from "src/util/lazy_then" console.info("starting", import.meta.url) @@ -28,9 +29,16 @@ const prepareThen: LazyThen = makeLazyThen(async () => { ] let heart = new AlarmHeart(messenger) + // Set the ready flag that promises the alarm event handler is registered + heart.ready(onAlarm) + return prepareBackgroundRouter({ messenger, heart, optionsSyncCtor, menuItems }) }) +function onAlarm(alarm: Alarm): void { + console.debug("beep", alarm) +} + messenger.composeAction.onClicked.addListener((tab, _info): Promise | void => prepareThen((router) => router.handleComposeAction(tab)), ) @@ -51,9 +59,7 @@ messenger.runtime.onMessage.addListener((msg, sender, sendResponse): Promise { - console.debug("beep", alarm) -}) +messenger.alarms.onAlarm.addListener(onAlarm) messenger.menus.onShown.addListener((info, tab) => prepareThen((router) => { diff --git a/src/root/startup/startup_background.ts b/src/root/startup/startup_background.ts index d56327d..32cf987 100644 --- a/src/root/startup/startup_background.ts +++ b/src/root/startup/startup_background.ts @@ -33,8 +33,5 @@ export const startupBackground = (consts: BackgroundConstants): WirelessInjector export function prepareBackgroundRouter(consts: BackgroundConstants): BackgroundEventRouter { let startup = startupBackground(consts) - // Set the ready flag that promises the alarm event handler is registered - consts.heart.assumeReady() - return startup(BackgroundEventRouter) } diff --git a/src/thunderbird/background_util/alarm_heart.ts b/src/thunderbird/background_util/alarm_heart.ts index 5b378f4..dabf2fe 100644 --- a/src/thunderbird/background_util/alarm_heart.ts +++ b/src/thunderbird/background_util/alarm_heart.ts @@ -12,8 +12,8 @@ export class AlarmHeart implements IHeart { * Should be called after the onAlarm listener has been registered. * Due to MV3 restriction, the event listener must be registered at the toplevel. */ - assumeReady(): void { - this.isListenerReady = true + ready(registeredCallback: (alarm: Alarm) => void): void { + this.isListenerReady = this.messenger.alarms.onAlarm.hasListener(registeredCallback) } startBeat(): () => void { From 337e36e78969047e730fc8070a9b06aeb187da48 Mon Sep 17 00:00:00 2001 From: snipsnipsnip Date: Fri, 17 Oct 2025 20:57:02 +0900 Subject: [PATCH 3/7] docs: update the PR template --- .github/pull_request_template.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 50803a2..6c90c2c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,14 +1,13 @@ +____ + * [ ] I agree that my contributions will be [dual-licensed under (MPL-2.0 OR GPL-3.0-or-later)](https://github.com/exteditor/ghostbird/blob/main/LICENSE). -## What kind of change does this PR introduce? +____ -- [ ] New feature -- [ ] Bugfix -- [ ] Documentation -- [ ] Typo fix -- [ ] Other + +@coderabbitai ## What is the current behavior? From 73b45ab949f7eb79a6eb9d4b793b2b304dc61ff9 Mon Sep 17 00:00:00 2001 From: snipsnipsnip Date: Mon, 20 Oct 2025 21:50:39 +0900 Subject: [PATCH 4/7] docs: fix links in README * Fix links to license website * Link to the Thunderbird ESR download page --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 53274af..d4dc4fb 100644 --- a/README.md +++ b/README.md @@ -62,9 +62,9 @@ Alternatively, you can: 1. Launch your favorite text editor. 2. Start the GhostText server in your text editor (e.g., with `:GhostTextStart` in Vim). -3. Press the gray Ghostbird button in the Thunderbird mail compose window. (The default shortcut is ^Ctrl+⇧Shift+H) - * If the connection is successful, the button will turn blue . - * If the connection fails, the button will turn red . Make sure that the GhostText server is listening. See [Troubleshooting page of original GhostText](https://ghosttext.fregante.com/troubleshooting/#unable-to-connect). +3. Press the gray Ghostbird button Gray button in the Thunderbird mail compose window. (The default shortcut is ^Ctrl+⇧Shift+H) + * If the connection is successful, the button will turn blue Blue button. + * If the connection fails, the button will turn red Red button. Make sure that the GhostText server is listening. See [Troubleshooting page of original GhostText](https://ghosttext.fregante.com/troubleshooting/#unable-to-connect). 4. Write your email in the text editor. 5. Close your text editor to stop Ghostbird. @@ -268,13 +268,13 @@ If you've looked at the options above and still want to motivate the maintainer ## License -[![License: MPL-2.0](https://img.shields.io/badge/license-MPL--2.0-00d230?logo=mozilla)](./LICENSE.mpl) -[![License: GPLv3](https://img.shields.io/badge/license-GPLv3-bd0000?logo=gplv3&logoSize=auto)](./LICENSE.gpl)
+[![License: MPL-2.0](https://img.shields.io/badge/license-MPL--2.0-00d230?logo=mozilla)](https://www.mozilla.org/en-US/MPL/2.0/) +[![License: GPLv3](https://img.shields.io/badge/license-GPLv3-bd0000?logo=gplv3&logoSize=auto)](https://www.gnu.org/licenses/gpl-3.0.html)
Ghostbird is [dual-licensed under (MPL-2.0 OR GPL-3.0-or-later)](./LICENSE). See also [NOTICE](./ext/NOTICE.md). [proj]: https://github.com/exteditor/ghostbird/projects [milestones]: https://github.com/exteditor/ghostbird/milestones -[tb]: https://thunderbird.net/ +[tb]: https://www.thunderbird.net/download/esr/ [gt]: https://ghosttext.fregante.com/ [helix]: https://github.com/rahji/helix-ghost [rels]: https://github.com/exteditor/ghostbird/releases From e08e75c0dcf4dbcb20a0f6fa96034d18af96d627 Mon Sep 17 00:00:00 2001 From: snipsnipsnip Date: Fri, 17 Oct 2025 21:40:08 +0900 Subject: [PATCH 5/7] ci: define components in the codecov config * Also remove catch-all `src/` definition from the Codecov config --- .github/codecov.yml | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/.github/codecov.yml b/.github/codecov.yml index 24e2f3f..3e4fa1e 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -1,10 +1,18 @@ -coverage: - status: - project: - src: +comment: + layout: "header, components" + +component_management: + default_rules: + statuses: + - type: project informational: true - paths: ["src/**/*", "!src/test/**/*"] - patch: - src: + - type: patch informational: true - paths: ["src/**/*", "!src/test/**/*"] + + individual_components: + - component_id: app + paths: ["src/app**"] + - component_id: ghosttext + paths: ["src/ghosttext**"] + - component_id: infra + paths: ["src/**", "!src/app**", "!src/ghosttext**", "!src/test/**", "!src/util/**"] From 3c5ef0be4fda6ebadab9d83af5ac1d4422fff81d Mon Sep 17 00:00:00 2001 From: snipsnipsnip Date: Fri, 17 Oct 2025 19:54:36 +0900 Subject: [PATCH 6/7] ci: don't build branches created for automation --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index df10c7a..c5ce1a5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,7 @@ name: Build on: push: - branches-ignore: [ 'wip/*' ] + branches-ignore: [ 'coderabbit**', 'gh-**' ] jobs: build: From 7bb1fbfbb17a7fc85196d5a31f615c18deab1aad Mon Sep 17 00:00:00 2001 From: snipsnipsnip Date: Mon, 20 Oct 2025 21:38:04 +0900 Subject: [PATCH 7/7] ci: configure website with docsify --- .github/site/coverpage.md | 13 ++++ .github/site/homepage.md | 151 ++++++++++++++++++++++++++++++++++++++ .github/site/index.html | 16 ++++ .github/site/index.mjs | 49 +++++++++++++ .github/workflows/doc.yml | 8 +- 5 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 .github/site/coverpage.md create mode 100644 .github/site/homepage.md create mode 100644 .github/site/index.html create mode 100644 .github/site/index.mjs diff --git a/.github/site/coverpage.md b/.github/site/coverpage.md new file mode 100644 index 0000000..7614fc4 --- /dev/null +++ b/.github/site/coverpage.md @@ -0,0 +1,13 @@ + +![logo](../ext/blue.svg) + +# Ghostbird + +> Compose email in your favorite text editor +> +>