From c96def314ea455062aeadced78c30fe70ec943ee Mon Sep 17 00:00:00 2001 From: Dharmesh Date: Fri, 10 Oct 2025 18:13:30 +0530 Subject: [PATCH 1/8] feat(status-bar): enhance functionality with action service integration and improve status updates --- .../src/content_scripts/batch.ts | 5 +- .../src/content_scripts/config.ts | 7 +- .../src/content_scripts/index.ts | 2 + apps/acf-extension/src/manifest.json | 10 +- .../core/common/src/lib/model/core-model.ts | 1 + .../chrome/messenger/action.messenger.ts | 30 +++- .../src/lib/background/chrome/runtime.ts | 2 +- .../core/service/src/lib/action.service.ts | 12 ++ packages/shared/status-bar/src/index.ts | 2 + .../shared/status-bar/src/lib/status-bar.ts | 157 ++++++------------ packages/shared/status-bar/tsconfig.json | 3 + packages/shared/status-bar/tsconfig.lib.json | 3 + 12 files changed, 109 insertions(+), 125 deletions(-) diff --git a/apps/acf-extension/src/content_scripts/batch.ts b/apps/acf-extension/src/content_scripts/batch.ts index 1fb7666a..37043ee2 100644 --- a/apps/acf-extension/src/content_scripts/batch.ts +++ b/apps/acf-extension/src/content_scripts/batch.ts @@ -29,7 +29,7 @@ const BatchProcessor = (() => { statusBar.batchUpdate(i + 2); console.groupCollapsed(`${BATCH_I18N.TITLE} #${i + 2} [${I18N_COMMON.REPEAT}]`); if (batch?.repeatInterval) { - await statusBar.wait(batch?.repeatInterval, STATUS_BAR_TYPE.BATCH_REPEAT, i + 2); + await statusBar.wait(batch?.repeatInterval, STATUS_BAR_TYPE.BATCH_REPEAT); } await Actions.start(actions, i + 2); const { notifications } = await new SettingsStorage().getSettings(); @@ -50,7 +50,7 @@ const BatchProcessor = (() => { while (true) { if (batch?.repeatInterval) { statusBar.batchUpdate('∞'); - await statusBar.wait(batch?.repeatInterval, STATUS_BAR_TYPE.BATCH_REPEAT, '∞'); + await statusBar.wait(batch?.repeatInterval, STATUS_BAR_TYPE.BATCH_REPEAT); } await Actions.start(actions, i); i += 1; @@ -61,7 +61,6 @@ const BatchProcessor = (() => { const start = async (actions: Array, batch?: IBatch) => { try { - statusBar.batchUpdate(1); console.groupCollapsed(`${BATCH_I18N.TITLE} #1 (${I18N_COMMON.DEFAULT})`); await Actions.start(actions, 1); console.groupEnd(); diff --git a/apps/acf-extension/src/content_scripts/config.ts b/apps/acf-extension/src/content_scripts/config.ts index 5ba77ef5..8af5b23d 100644 --- a/apps/acf-extension/src/content_scripts/config.ts +++ b/apps/acf-extension/src/content_scripts/config.ts @@ -142,17 +142,12 @@ const ConfigProcessor = (() => { } }; - const setupStatusBar = async () => { - const { statusBar: statusBarLocation } = await new SettingsStorage().getSettings(); - statusBar.setLocation(statusBarLocation); - }; - const checkStartType = async (configs: Array, config?: IConfiguration) => { - setupStatusBar(); configs.forEach((c) => { Hotkey.setup(start.bind(this, c), c.hotkey); }); if (config) { + statusBar.enable(config.actions.length, config.batch?.repeat); await checkStartTime(config); await start(config); } diff --git a/apps/acf-extension/src/content_scripts/index.ts b/apps/acf-extension/src/content_scripts/index.ts index 1c1fee28..27be4a0a 100644 --- a/apps/acf-extension/src/content_scripts/index.ts +++ b/apps/acf-extension/src/content_scripts/index.ts @@ -34,6 +34,8 @@ async function loadConfig(loadType: ELoadTypes) { } } else if (manualConfigs.length > 0 && loadType === ELoadTypes.DOCUMENT) { await ConfigProcessor.checkStartType(manualConfigs); + } else { + statusBar.disable(); } }); } catch (e) { diff --git a/apps/acf-extension/src/manifest.json b/apps/acf-extension/src/manifest.json index 14c80b5e..45c6bea4 100644 --- a/apps/acf-extension/src/manifest.json +++ b/apps/acf-extension/src/manifest.json @@ -16,7 +16,15 @@ "128": "assets/icons/icon128.png" }, "action": { - "default_icon": "assets/icons/icon64.png" + "default_icon": { + "16": "assets/icons/icon16.png", + "32": "assets/icons/icon32.png", + "48": "assets/icons/icon48.png", + "64": "assets/icons/icon64.png", + "96": "assets/icons/icon96.png", + "128": "assets/icons/icon128.png" + }, + "default_title": "↗ Options Page" }, "background": { "service_worker": "background.js", diff --git a/packages/core/common/src/lib/model/core-model.ts b/packages/core/common/src/lib/model/core-model.ts index de686b17..bf62550a 100644 --- a/packages/core/common/src/lib/model/core-model.ts +++ b/packages/core/common/src/lib/model/core-model.ts @@ -11,6 +11,7 @@ export interface IExtension { __currentActionName: string; __actionError: string; __actionRepeat: number; + __addonRecheck: number; __batchRepeat: number; __sessionCount: number; __sheets?: ISheets; diff --git a/packages/core/extension/src/lib/background/chrome/messenger/action.messenger.ts b/packages/core/extension/src/lib/background/chrome/messenger/action.messenger.ts index 4cca3f6c..5023f788 100644 --- a/packages/core/extension/src/lib/background/chrome/messenger/action.messenger.ts +++ b/packages/core/extension/src/lib/background/chrome/messenger/action.messenger.ts @@ -1,23 +1,35 @@ export interface ActionRequest { messenger: 'action'; - methodName: 'setIcon' | 'setBadgeBackgroundColor' | 'setBadgeText' | 'setTitle'; + methodName: 'setIcon' | 'setBadgeBackgroundColor' | 'setBadgeText' | 'setTitle' | 'setBadgeTextColor' | 'enable' | 'disable'; message: chrome.action.TabIconDetails | chrome.action.BadgeColorDetails | chrome.action.BadgeTextDetails | chrome.action.TitleDetails; } export class ActionMessenger { - setIcon(details: chrome.action.TabIconDetails) { - return chrome.action.setIcon(details); + disable(sender: chrome.runtime.MessageSender) { + return chrome.action.disable(sender.tab?.id); } - setBadgeBackgroundColor(details: chrome.action.BadgeColorDetails) { - return chrome.action.setBadgeBackgroundColor(details); + enable(sender: chrome.runtime.MessageSender) { + return chrome.action.enable(sender.tab?.id); } - setBadgeText(details: chrome.action.BadgeTextDetails) { - return chrome.action.setBadgeText(details); + setIcon(details: chrome.action.TabIconDetails, sender: chrome.runtime.MessageSender) { + return chrome.action.setIcon({ ...details, tabId: sender.tab?.id }); } - setTitle(details: chrome.action.TitleDetails) { - return chrome.action.setTitle(details); + setBadgeBackgroundColor(details: chrome.action.BadgeColorDetails, sender: chrome.runtime.MessageSender) { + return chrome.action.setBadgeBackgroundColor({ ...details, tabId: sender.tab?.id }); + } + + setBadgeText(details: chrome.action.BadgeTextDetails, sender: chrome.runtime.MessageSender) { + return chrome.action.setBadgeText({ ...details, tabId: sender.tab?.id }); + } + + setBadgeTextColor(details: chrome.action.BadgeColorDetails, sender: chrome.runtime.MessageSender) { + return chrome.action.setBadgeTextColor({ ...details, tabId: sender.tab?.id }); + } + + setTitle(details: chrome.action.TitleDetails, sender: chrome.runtime.MessageSender) { + return chrome.action.setTitle({ ...details, tabId: sender.tab?.id }); } } diff --git a/packages/core/extension/src/lib/background/chrome/runtime.ts b/packages/core/extension/src/lib/background/chrome/runtime.ts index e0aca0d9..e4d37233 100644 --- a/packages/core/extension/src/lib/background/chrome/runtime.ts +++ b/packages/core/extension/src/lib/background/chrome/runtime.ts @@ -18,7 +18,7 @@ export const messageListener = async (request: any, sender: chrome.runtime.Messa case 'manifest': return new ManifestMessenger()[(methodName as keyof ManifestMessenger) || 'values'](message); case 'action': - return new ActionMessenger()[(methodName as keyof ActionMessenger) || 'setIcon'](message); + return new ActionMessenger()[(methodName as keyof ActionMessenger) || 'setIcon'](message, sender); case 'alarms': return new AlarmsMessenger()[(methodName as keyof AlarmsMessenger) || 'create'](message); case 'userScripts': diff --git a/packages/core/service/src/lib/action.service.ts b/packages/core/service/src/lib/action.service.ts index 0df42fc0..f65a7909 100644 --- a/packages/core/service/src/lib/action.service.ts +++ b/packages/core/service/src/lib/action.service.ts @@ -17,4 +17,16 @@ export class ActionService extends CoreService { static async setTitle(details: chrome.action.TitleDetails) { return await this.message({ messenger: 'action', methodName: 'setTitle', message: details }); } + + static async setBadgeTextColor(details: chrome.action.BadgeColorDetails) { + return await this.message({ messenger: 'action', methodName: 'setBadgeTextColor', message: details }); + } + + static async enable(tabId?: number) { + return await this.message({ messenger: 'action', methodName: 'enable', message: { tabId } }); + } + + static async disable(tabId?: number) { + return await this.message({ messenger: 'action', methodName: 'disable', message: { tabId } }); + } } diff --git a/packages/shared/status-bar/src/index.ts b/packages/shared/status-bar/src/index.ts index 4a30b72f..6c3f29f9 100644 --- a/packages/shared/status-bar/src/index.ts +++ b/packages/shared/status-bar/src/index.ts @@ -1,2 +1,4 @@ +/// + export * from './lib/status-bar'; export * from './lib/status-bar.types'; diff --git a/packages/shared/status-bar/src/lib/status-bar.ts b/packages/shared/status-bar/src/lib/status-bar.ts index 58d1a557..949bf059 100644 --- a/packages/shared/status-bar/src/lib/status-bar.ts +++ b/packages/shared/status-bar/src/lib/status-bar.ts @@ -1,142 +1,89 @@ +import { ActionService } from '@dhruv-techapps/core-service'; import { Timer } from '@dhruv-techapps/shared-util'; -import { STATUS_BAR_LOCATION } from './status-bar.types'; export enum STATUS_BAR_TYPE { CONFIG_WAIT = 'Config wait', - BATCH_WAIT = 'Batch wait', - BATCH_REPEAT = 'Batch repeat', ACTION_WAIT = 'Action wait', - ACTION_REPEAT = 'Action repeat', - ADDON_RECHECK = 'Addon recheck' + BATCH_REPEAT = 'Batch repeat', + ADDON_RECHECK = 'Addon recheck', + ACTION_REPEAT = 'Action repeat' } export class StatusBar { - private readonly statusBar: HTMLDivElement = document.createElement('div'); - private readonly icon: HTMLSpanElement = document.createElement('span'); - private readonly batch: HTMLSpanElement = document.createElement('span'); - private readonly action: HTMLSpanElement = document.createElement('span'); - private readonly addon: HTMLSpanElement = document.createElement('span'); - private readonly timer: HTMLSpanElement = document.createElement('span'); - private readonly text: HTMLSpanElement = document.createElement('span'); - - constructor() { - this.statusBar = document.createElement('div'); - this.statusBar.className = 'hide'; - this.statusBar.id = 'auto-clicker-auto-fill-status'; - ['icon', 'text', 'batch', 'action', 'addon', 'timer'].forEach((el) => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (this as any)[el].className = el; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - this.statusBar.appendChild((this as any)[el]); - }); + private batch: string | number = ''; + private action: string = ''; + private totalActions: number = 0; + private totalBatches: number = 0; + + public enable(totalActions: number, totalBatches?: number): void { + this.batch = ''; + this.action = ''; + this.totalActions = totalActions; + this.totalBatches = totalBatches || 0; + ActionService.enable(); + ActionService.setBadgeText({ text: '⚡' }); + ActionService.setTitle({ title: 'Initializing setup...' }); } - public setLocation = async (location: STATUS_BAR_LOCATION) => { - this.statusBar.className = location; - document.body.appendChild(this.statusBar); - }; + public disable(): void { + ActionService.disable(); + } - public async wait(text?: number | string, type?: STATUS_BAR_TYPE, name?: string | number): Promise { - this.timer.textContent = ''; + public async wait(text?: number | string, _type?: STATUS_BAR_TYPE | string, current?: number): Promise { const waitTime = Timer.getWaitTime(text); if (!waitTime) { return; } - switch (type) { + const time = waitTime / 1000; + let title = ''; + let icon = '🔄⏳'; + switch (_type) { case STATUS_BAR_TYPE.CONFIG_WAIT: - this.text.textContent = 'Config'; + icon = '▶️⏳'; + title = `Waiting ${time}s before starting configuration.`; break; - case STATUS_BAR_TYPE.BATCH_WAIT: - case STATUS_BAR_TYPE.BATCH_REPEAT: case STATUS_BAR_TYPE.ACTION_WAIT: + icon = '🔁⏳'; + title = `Waiting ${time}s before starting Action ${this.action} of ${this.totalActions}.`; break; - case STATUS_BAR_TYPE.ADDON_RECHECK: - this.timer.textContent = `🔁${name} ~`; + case STATUS_BAR_TYPE.BATCH_REPEAT: + icon = '📦⏳'; + title = `Waiting ${time}s before starting Batch ${this.batch} of ${this.totalBatches}.`; break; case STATUS_BAR_TYPE.ACTION_REPEAT: - this.timer.textContent = `🔁${name} ~`; + title = `Waiting ${time}s before repeating Action ${this.action} (${current} repeats left).`; + break; + case STATUS_BAR_TYPE.ADDON_RECHECK: + icon = '✅⏳'; + title = `Condition not met. Rechecking in ${time}s... ${current} checks left (Action ${this.action}).`; break; default: - this.timer.textContent = `🔍${name} ~`; + icon = '👀⏳'; + title = `Element not found. Retrying in ${time}s... ${current} retries left (Action ${this.action}).`; break; } - - this.timer.textContent += '🕒' + waitTime / 1000 + ' sec'; + ActionService.setBadgeText({ text: icon }); + ActionService.setTitle({ title }); await Timer.sleep(waitTime); } - public addonUpdate(): void { - this.addon.textContent = '❓'; - this.addon.title = 'Addon'; - this.text.textContent = ''; - } - - public actionUpdate(number: number, text: string | undefined): void { - this.action.textContent = `🅰️${number}`; - this.action.title = text ?? 'Action'; - this.addon.textContent = ''; - } - public batchUpdate(text: string | number): void { - this.batch.textContent = `🅱️${text}`; - this.batch.title = 'Batch'; - this.action.textContent = ''; - this.addon.textContent = ''; - this.text.textContent = ''; + this.batch = text; + this.action = ''; } - public error = (text: string): void => { - this.icon.textContent = '❌'; - this.batch.textContent = ''; - this.action.textContent = ''; - this.addon.textContent = ''; - this.timer.textContent = ''; - this.text.textContent = text; - }; - - public done = (): void => { - this.icon.textContent = '✨'; - this.batch.textContent = ''; - this.action.textContent = ''; - this.addon.textContent = ''; - this.timer.textContent = ''; - this.text.textContent = 'Done'; - }; -} - -export class ManualStatusBar { - private static instance: ManualStatusBar; - private readonly statusBar: HTMLDivElement; - private readonly manualContainer: HTMLUListElement = document.createElement('ul'); - - private constructor() { - this.statusBar = document.createElement('div'); - this.statusBar.id = 'auto-clicker-auto-fill-manual'; - - this.manualSetup(); - document.body.appendChild(this.statusBar); + public actionUpdate(number: string): void { + this.action = number; } - public manual = (text: string): void => { - if (!this.manualContainer.textContent) { - const li = document.createElement('li'); - li.textContent = '👋'; - this.manualContainer.appendChild(li); - } - const li = document.createElement('li'); - li.textContent = text; - this.manualContainer.appendChild(li); + public error = (error: string): void => { + console.error('Error: %s', error); + ActionService.setBadgeText({ text: '❌' }); + ActionService.setTitle({ title: error }); }; - private readonly manualSetup = (): void => { - this.manualContainer.className = 'manual'; - this.statusBar.appendChild(this.manualContainer); + public done = (): void => { + ActionService.setBadgeText({ text: '✅' }); + ActionService.setTitle({ title: 'Auto Clicker & Auto Fill' }); }; - - public static getInstance(): ManualStatusBar { - if (!ManualStatusBar.instance) { - ManualStatusBar.instance = new ManualStatusBar(); - } - return ManualStatusBar.instance; - } } diff --git a/packages/shared/status-bar/tsconfig.json b/packages/shared/status-bar/tsconfig.json index 81c155a9..1dc7069b 100644 --- a/packages/shared/status-bar/tsconfig.json +++ b/packages/shared/status-bar/tsconfig.json @@ -3,6 +3,9 @@ "files": [], "include": [], "references": [ + { + "path": "../../core/service" + }, { "path": "../util" }, diff --git a/packages/shared/status-bar/tsconfig.lib.json b/packages/shared/status-bar/tsconfig.lib.json index 9c2a305d..d8beb7df 100644 --- a/packages/shared/status-bar/tsconfig.lib.json +++ b/packages/shared/status-bar/tsconfig.lib.json @@ -12,6 +12,9 @@ }, "include": ["src/**/*.ts"], "references": [ + { + "path": "../../core/service/tsconfig.lib.json" + }, { "path": "../util/tsconfig.lib.json" } From d5ef0c8afb762e8b69a765cbdefbca2ab31f1935 Mon Sep 17 00:00:00 2001 From: Dharmesh Date: Fri, 17 Oct 2025 12:59:01 +0530 Subject: [PATCH 2/8] feat(port-service): implement PortService for managing runtime connections and messaging --- apps/acf-extension/src/background/index.ts | 2 + .../src/lib/background/chrome/runtime.ts | 20 +++++++ .../core/service/src/lib/action.service.ts | 32 +++++------ packages/core/service/src/lib/service.ts | 56 +++++++++++++++++++ 4 files changed, 94 insertions(+), 16 deletions(-) diff --git a/apps/acf-extension/src/background/index.ts b/apps/acf-extension/src/background/index.ts index 34462059..9bb95b36 100644 --- a/apps/acf-extension/src/background/index.ts +++ b/apps/acf-extension/src/background/index.ts @@ -109,7 +109,9 @@ try { [RUNTIME_MESSAGE_OPENAI]: new OpenAIBackground(auth, FIREBASE_FUNCTIONS_URL, EDGE_OAUTH_CLIENT_ID) }; Runtime.onMessageExternal(onMessageListener); + Runtime.onMessage(onMessageListener); + Runtime.onConnect(onMessageListener); auth.authStateReady().then(() => { const clientId = auth.currentUser?.uid; diff --git a/packages/core/extension/src/lib/background/chrome/runtime.ts b/packages/core/extension/src/lib/background/chrome/runtime.ts index e4d37233..57690170 100644 --- a/packages/core/extension/src/lib/background/chrome/runtime.ts +++ b/packages/core/extension/src/lib/background/chrome/runtime.ts @@ -49,6 +49,26 @@ export class Runtime { chrome.runtime.sendMessage(message, callback); } + static onConnect(configs: MessengerConfigObject) { + chrome.runtime.onConnect.addListener((port) => { + const { sender = {}, name } = port; + const tabId = sender.tab?.id; + if (!tabId) { + port.postMessage({ error: 'no tab id' }); + port.disconnect(); + return; + } + console.log('port connected', name); + port.onMessage.addListener((msg) => { + messageListener(msg, sender, configs); + }); + }); + } + + static onConnectExternal(configs: MessengerConfigObject) { + //TODO + } + static onMessage(configs: MessengerConfigObject) { chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { messageListener(request, sender, configs) diff --git a/packages/core/service/src/lib/action.service.ts b/packages/core/service/src/lib/action.service.ts index f65a7909..a49e615e 100644 --- a/packages/core/service/src/lib/action.service.ts +++ b/packages/core/service/src/lib/action.service.ts @@ -1,32 +1,32 @@ import { ActionRequest } from '@dhruv-techapps/core-extension'; -import { CoreService } from './service'; +import { PortService } from './service'; -export class ActionService extends CoreService { - static async setBadgeBackgroundColor(details: chrome.action.BadgeColorDetails) { - return await this.message({ messenger: 'action', methodName: 'setBadgeBackgroundColor', message: details }); +export class ActionService { + static setBadgeBackgroundColor(details: chrome.action.BadgeColorDetails) { + PortService.getInstance().message({ messenger: 'action', methodName: 'setBadgeBackgroundColor', message: details }); } - static async setBadgeText(details: chrome.action.BadgeTextDetails) { - return await this.message({ messenger: 'action', methodName: 'setBadgeText', message: details }); + static setBadgeText(details: chrome.action.BadgeTextDetails) { + PortService.getInstance().message({ messenger: 'action', methodName: 'setBadgeText', message: details }); } - static async setIcon(details: chrome.action.TabIconDetails) { - return await this.message({ messenger: 'action', methodName: 'setIcon', message: details }); + static setIcon(details: chrome.action.TabIconDetails) { + PortService.getInstance().message({ messenger: 'action', methodName: 'setIcon', message: details }); } - static async setTitle(details: chrome.action.TitleDetails) { - return await this.message({ messenger: 'action', methodName: 'setTitle', message: details }); + static setTitle(details: chrome.action.TitleDetails) { + PortService.getInstance().message({ messenger: 'action', methodName: 'setTitle', message: details }); } - static async setBadgeTextColor(details: chrome.action.BadgeColorDetails) { - return await this.message({ messenger: 'action', methodName: 'setBadgeTextColor', message: details }); + static setBadgeTextColor(details: chrome.action.BadgeColorDetails) { + PortService.getInstance().message({ messenger: 'action', methodName: 'setBadgeTextColor', message: details }); } - static async enable(tabId?: number) { - return await this.message({ messenger: 'action', methodName: 'enable', message: { tabId } }); + static enable(tabId?: number) { + PortService.getInstance().message({ messenger: 'action', methodName: 'enable', message: { tabId } }); } - static async disable(tabId?: number) { - return await this.message({ messenger: 'action', methodName: 'disable', message: { tabId } }); + static disable(tabId?: number) { + PortService.getInstance().message({ messenger: 'action', methodName: 'disable', message: { tabId } }); } } diff --git a/packages/core/service/src/lib/service.ts b/packages/core/service/src/lib/service.ts index b581f313..03fee77f 100644 --- a/packages/core/service/src/lib/service.ts +++ b/packages/core/service/src/lib/service.ts @@ -44,3 +44,59 @@ export class CoreService { return await this.messageChrome(message); } } + +export class PortService { + private static instance?: PortService; + private readonly port: chrome.runtime.Port; + private readonly portName: string; + + private constructor(name: string = 'Auto Clicker & Auto Fill') { + if (!chrome.runtime?.connect) { + throw new Error('Extension context invalidated'); + } + + const id = chrome.runtime.id || window.EXTENSION_ID; + if (!id || typeof id !== 'string') { + throw new Error('extensionId is not undefined neither string'); + } + + this.portName = name; + this.port = chrome.runtime.connect(id, { name: this.portName }); + } + + static getInstance(name?: string): PortService { + if (!PortService.instance) { + PortService.instance = new PortService(name); + return PortService.instance; + } + + if (name && PortService.instance.portName !== name) { + console.warn(`PortService already initialized with name "${PortService.instance.portName}". Ignoring request for "${name}".`); + } + + return PortService.instance; + } + + private postMessage(message: unknown): void { + this.port.postMessage(message); + } + + public onMessage(listener: (message: unknown) => void): void { + if (this.port.onMessage.hasListener(listener)) { + return; + } + this.port.onMessage.addListener(listener); + } + + public disconnect(): void { + this.port.disconnect(); + } + + public onDisconnect(listener: () => void): void { + this.port.onDisconnect.addListener(listener); + } + + public message(message: K): void { + this.postMessage(message); + } +} From bf72ccd1ba26b6a44cf713c6ab914708971a3119 Mon Sep 17 00:00:00 2001 From: Dharmesh Date: Fri, 17 Oct 2025 13:03:51 +0530 Subject: [PATCH 3/8] fix(service): simplify constructor parameter default value syntax fix(status-bar): standardize property initialization syntax --- packages/core/service/src/lib/service.ts | 2 +- packages/shared/status-bar/package.json | 3 ++- packages/shared/status-bar/src/lib/status-bar.ts | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/core/service/src/lib/service.ts b/packages/core/service/src/lib/service.ts index 03fee77f..974d2a77 100644 --- a/packages/core/service/src/lib/service.ts +++ b/packages/core/service/src/lib/service.ts @@ -50,7 +50,7 @@ export class PortService { private readonly port: chrome.runtime.Port; private readonly portName: string; - private constructor(name: string = 'Auto Clicker & Auto Fill') { + private constructor(name = 'Auto Clicker & Auto Fill') { if (!chrome.runtime?.connect) { throw new Error('Extension context invalidated'); } diff --git a/packages/shared/status-bar/package.json b/packages/shared/status-bar/package.json index b55cd5a8..046ae575 100644 --- a/packages/shared/status-bar/package.json +++ b/packages/shared/status-bar/package.json @@ -20,6 +20,7 @@ ], "dependencies": { "@swc/helpers": "~0.5.11", - "@dhruv-techapps/shared-util": "0.0.1" + "@dhruv-techapps/shared-util": "0.0.1", + "@dhruv-techapps/core-service": "0.0.1" } } diff --git a/packages/shared/status-bar/src/lib/status-bar.ts b/packages/shared/status-bar/src/lib/status-bar.ts index 949bf059..151d7fc4 100644 --- a/packages/shared/status-bar/src/lib/status-bar.ts +++ b/packages/shared/status-bar/src/lib/status-bar.ts @@ -11,9 +11,9 @@ export enum STATUS_BAR_TYPE { export class StatusBar { private batch: string | number = ''; - private action: string = ''; - private totalActions: number = 0; - private totalBatches: number = 0; + private action = ''; + private totalActions = 0; + private totalBatches = 0; public enable(totalActions: number, totalBatches?: number): void { this.batch = ''; From d6591e2ed05e1f13a428484410b849b98f737eb7 Mon Sep 17 00:00:00 2001 From: Dharmesh Date: Fri, 17 Oct 2025 13:11:24 +0530 Subject: [PATCH 4/8] refactor(status-bar): remove enable/disable methods and streamline badge updates --- apps/acf-extension/src/background/index.ts | 9 +++------ packages/core/service/src/lib/action.service.ts | 8 -------- packages/shared/status-bar/src/lib/status-bar.ts | 5 ----- 3 files changed, 3 insertions(+), 19 deletions(-) diff --git a/apps/acf-extension/src/background/index.ts b/apps/acf-extension/src/background/index.ts index 9bb95b36..969a062d 100644 --- a/apps/acf-extension/src/background/index.ts +++ b/apps/acf-extension/src/background/index.ts @@ -15,7 +15,6 @@ import { registerNotifications } from '@dhruv-techapps/shared-notifications'; import { OpenAIBackground, RUNTIME_MESSAGE_OPENAI } from '@dhruv-techapps/shared-openai'; import { RUNTIME_MESSAGE_VISION, VisionBackground } from '@dhruv-techapps/shared-vision'; import XMLHttpRequest from 'xhr-shim'; -import { ACTION_POPUP } from '../common/constant'; import { DISCORD_CLIENT_ID, EDGE_OAUTH_CLIENT_ID, FIREBASE_FUNCTIONS_URL, OPTIONS_PAGE_URL, VARIANT } from '../common/environments'; import { scope } from '../common/instrument'; import AcfBackup from './acf-backup'; @@ -33,11 +32,9 @@ try { /** * Browser Action set to open option page / configuration page */ - chrome.action.onClicked.addListener((tab) => { - googleAnalytics?.fireEvent({ name: 'Wizard', params: { location: 'action:onClicked' } }); - if (tab.id !== undefined) { - chrome.tabs.sendMessage(tab.id, { action: ACTION_POPUP }); - } + chrome.action.onClicked.addListener(() => { + googleAnalytics?.fireEvent({ name: 'Web', params: { location: 'action:onClicked' } }); + chrome.tabs.create({ url: OPTIONS_PAGE_URL }); }); /** diff --git a/packages/core/service/src/lib/action.service.ts b/packages/core/service/src/lib/action.service.ts index a49e615e..33815e2b 100644 --- a/packages/core/service/src/lib/action.service.ts +++ b/packages/core/service/src/lib/action.service.ts @@ -21,12 +21,4 @@ export class ActionService { static setBadgeTextColor(details: chrome.action.BadgeColorDetails) { PortService.getInstance().message({ messenger: 'action', methodName: 'setBadgeTextColor', message: details }); } - - static enable(tabId?: number) { - PortService.getInstance().message({ messenger: 'action', methodName: 'enable', message: { tabId } }); - } - - static disable(tabId?: number) { - PortService.getInstance().message({ messenger: 'action', methodName: 'disable', message: { tabId } }); - } } diff --git a/packages/shared/status-bar/src/lib/status-bar.ts b/packages/shared/status-bar/src/lib/status-bar.ts index 151d7fc4..f7ab64c2 100644 --- a/packages/shared/status-bar/src/lib/status-bar.ts +++ b/packages/shared/status-bar/src/lib/status-bar.ts @@ -20,15 +20,10 @@ export class StatusBar { this.action = ''; this.totalActions = totalActions; this.totalBatches = totalBatches || 0; - ActionService.enable(); ActionService.setBadgeText({ text: '⚡' }); ActionService.setTitle({ title: 'Initializing setup...' }); } - public disable(): void { - ActionService.disable(); - } - public async wait(text?: number | string, _type?: STATUS_BAR_TYPE | string, current?: number): Promise { const waitTime = Timer.getWaitTime(text); if (!waitTime) { From e9ff8c61e794ed85e4fea554ef85a3a31b42710f Mon Sep 17 00:00:00 2001 From: Dharmesh Date: Fri, 17 Oct 2025 13:19:19 +0530 Subject: [PATCH 5/8] refactor(action): remove parameters from enable/disable methods and update ActionService methods --- apps/acf-extension/src/content_scripts/index.ts | 2 -- .../lib/background/chrome/messenger/action.messenger.ts | 4 ++-- packages/core/service/src/lib/action.service.ts | 8 ++++++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/apps/acf-extension/src/content_scripts/index.ts b/apps/acf-extension/src/content_scripts/index.ts index 27be4a0a..1c1fee28 100644 --- a/apps/acf-extension/src/content_scripts/index.ts +++ b/apps/acf-extension/src/content_scripts/index.ts @@ -34,8 +34,6 @@ async function loadConfig(loadType: ELoadTypes) { } } else if (manualConfigs.length > 0 && loadType === ELoadTypes.DOCUMENT) { await ConfigProcessor.checkStartType(manualConfigs); - } else { - statusBar.disable(); } }); } catch (e) { diff --git a/packages/core/extension/src/lib/background/chrome/messenger/action.messenger.ts b/packages/core/extension/src/lib/background/chrome/messenger/action.messenger.ts index 5023f788..ce943b28 100644 --- a/packages/core/extension/src/lib/background/chrome/messenger/action.messenger.ts +++ b/packages/core/extension/src/lib/background/chrome/messenger/action.messenger.ts @@ -5,11 +5,11 @@ export interface ActionRequest { } export class ActionMessenger { - disable(sender: chrome.runtime.MessageSender) { + disable(_: void, sender: chrome.runtime.MessageSender) { return chrome.action.disable(sender.tab?.id); } - enable(sender: chrome.runtime.MessageSender) { + enable(_: void, sender: chrome.runtime.MessageSender) { return chrome.action.enable(sender.tab?.id); } diff --git a/packages/core/service/src/lib/action.service.ts b/packages/core/service/src/lib/action.service.ts index 33815e2b..a49e615e 100644 --- a/packages/core/service/src/lib/action.service.ts +++ b/packages/core/service/src/lib/action.service.ts @@ -21,4 +21,12 @@ export class ActionService { static setBadgeTextColor(details: chrome.action.BadgeColorDetails) { PortService.getInstance().message({ messenger: 'action', methodName: 'setBadgeTextColor', message: details }); } + + static enable(tabId?: number) { + PortService.getInstance().message({ messenger: 'action', methodName: 'enable', message: { tabId } }); + } + + static disable(tabId?: number) { + PortService.getInstance().message({ messenger: 'action', methodName: 'disable', message: { tabId } }); + } } From 428b54f8758b70dab118e132d94f9c345ca5188b Mon Sep 17 00:00:00 2001 From: Dharmesh Date: Fri, 17 Oct 2025 14:01:22 +0530 Subject: [PATCH 6/8] refactor(status-bar): update description and enhance badge functionality details in documentation --- site/src/components/home/MastHead.astro | 2 +- .../src/content/docs/extension/status-bar.mdx | 29 +++++++++++-------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/site/src/components/home/MastHead.astro b/site/src/components/home/MastHead.astro index cb8cd8ec..6e0dcf08 100644 --- a/site/src/components/home/MastHead.astro +++ b/site/src/components/home/MastHead.astro @@ -29,7 +29,7 @@ import { getVersionedDocsPath } from '@libs/path' Read the docs diff --git a/site/src/content/docs/extension/status-bar.mdx b/site/src/content/docs/extension/status-bar.mdx index 080c3bc4..45c414a2 100644 --- a/site/src/content/docs/extension/status-bar.mdx +++ b/site/src/content/docs/extension/status-bar.mdx @@ -1,24 +1,29 @@ --- title: Status Bar -description: Track configuration and execution status from a compact on-page status bar +description: Track configuration and execution status from the Chrome Action badge tags: [status-bar, configuration, execution, ui] toc: true --- -The configuration status appears by default at the bottom-right of the page. You can disable or reposition it from global settings. +The status experience now lives in the Chrome Action badge (the extension icon) instead of an on-page overlay. When automation starts, the badge becomes active and its badge text and tooltip communicate the current state. Once automation completes or is stopped, the badge is disabled and Chrome returns to its default icon behavior. - +- Badge text changes to show the current phase using emoji indicators. +- Tooltip (Chrome Action title) gives the full context, including timers, batch/action counters, and retry information. +- The badge automatically resets to the default extension title when work is complete or when the automation is disabled. -| Icon | Description | -| ---------------------- | ------------------------------------------------------------------- | -| 🅱️1 | `🅱️` denotes the batch; `1` is the current batch index (1‑based). | -| 🅰️1 | `🅰️` denotes the action; `1` is the current action index (1‑based). | -| ❓ | Addon condition check in progress. | -| 🔁 "addon" \| "action" | Repeat in progress for the specified scope: `addon` or `action`. | -| 🔍 | Element Finder is searching for the target element (not yet found). | -| 🕒 | Waiting (Init Wait, Repeat Interval, or Retry Interval). | -| Done | Action completed successfully. | +| Badge text | Title preview | When it appears | +| ---------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| ⚡ | `Initializing setup...` | Immediately after automation starts; the badge is enabled and the extension icon signals that actions are being prepared. | +| ▶️⏳ | `Waiting {time}s before starting configuration.` | Configuration wait timers (Init Wait) before the first batch/action runs. | +| 📦⏳ | `Waiting {time}s before starting Batch {current} of {total}.` | Batch level waits between batch executions. | +| 🔁⏳ | `Waiting {time}s before starting Action {current} of {total}.` | Delay before the next action executes. | +| �⏳ | `Element not found. Retrying in {time}s... {retries} retries left (Action {current}).` | Retry logic while searching for page elements. | +| ✅⏳ | `Condition not met. Rechecking in {time}s... {checks} checks left (Action {current}).` | Add-on recheck countdowns before concluding conditions. | +| ❌ | `` | An error occurred; the badge remains active until the issue is resolved or automation stops. | +| ✅ | `Auto Clicker & Auto Fill` | Automation completed successfully; the badge resets but stays enabled momentarily before disable. | + +> **Note:** The badge is disabled (no text or custom title) whenever the automation is idle. Launching a workflow re-enables the badge and reinstates the live status indicators until completion or manual stop. From be92aed1c9d42e1f33af915bfae4bfecddd6e538 Mon Sep 17 00:00:00 2001 From: Dharmesh Date: Fri, 17 Oct 2025 14:03:35 +0530 Subject: [PATCH 7/8] refactor(status-bar): update action property type and modify actionUpdate method signature --- apps/acf-extension/src/content_scripts/actions.ts | 2 +- apps/acf-extension/src/content_scripts/addon.ts | 1 - packages/shared/status-bar/src/lib/status-bar.ts | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/acf-extension/src/content_scripts/actions.ts b/apps/acf-extension/src/content_scripts/actions.ts index 1867328d..52b9e410 100644 --- a/apps/acf-extension/src/content_scripts/actions.ts +++ b/apps/acf-extension/src/content_scripts/actions.ts @@ -45,7 +45,7 @@ const Actions = (() => { i += 1; continue; } - statusBar.actionUpdate(i + 1, action.name); + statusBar.actionUpdate(i + 1); window.ext.__currentAction = i + 1; try { await checkStatement(actions, action); diff --git a/apps/acf-extension/src/content_scripts/addon.ts b/apps/acf-extension/src/content_scripts/addon.ts index 900ff908..f3dd7e30 100644 --- a/apps/acf-extension/src/content_scripts/addon.ts +++ b/apps/acf-extension/src/content_scripts/addon.ts @@ -116,7 +116,6 @@ const AddonProcessor = (() => { }; const start = async ({ elementFinder, value, condition, valueExtractor, valueExtractorFlags, ...props }: IAddon, settings?: IActionSettings): Promise => { - statusBar.addonUpdate(); let nodeValue; if (/^Func::/gi.test(elementFinder)) { nodeValue = await Sandbox.sandboxEval(elementFinder.replace(/^Func::/gi, '')); diff --git a/packages/shared/status-bar/src/lib/status-bar.ts b/packages/shared/status-bar/src/lib/status-bar.ts index f7ab64c2..ce20365c 100644 --- a/packages/shared/status-bar/src/lib/status-bar.ts +++ b/packages/shared/status-bar/src/lib/status-bar.ts @@ -11,7 +11,7 @@ export enum STATUS_BAR_TYPE { export class StatusBar { private batch: string | number = ''; - private action = ''; + private action: string | number = ''; private totalActions = 0; private totalBatches = 0; @@ -67,7 +67,7 @@ export class StatusBar { this.action = ''; } - public actionUpdate(number: string): void { + public actionUpdate(number: number | string): void { this.action = number; } From 29f8bd5995acf55c9cd7e27c733790beab339947 Mon Sep 17 00:00:00 2001 From: Dharmesh Date: Fri, 17 Oct 2025 14:10:48 +0530 Subject: [PATCH 8/8] refactor(runtime): remove unused onConnectExternal method --- packages/core/extension/src/lib/background/chrome/runtime.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/core/extension/src/lib/background/chrome/runtime.ts b/packages/core/extension/src/lib/background/chrome/runtime.ts index 57690170..ff64325c 100644 --- a/packages/core/extension/src/lib/background/chrome/runtime.ts +++ b/packages/core/extension/src/lib/background/chrome/runtime.ts @@ -65,10 +65,6 @@ export class Runtime { }); } - static onConnectExternal(configs: MessengerConfigObject) { - //TODO - } - static onMessage(configs: MessengerConfigObject) { chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { messageListener(request, sender, configs)