Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/acf-extension/src/common/instrument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ if (VARIANT === 'PROD' || VARIANT === 'LOCAL') {
...integrations,
browserTracingIntegration(),
captureConsoleIntegration({
levels: ['error', 'warn']
levels: ['error']
})
],
ignoreErrors: [
Expand Down
4 changes: 2 additions & 2 deletions apps/acf-extension/src/content_scripts/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const ActionProcessor = (() => {
if (repeat > 0 || repeat < -1) {
await statusBar.wait(repeatInterval, STATUS_BAR_TYPE.ACTION_REPEAT, repeat);
repeat -= 1;
window.__actionRepeat = window.__actionRepeat + 1;
window.ext.__actionRepeat = window.ext.__actionRepeat + 1;
await process(action);
return await repeatFunc(action, repeat, repeatInterval);
}
Expand All @@ -30,7 +30,7 @@ const ActionProcessor = (() => {
};

const start = async (action: IAction) => {
window.__actionRepeat = 1;
window.ext.__actionRepeat = 1;
await process(action);
return await repeatFunc(action, action.repeat, action.repeatInterval);
};
Expand Down
33 changes: 18 additions & 15 deletions apps/acf-extension/src/content_scripts/actions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EActionRunning, EActionStatus, IAction } from '@dhruv-techapps/acf-common';
import { EActionRunning, EActionStatus, IAction, isUserScript, IUserScript } from '@dhruv-techapps/acf-common';
import { SettingsStorage } from '@dhruv-techapps/acf-store';
import { ConfigError, isValidUUID } from '@dhruv-techapps/core-common';
import { NotificationsService } from '@dhruv-techapps/core-service';
Expand All @@ -9,61 +9,64 @@ import Common from './common';
import { I18N_COMMON, I18N_ERROR } from './i18n';
import Statement from './statement';
import { statusBar } from './status-bar';
import UserScriptProcessor from './userscript';

const ACTION_I18N = {
TITLE: chrome.i18n.getMessage('@ACTION__TITLE'),
NO_NAME: chrome.i18n.getMessage('@ACTION__NO_NAME')
};

const Actions = (() => {
const checkStatement = async (actions: Array<IAction>, action: IAction) => {
const checkStatement = async (actions: Array<IAction | IUserScript>, action: IAction | IUserScript) => {
Statement.check(actions, action.statement);
};

const notify = async (action: IAction) => {
const notify = async (action: IAction | IUserScript) => {
const settings = await new SettingsStorage().getSettings();
if (settings.notifications?.onAction) {
NotificationsService.create({
type: 'basic',
title: `${ACTION_I18N.TITLE} ${I18N_COMMON.COMPLETED}`,
message: action.elementFinder,
message: isUserScript(action) ? 'Userscript' : action.elementFinder,
silent: !settings.notifications.sound,
iconUrl: Common.getNotificationIcon()
});
}
};
const start = async (actions: Array<IAction>, batchRepeat: number) => {
window.__batchRepeat = batchRepeat;

const start = async (actions: Array<IAction | IUserScript>, batchRepeat: number) => {
window.ext.__batchRepeat = batchRepeat;
let i = 0;
while (i < actions.length) {
const action = actions[i];
window.__currentActionName = action.name ?? ACTION_I18N.NO_NAME;
window.ext.__currentActionName = action.name ?? ACTION_I18N.NO_NAME;
if (action.disabled) {
console.debug(`${ACTION_I18N.TITLE} #${i + 1}`, `[${window.__currentActionName}]`, `🚫 ${I18N_COMMON.DISABLED} `);
console.debug(`${ACTION_I18N.TITLE} #${i + 1}`, `[${window.ext.__currentActionName}]`, `🚫 ${I18N_COMMON.DISABLED} `);
i += 1;
continue;
}
statusBar.actionUpdate(i + 1, action.name);
window.__currentAction = i + 1;
if (!action.elementFinder) {
throw new ConfigError(I18N_ERROR.ELEMENT_FINDER_BLANK, ACTION_I18N.TITLE);
}
window.ext.__currentAction = i + 1;
try {
await checkStatement(actions, action);
await statusBar.wait(action.initWait, STATUS_BAR_TYPE.ACTION_WAIT);
await AddonProcessor.check(action.addon, action.settings);
action.status = await ActionProcessor.start(action);
if (action.type === 'userscript') {
action.status = await UserScriptProcessor.start(action as IUserScript);
} else {
action.status = await ActionProcessor.start(action as IAction);
}
notify(action);
} catch (error) {
if (error === EActionStatus.SKIPPED || error === EActionRunning.SKIP) {
console.debug(`${ACTION_I18N.TITLE} #${window.__currentAction}`, `[${window.__currentActionName}]`, window.__actionError, `⏭️ ${EActionStatus.SKIPPED}`);
console.debug(`${ACTION_I18N.TITLE} #${window.ext.__currentAction}`, `[${window.ext.__currentActionName}]`, window.ext.__actionError, `⏭️ ${EActionStatus.SKIPPED}`);
action.status = EActionStatus.SKIPPED;
} else if (typeof error === 'number' || (typeof error === 'string' && isValidUUID(error))) {
const index = typeof error === 'number' ? error : actions.findIndex((a) => a.id === error);
if (index === -1) {
throw new ConfigError(I18N_ERROR.ACTION_NOT_FOUND_FOR_GOTO, ACTION_I18N.TITLE);
}
console.debug(`${ACTION_I18N.TITLE} #${window.__currentAction}`, `[${window.__currentActionName}]`, window.__actionError, `${I18N_COMMON.GOTO} Action ➡️ ${index + 1}`);
console.debug(`${ACTION_I18N.TITLE} #${window.ext.__currentAction}`, `[${window.ext.__currentActionName}]`, window.ext.__actionError, `${I18N_COMMON.GOTO} Action ➡️ ${index + 1}`);
i = index - 1;
} else {
throw error;
Expand Down
4 changes: 2 additions & 2 deletions apps/acf-extension/src/content_scripts/addon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const AddonProcessor = (() => {
return await start({ elementFinder, value, condition, recheck, recheckOption, ...props }, settings);
}
}
window.__actionError = `${ADDON_I18N.TITLE} ${I18N_COMMON.COMPARE} '${nodeValue}' ${condition} '${value}'. ${I18N_COMMON.RESULT}: ${I18N_COMMON.CONDITION_NOT_SATISFIED}`;
window.ext.__actionError = `${ADDON_I18N.TITLE} ${I18N_COMMON.COMPARE} '${nodeValue}' ${condition} '${value}'. ${I18N_COMMON.RESULT}: ${I18N_COMMON.CONDITION_NOT_SATISFIED}`;
if (recheckOption === ERecheckOptions.RELOAD) {
if (document.readyState === 'complete') {
window.location.reload();
Expand Down Expand Up @@ -133,7 +133,7 @@ const AddonProcessor = (() => {
await recheckFunc({ nodeValue, elementFinder, value, condition, valueExtractor, valueExtractorFlags, ...props }, settings);
}
console.debug(
`${ADDON_I18N.TITLE} #${window.__currentAction} [${window.__currentActionName}]`,
`${ADDON_I18N.TITLE} #${window.ext.__currentAction} [${window.ext.__currentActionName}]`,
`${I18N_COMMON.COMPARE} '${nodeValue}' ${condition} '${value}'. ${I18N_COMMON.RESULT}: ${I18N_COMMON.CONDITION_SATISFIED}`
);
}
Expand Down
6 changes: 3 additions & 3 deletions apps/acf-extension/src/content_scripts/batch.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IAction, IBatch } from '@dhruv-techapps/acf-common';
import { IAction, IBatch, IUserScript } from '@dhruv-techapps/acf-common';
import { SettingsStorage } from '@dhruv-techapps/acf-store';
import { NotificationsService } from '@dhruv-techapps/core-service';
import { STATUS_BAR_TYPE } from '@dhruv-techapps/shared-status-bar';
Expand All @@ -22,7 +22,7 @@ const BatchProcessor = (() => {
}
};

const checkRepeat = async (actions: Array<IAction>, batch: IBatch) => {
const checkRepeat = async (actions: Array<IAction | IUserScript>, batch: IBatch) => {
if (batch.repeat) {
if (batch.repeat > 0) {
for (let i = 0; i < batch.repeat; i += 1) {
Expand Down Expand Up @@ -59,7 +59,7 @@ const BatchProcessor = (() => {
}
};

const start = async (actions: Array<IAction>, batch?: IBatch) => {
const start = async (actions: Array<IAction | IUserScript>, batch?: IBatch) => {
try {
statusBar.batchUpdate(1);
console.groupCollapsed(`${BATCH_I18N.TITLE} #1 (${I18N_COMMON.DEFAULT})`);
Expand Down
2 changes: 1 addition & 1 deletion apps/acf-extension/src/content_scripts/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ const Common = (() => {
if (!elementFinder) {
throw new ConfigError(I18N_ERROR.ELEMENT_FINDER_BLANK, 'Element Finder');
}
window.__actionError = I18N_ERROR.NO_ELEMENT_FOUND;
window.ext.__actionError = I18N_ERROR.NO_ELEMENT_FOUND;
const { retryOption, retryInterval, retry, checkiFrames, iframeFirst, retryGoto } = { ...(await new SettingsStorage().getSettings()), ...settings };
let elements: HTMLElement[] | undefined;
if (iframeFirst) {
Expand Down
4 changes: 2 additions & 2 deletions apps/acf-extension/src/content_scripts/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ const ConfigProcessor = (() => {

const start = async (config: IConfiguration) => {
try {
window.__sessionCount = new Session(config.id).getCount();
window.ext.__sessionCount = new Session(config.id).getCount();
if (config.bypass) {
await MainWorldService.bypass(config.bypass);
}
const sheets = GoogleSheets.getSheets(config);
window.__sheets = await new GoogleSheetsCS().getValues(sheets, config.spreadsheetId);
window.ext.__sheets = await new GoogleSheetsCS().getValues(sheets, config.spreadsheetId);
await BatchProcessor.start(config.actions, config.batch);
const { notifications } = await new SettingsStorage().getSettings();
if (notifications) {
Expand Down
13 changes: 4 additions & 9 deletions apps/acf-extension/src/content_scripts/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ELoadTypes, RUNTIME_MESSAGE_ACF } from '@dhruv-techapps/acf-common';
import { ConfigStorage, GetConfigResult, SettingsStorage } from '@dhruv-techapps/acf-store';
import { Logger, LoggerColor } from '@dhruv-techapps/core-common';
import { Sheets } from '@dhruv-techapps/shared-google-sheets';
import { IExtension, Logger, LoggerColor } from '@dhruv-techapps/core-common';
import { scope } from '../common/instrument';
import ConfigProcessor from './config';
import { statusBar } from './status-bar';
Expand All @@ -10,16 +9,12 @@ scope.setTag('page', 'content-script');

declare global {
interface Window {
__currentAction: number;
__currentActionName: string;
__actionError: string;
__actionRepeat: number;
__batchRepeat: number;
__sessionCount: number;
__sheets?: Sheets;
ext: IExtension;
}
}

window.ext = window.ext || {};

let reloadOnError = false;
new SettingsStorage().getSettings().then((settings) => {
if (settings.reloadOnError !== undefined) {
Expand Down
8 changes: 4 additions & 4 deletions apps/acf-extension/src/content_scripts/statement.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EActionConditionOperator, EActionRunning, ERetryOptions, IAction, IActionCondition, IActionStatement, TGoto } from '@dhruv-techapps/acf-common';
import { EActionConditionOperator, EActionRunning, ERetryOptions, IAction, IActionCondition, IActionStatement, IUserScript, TGoto } from '@dhruv-techapps/acf-common';
import { ConfigError } from '@dhruv-techapps/core-common';
import { I18N_COMMON, I18N_ERROR } from './i18n';

Expand All @@ -7,7 +7,7 @@ const ACTION_CONDITION_I18N = {
};

const Statement = (() => {
const conditionResult = (conditions: Array<IActionCondition>, actions: Array<IAction>) => {
const conditionResult = (conditions: Array<IActionCondition>, actions: Array<IAction | IUserScript>) => {
if (conditions.filter((condition) => condition.actionIndex !== undefined && condition.actionId === undefined).length > 0) {
throw new ConfigError(I18N_ERROR.ACTION_CONDITION_CONFIG_ERROR, ACTION_CONDITION_I18N.TITLE);
}
Expand All @@ -25,7 +25,7 @@ const Statement = (() => {
};

const checkThen = (condition: boolean, then: ERetryOptions, goto?: TGoto) => {
window.__actionError = `↔️ ${ACTION_CONDITION_I18N.TITLE} ${condition ? I18N_COMMON.CONDITION_SATISFIED : I18N_COMMON.CONDITION_NOT_SATISFIED}`;
window.ext.__actionError = `↔️ ${ACTION_CONDITION_I18N.TITLE} ${condition ? I18N_COMMON.CONDITION_SATISFIED : I18N_COMMON.CONDITION_NOT_SATISFIED}`;
if (!condition) {
if (then === ERetryOptions.GOTO && goto) {
throw goto;
Expand All @@ -44,7 +44,7 @@ const Statement = (() => {
}
};

const check = (actions: Array<IAction>, statement?: IActionStatement) => {
const check = (actions: Array<IAction | IUserScript>, statement?: IActionStatement) => {
if (statement) {
const { conditions, then, goto } = statement;
if (conditions && then) {
Expand Down
34 changes: 34 additions & 0 deletions apps/acf-extension/src/content_scripts/userscript.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { EActionStatus, IUserScript } from '@dhruv-techapps/acf-common';
import { IUserScriptsExecuteResponse } from '@dhruv-techapps/core-extension';
import { UserScriptsService } from '@dhruv-techapps/core-service';
import { I18N_COMMON } from './i18n';

const USER_SCRIPTS_I18N = {
TITLE: chrome.i18n.getMessage('@USER_SCRIPT__TITLE')
};

const UserScriptProcessor = (() => {
const start = async (action: IUserScript): Promise<EActionStatus> => {
const executeRequest = {
ext: window.ext,
code: action.value
};
return await UserScriptsService.execute(executeRequest)
.then((response: IUserScriptsExecuteResponse) => {
if (response.error) {
console.error(`${USER_SCRIPTS_I18N.TITLE} #${window.ext.__currentAction}`, `❌ ${I18N_COMMON.ERROR}`);
return EActionStatus.SKIPPED;
}
console.debug(`${USER_SCRIPTS_I18N.TITLE} #${window.ext.__currentAction}`, `✅ ${I18N_COMMON.COMPLETED}`);
return EActionStatus.DONE;
})
.catch((error) => {
console.error('Error executing UserScript:', error);
return EActionStatus.SKIPPED;
});
};

return { start };
})();

export default UserScriptProcessor;
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default class GoogleSheets {
ranges.add(range.replace(BATCH_REPEAT, '1'));
ranges.add(range.replace(BATCH_REPEAT, String(batchHighestRepeat + 1)));
} else if (value.includes(SESSION_COUNT)) {
ranges.add(range.replace(SESSION_COUNT, String(window.__sessionCount)));
ranges.add(range.replace(SESSION_COUNT, String(window.ext.__sessionCount)));
} else {
ranges.add(range);
}
Expand Down
2 changes: 1 addition & 1 deletion apps/acf-extension/src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"version": "5.0.0",
"manifest_version": 3,
"default_locale": "en",
"permissions": ["storage", "notifications", "contextMenus", "activeTab", "identity", "alarms", "unlimitedStorage", "scripting"],
"permissions": ["storage", "notifications", "contextMenus", "activeTab", "identity", "alarms", "unlimitedStorage", "scripting", "userScripts"],
"host_permissions": ["http://*/*", "https://*/*"],
"icons": {
"16": "assets/icons/icon16.png",
Expand Down
3 changes: 3 additions & 0 deletions apps/acf-i18n/src/locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
"@ACTION__TITLE": {
"message": "Action"
},
"@USER_SCRIPT__TITLE": {
"message": "User Script"
},
"@ACTION__NO_NAME": {
"message": "no-name"
},
Expand Down
18 changes: 18 additions & 0 deletions apps/acf-i18n/src/locales/en/web.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@
"title": "Remove Action",
"message": "Are you sure to remove [{{name}}] Action?"
}
},
"userscript": {
"remove": {
"title": "Remove User Script",
"message": "Are you sure to remove [{{name}}] User Script?"
}
}
},
"modal": {
Expand Down Expand Up @@ -299,6 +305,18 @@
"repeat": "Repeat",
"repeatInterval": "R-Interval"
},
"userscript": {
"title": "User Script",
"add": "Add User Script",
"addBefore": "Add User Script Above",
"addAfter": "Add User Script Below",
"remove": "Remove User Script",
"disable": "Disable User Script",
"enable": "Enable User Script",
"name": "Name",
"value": "Value",
"script": "Script"
},
"popover": {
"valueExtractor": {
"title": "Examples"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { DropdownToggle } from '@acf-options-page/components';
import { TRandomUUID } from '@dhruv-techapps/core-common';
import { Dropdown } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';

interface ActionOptionsDropdownProps {
index: number;
actionId: TRandomUUID;
disabled?: boolean;
removeActionConfirm: (actionId: TRandomUUID, index: number) => void;
showAddon: (actionId: TRandomUUID) => void;
showSettings: (actionId: TRandomUUID) => void;
showCondition: (actionId: TRandomUUID) => void;
onAddClick: (actionId: TRandomUUID, position: 1 | 0) => void;
onDisableClick: (actionId: TRandomUUID, disabled?: boolean) => void;
}

export const ActionOptionsDropdown: React.FC<ActionOptionsDropdownProps> = (props) => {
const { index, actionId, disabled, showAddon, showSettings, showCondition, onAddClick, onDisableClick } = props;
const { t } = useTranslation();
return (
<Dropdown id='action-dropdown-wrapper' className='d-inline-block'>
<Dropdown.Toggle as={DropdownToggle} id='action-dropdown' aria-label='Action more option'>
<i className='bi bi-three-dots' />
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item data-testid='action-addon' onClick={() => showAddon(actionId)}>
{t('action.addon')}
</Dropdown.Item>
<Dropdown.Item data-testid='action-settings' onClick={() => showSettings(actionId)}>
{t('action.settings')}
</Dropdown.Item>
{index !== 0 && (
<Dropdown.Item data-testid='action-statement' onClick={() => showCondition(actionId)}>
{t('modal.actionCondition.title')}
</Dropdown.Item>
)}
<Dropdown.Divider />
<Dropdown.Item data-testid='action-add' onClick={() => onAddClick(actionId, 0)}>
<i className='bi bi-plus-lg me-2' /> {t('action.addBefore')}
</Dropdown.Item>
<Dropdown.Item data-testid='action-add' onClick={() => onAddClick(actionId, 1)}>
<i className='bi bi-plus-lg me-2' /> {t('action.addAfter')}
</Dropdown.Item>
<Dropdown.Divider />
<Dropdown.Item data-testid='action-disable' onClick={() => onDisableClick(actionId, disabled)}>
{t(`action.${disabled ? 'enable' : 'disable'}`)}
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
);
};
Loading
Loading