Enhance agent.user.js by implementing a timer system for session management, including start, pause, and stop functionalities. Introduce new session keys for timer state and accumulated time, and update the dashboard overlay to display timer information. Refactor task handling to improve clarity and maintainability.

This commit is contained in:
thuanle
2025-08-05 12:36:10 +07:00
parent d2051afab6
commit 1423b63c03

View File

@@ -34,10 +34,14 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
SESSION_ID: 'aRah9OhHeijee6sho3baequu9phoovah', SESSION_ID: 'aRah9OhHeijee6sho3baequu9phoovah',
SESSION_BINDED: 'Oos2uoth2thae8Ir8iakahj1OohaMahb', SESSION_BINDED: 'Oos2uoth2thae8Ir8iakahj1OohaMahb',
SESSION_TOKEN: 'ThiegiecohViuZ1Iecio7gahphiechub', SESSION_TOKEN: 'ThiegiecohViuZ1Iecio7gahphiechub',
SESSION_INITIALIZED: 'iR4choo2Ieg2ew0ogheeyaer8Aisheet',
BOT_STATUS: 'wiethie3boGhoh3iegh3ohnezei2tauj', BOT_STATUS: 'wiethie3boGhoh3iegh3ohnezei2tauj',
CURRENT_TASK: 'Reebo1eitahh2aotumai5jae1neetoh3', CURRENT_TASK: 'Reebo1eitahh2aotumai5jae1neetoh3',
CURRENT_TASK_DATA: 'cheishailoh5keePoo6oe2Quie1gaxah', CURRENT_TASK_DATA: 'cheishailoh5keePoo6oe2Quie1gaxah',
CURRENT_STEP: 'eDusaidu2hooweiMoonahng3fua7aoso', CURRENT_STEP: 'eDusaidu2hooweiMoonahng3fua7aoso',
TIMER_START_TIME: 'einguh3eshuiqua7Ux7thaNgai5Axahy',
TIMER_IS_RUNNING: 'iengoose3vie2aikePhooCaPheeceizu',
TIMER_ACCUMULATED: 'aeMaiwae3PohB5Soshaech8eegh5quoo',
} }
if (!sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_ID)) { if (!sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_ID)) {
@@ -50,13 +54,13 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
DASHBOARD_UPDATE_INTERVAL: 500, // Update dashboard overlay every 0.5 seconds DASHBOARD_UPDATE_INTERVAL: 500, // Update dashboard overlay every 0.5 seconds
TASK_INTERVAL: 10_000, // Check for new task every 10 seconds TASK_INTERVAL: 10_000, // Check for new task every 10 seconds
REQUEST_TIMEOUT: 10_000, // Request timeout in milliseconds (10 seconds) REQUEST_TIMEOUT: 10_000, // Request timeout in milliseconds (10 seconds)
DEBUG_MILESTONE: true, // Show milestone debug logs
SERVERS: { SERVERS: {
local: { label: '🏠 Local', url: 'http://localhost:3000' }, local: { label: '🏠 Local', url: 'http://localhost:3000' },
prod: { label: '🌐 Prod', url: 'https://baf.thuanle.me' }, prod: { label: '🌐 Prod', url: 'https://baf.thuanle.me' },
}, },
}; };
const AppSession = { const AppSession = {
SESSION_ID: sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_ID), SESSION_ID: sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_ID),
@@ -66,11 +70,14 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
getSessionToken: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_TOKEN), getSessionToken: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_TOKEN),
setSessionToken: token => sessionStorage.setItem(SESSION_STORAGE_KEYS.SESSION_TOKEN, token), setSessionToken: token => sessionStorage.setItem(SESSION_STORAGE_KEYS.SESSION_TOKEN, token),
getSessionStatus: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.BOT_STATUS) || AppEnums.BOT_STATUS.STOP, getSessionStatus: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.BOT_STATUS),
setSessionStatus: status => sessionStorage.setItem(SESSION_STORAGE_KEYS.BOT_STATUS, status), setSessionStatus: status => sessionStorage.setItem(SESSION_STORAGE_KEYS.BOT_STATUS, status),
getSessionInitialized: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.SESSION_INITIALIZED) === 'true',
setSessionInitialized: initialized => sessionStorage.setItem(SESSION_STORAGE_KEYS.SESSION_INITIALIZED, initialized ? 'true' : 'false'),
// Task state - Trạng thái task hiện tại (lưu trong sessionStorage) // Task state - Trạng thái task hiện tại (lưu trong sessionStorage)
getCurrentTask: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.CURRENT_TASK) || BAF_TASKS.NO_TASK, getCurrentTask: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.CURRENT_TASK),
setCurrentTask: task => sessionStorage.setItem(SESSION_STORAGE_KEYS.CURRENT_TASK, task), setCurrentTask: task => sessionStorage.setItem(SESSION_STORAGE_KEYS.CURRENT_TASK, task),
getCurrentTaskData: () => { getCurrentTaskData: () => {
@@ -79,15 +86,35 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
}, },
setCurrentTaskData: data => sessionStorage.setItem(SESSION_STORAGE_KEYS.CURRENT_TASK_DATA, JSON.stringify(data)), setCurrentTaskData: data => sessionStorage.setItem(SESSION_STORAGE_KEYS.CURRENT_TASK_DATA, JSON.stringify(data)),
getCurrentStep: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.CURRENT_STEP) || BAF_TASKS.NO_STEP, getCurrentStep: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.CURRENT_STEP),
setCurrentStep: step => sessionStorage.setItem(SESSION_STORAGE_KEYS.CURRENT_STEP, step), setCurrentStep: step => sessionStorage.setItem(SESSION_STORAGE_KEYS.CURRENT_STEP, step),
initialize: async () => {
try {
const isInitialized = AppSession.getSessionInitialized();
if (!isInitialized) {
AppSession.setSessionStatus(AppEnums.BOT_STATUS.INITIALIZING);
AppSession.setCurrentTask(BAF_TASKS.NO_TASK);
AppSession.setCurrentStep(BAF_TASKS.NO_STEP);
AppSession.setSessionInitialized(true);
} else {
}
} catch (error) {
TL.error('APP-SESSION', '1.2.4. Error during session initialization:', error);
throw error;
}
},
} }
// ====== APP ENUMS ====== // ====== APP ENUMS ======
const AppEnums = { const AppEnums = {
BOT_STATUS: { BOT_STATUS: {
INITIALIZING: 'initializing',
STOP: 'stop', STOP: 'stop',
RUNNING: 'running', PAUSE: 'pause',
WAITING_FOR_TASK: 'waiting_for_task',
PERFORMING_TASK: 'performing_task',
ERROR: 'error', ERROR: 'error',
}, },
BOT_STARTUP_MODE: { BOT_STARTUP_MODE: {
@@ -115,7 +142,6 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
// Session flags - Flags cho session hiện tại (reset khi reload) // Session flags - Flags cho session hiện tại (reset khi reload)
menuCreated: false, // Menu đã được tạo menuCreated: false, // Menu đã được tạo
popupInitialized: false, // Popup đã được khởi tạo popupInitialized: false, // Popup đã được khởi tạo
appInitialized: false // App đã được khởi tạo hoàn toàn
}; };
this.observers = new Map(); // Observer pattern cho state changes this.observers = new Map(); // Observer pattern cho state changes
@@ -166,7 +192,6 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
getIsLoggedIn() { return this.data.is_logged_in; } getIsLoggedIn() { return this.data.is_logged_in; }
getMenuCreated() { return this.data.menuCreated; } getMenuCreated() { return this.data.menuCreated; }
getPopupInitialized() { return this.data.popupInitialized; } getPopupInitialized() { return this.data.popupInitialized; }
getAppInitialized() { return this.data.appInitialized; }
/** /**
* Cập nhật state với partial update * Cập nhật state với partial update
@@ -284,6 +309,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
*/ */
const TL = { const TL = {
debug: (tag, msg, ...args) => AppSettings.getDebug() && GM_log(`[TL] [DEBUG] [${new Date().toLocaleString()}] [${tag}] \n${msg}`, ...args), debug: (tag, msg, ...args) => AppSettings.getDebug() && GM_log(`[TL] [DEBUG] [${new Date().toLocaleString()}] [${tag}] \n${msg}`, ...args),
milestone: (tag, msg, ...args) => CONFIG.DEBUG_MILESTONE && GM_log(`[TL] [MILESTONE] [${new Date().toLocaleString()}] [${tag}] 🎯\n${msg}`, ...args),
log: (tag, msg, ...args) => GM_log(`[TL] [LOG] [${new Date().toLocaleString()}] [${tag}] \n${msg}`, ...args), log: (tag, msg, ...args) => GM_log(`[TL] [LOG] [${new Date().toLocaleString()}] [${tag}] \n${msg}`, ...args),
warn: (tag, msg, ...args) => GM_log(`[TL] [WARN] [${new Date().toLocaleString()}] [${tag}] ⚠️\n${msg}`, ...args), warn: (tag, msg, ...args) => GM_log(`[TL] [WARN] [${new Date().toLocaleString()}] [${tag}] ⚠️\n${msg}`, ...args),
error: (tag, msg, ...args) => GM_log(`[TL] [ERROR] [${new Date().toLocaleString()}] [${tag}] ❌\n${msg}`, ...args), error: (tag, msg, ...args) => GM_log(`[TL] [ERROR] [${new Date().toLocaleString()}] [${tag}] ❌\n${msg}`, ...args),
@@ -352,7 +378,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
* Navigate to URL với option forceReload * Navigate to URL với option forceReload
* @param {string} url - URL cần navigate * @param {string} url - URL cần navigate
*/ */
navigate: (url) => { navigateTo: (url) => {
window.location.href = url; window.location.href = url;
} }
}, },
@@ -419,7 +445,12 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
const BAF_TASKS = { const BAF_TASKS = {
NO_TASK: 'no_task', NO_TASK: 'no_task',
LOGIN: 'login',
WALLET_SPOT: 'wallet_spot',
WALLET_FUNDING: 'wallet_funding',
WALLET_EARN: 'wallet_earn',
ALPHA_SWAP: 'alpha_swap',
ALPHA_ORDER_HISTORY: 'alpha_order_history',
NO_STEP: 'no_step', NO_STEP: 'no_step',
}; };
@@ -630,7 +661,10 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
// Create dashboard overlay element // Create dashboard overlay element
create: () => { create: () => {
if (AppUi.dashboardOverlay.element) { if (AppUi.dashboardOverlay.element) {
document.body.removeChild(AppUi.dashboardOverlay.element); document.body.removeChild(AppUi.dashboardOverlay.element);
} }
@@ -655,6 +689,36 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
user-select: none; user-select: none;
`; `;
// Add close button (X)
const closeBtn = document.createElement('div');
closeBtn.style.cssText = `
position: absolute;
top: -8px;
left: -8px;
width: 20px;
height: 20px;
background: #dc3545;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 12px;
color: white;
border: 2px solid rgba(255, 255, 255, 0.2);
transition: all 0.2s ease;
font-weight: bold;
`;
closeBtn.innerHTML = '×';
closeBtn.title = 'Close popup';
closeBtn.addEventListener('click', () => {
AppUi.dashboardOverlay.hide();
AppSettings.setPopupVisible(false);
});
TL.dom.setHover(closeBtn, 'mouseenter', { scale: 1.5, background: '#c82333' });
TL.dom.setHover(closeBtn, 'mouseleave', { scale: 1, background: '#dc3545' });
overlay.appendChild(closeBtn);
// Add position toggle button // Add position toggle button
const positionBtn = document.createElement('div'); const positionBtn = document.createElement('div');
positionBtn.style.cssText = ` positionBtn.style.cssText = `
@@ -679,15 +743,18 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
positionBtn.addEventListener('click', () => { positionBtn.addEventListener('click', () => {
const newPosition = (AppSettings.getPopupPosition() % 4) + 1; const newPosition = (AppSettings.getPopupPosition() % 4) + 1;
AppSettings.setPopupPosition(newPosition); AppSettings.setPopupPosition(newPosition);
AppUi.statusOverlay.updatePosition(); AppUi.dashboardOverlay.updatePosition();
}); });
TL.dom.setHover(positionBtn, 'mouseenter', { scale: 1.5, background: '#0056b3' }); TL.dom.setHover(positionBtn, 'mouseenter', { scale: 1.5, background: '#0056b3' });
TL.dom.setHover(positionBtn, 'mouseleave', { scale: 1, background: '#007bff' }); TL.dom.setHover(positionBtn, 'mouseleave', { scale: 1, background: '#007bff' });
overlay.appendChild(positionBtn); overlay.appendChild(positionBtn);
AppUi.dashboardOverlay.element = overlay; AppUi.dashboardOverlay.element = overlay;
document.body.appendChild(overlay); document.body.appendChild(overlay);
return overlay; return overlay;
}, },
@@ -703,20 +770,37 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
// Update overlay content // Update overlay content
updateContent: () => { updateContent: () => {
try { try {
if (!AppUi.dashboardOverlay.element) {
AppUi.dashboardOverlay.create();
}
// Get status display // Get status display
let statusDisplay = ''; let statusDisplay = '';
switch (AppSession.getSessionStatus()) { const currentStatus = AppSession.getSessionStatus();
case AppEnums.BOT_STATUS.RUNNING:
statusDisplay = '▶️ Running'; switch (currentStatus) {
case AppEnums.BOT_STATUS.INITIALIZING:
statusDisplay = '🔄 Initializing';
break; break;
case AppEnums.BOT_STATUS.STOP: case AppEnums.BOT_STATUS.STOP:
statusDisplay = '⏹️ Stop'; statusDisplay = '⏹️ Stop';
break; break;
case AppEnums.BOT_STATUS.PAUSE:
statusDisplay = '⏸️ Pause';
break;
case AppEnums.BOT_STATUS.WAITING_FOR_TASK:
statusDisplay = '⏳ Waiting for Task';
break;
case AppEnums.BOT_STATUS.PERFORMING_TASK:
statusDisplay = '▶️ Performing Task';
break;
case AppEnums.BOT_STATUS.ERROR: case AppEnums.BOT_STATUS.ERROR:
statusDisplay = '❌ Error'; statusDisplay = '❌ Error';
break; break;
default: default:
statusDisplay = '❌ Error'; statusDisplay = '❓ Unknown';
break; break;
} }
@@ -741,16 +825,16 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
<div style="margin-bottom: 8px;"><strong>BAF Agent Dashboard</strong></div> <div style="margin-bottom: 8px;"><strong>BAF Agent Dashboard</strong></div>
<div style="margin-bottom: 4px;"> <div style="margin-bottom: 4px;">
<span id="safety-toggle-btn" style="color: ${safetyStatus.enabled ? '#28a745' : '#dc3545'}; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid ${safetyStatus.enabled ? '#28a745' : '#dc3545'}; background: ${safetyStatus.enabled ? 'rgba(40, 167, 69, 0.1)' : 'rgba(220, 53, 69, 0.1)'}; transition: all 0.2s ease;" title="Click to toggle safety status">🛟 Safety: ${safetyStatus.enabled ? '🛡️ Safe' : '🚨 Blocked'}</span> <span id="safety-toggle-btn-AithaiG2" style="color: ${safetyStatus.enabled ? '#28a745' : '#dc3545'}; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid ${safetyStatus.enabled ? '#28a745' : '#dc3545'}; background: ${safetyStatus.enabled ? 'rgba(40, 167, 69, 0.1)' : 'rgba(220, 53, 69, 0.1)'}; transition: all 0.2s ease;" title="Click to toggle safety status">🛟 Safety: ${safetyStatus.enabled ? '🛡️ Safe' : '🚨 Blocked'}</span>
</div> </div>
<div style="margin-bottom: 4px;"> <div style="margin-bottom: 4px;">
<span style="color: #6c757d; font-size: 11px;">🆔 Tab: ${AppSession.SESSION_ID.slice(-12)}</span> <span style="color: #6c757d; font-size: 11px;">🆔 Tab: ${AppSession.SESSION_ID.slice(-12)}</span>
</div> </div>
<div style="margin-bottom: 4px;"> <div style="margin-bottom: 4px;">
<span id="bot-status-toggle-btn" style="color: #007bff; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid #007bff; background: rgba(0, 123, 255, 0.1); transition: all 0.2s ease;" title="Click to toggle bot status">🤖 Bot Status: ${statusDisplay}</span> <span style="color: #007bff; padding: 2px 4px; background: rgba(0, 123, 255, 0.1);" title="Current bot status">🤖 Bot Status: ${statusDisplay}</span>
</div> </div>
<div style="margin-bottom: 4px;"> <div style="margin-bottom: 4px;">
<span id="startup-mode-toggle-btn" style="color: #ffc107; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid #ffc107; background: rgba(255, 193, 7, 0.1); transition: all 0.2s ease;" title="Click to toggle startup mode between auto and manual">🚀 Startup Mode: ${AppSettings.getBotStartupMode() === AppEnums.BOT_STARTUP_MODE.AUTO ? '🔄 Auto' : '✋ Manual'}</span> <span id="startup-mode-toggle-btn-tha9ieCa" style="color: #ffc107; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid #ffc107; background: rgba(255, 193, 7, 0.1); transition: all 0.2s ease;" title="Click to toggle startup mode between auto and manual">🚀 Startup Mode: ${AppSettings.getBotStartupMode() === AppEnums.BOT_STARTUP_MODE.AUTO ? '🔄 Auto' : '✋ Manual'}</span>
</div> </div>
<div style="margin-bottom: 4px;"> <div style="margin-bottom: 4px;">
<span style="color: #28a745;">📋 Task: ${AppSession.getCurrentTask() || 'None'}</span> <span style="color: #28a745;">📋 Task: ${AppSession.getCurrentTask() || 'None'}</span>
@@ -765,14 +849,32 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
<span style="color: #6f42c1;">Page: ${pageDisplay}</span> <span style="color: #6f42c1;">Page: ${pageDisplay}</span>
</div> </div>
<div style="margin-bottom: 4px;"> <div style="margin-bottom: 4px;">
<span id="server-toggle-btn" style="color: #e83e8c; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid #e83e8c; background: rgba(232, 62, 140, 0.1); transition: all 0.2s ease;" title="Click to switch between local and prod servers">🌐 Server: ${serverLabel} ${serverConnected}</span> <span id="server-toggle-btn-Youx4pho" style="color: #e83e8c; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid #e83e8c; background: rgba(232, 62, 140, 0.1); transition: all 0.2s ease;" title="Click to switch between local and prod servers">🌐 Server: ${serverLabel} ${serverConnected}</span>
</div> </div>
<div style="margin-bottom: 4px;"> <div style="margin-bottom: 4px;">
<span id="debug-toggle-btn" style="color: ${AppSettings.getDebug() ? '#17a2b8' : '#6c757d'}; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid ${AppSettings.getDebug() ? '#17a2b8' : '#6c757d'}; background: ${AppSettings.getDebug() ? 'rgba(23, 162, 184, 0.1)' : 'rgba(108, 117, 125, 0.1)'}; transition: all 0.2s ease;" title="Click to toggle debug mode">🐛 Debug: ${AppSettings.getDebug() ? '🔈 ON' : '🔇 OFF'}</span> <span id="debug-toggle-btn-Tai5guto" style="color: ${AppSettings.getDebug() ? '#17a2b8' : '#6c757d'}; cursor: pointer; padding: 2px 4px; border-radius: 3px; border: 1px solid ${AppSettings.getDebug() ? '#17a2b8' : '#6c757d'}; background: ${AppSettings.getDebug() ? 'rgba(23, 162, 184, 0.1)' : 'rgba(108, 117, 125, 0.1)'}; transition: all 0.2s ease;" title="Click to toggle debug mode">🐛 Debug: ${AppSettings.getDebug() ? '🔈 ON' : '🔇 OFF'}</span>
</div>
<div style="margin-bottom: 4px;">
<span style="color: ${CONFIG.DEBUG_MILESTONE ? '#28a745' : '#6c757d'}; padding: 2px 4px; border-radius: 3px; border: 1px solid ${CONFIG.DEBUG_MILESTONE ? '#28a745' : '#6c757d'}; background: ${CONFIG.DEBUG_MILESTONE ? 'rgba(40, 167, 69, 0.1)' : 'rgba(108, 117, 125, 0.1)'};" title="Milestone debug mode (configured in CONFIG)">🎯 Milestone: ${CONFIG.DEBUG_MILESTONE ? '🔈 ON' : '🔇 OFF'}</span>
</div>
<div style="margin-top: 8px; border-top: 1px solid rgba(255, 255, 255, 0.2); padding-top: 8px;">
<div style="text-align: center; margin-bottom: 8px;">
<span id="timer-display-ohr1Youj" style="color: #20c997; font-family: 'Courier New', monospace; font-size: 16px; font-weight: bold; padding: 4px 8px; border-radius: 4px; border: 1px solid #20c997; background: rgba(32, 201, 151, 0.1);" title="Session timer">⏱️ ${AppServices.Timer.getDisplay()}</span>
</div>
<div style="display: flex; gap: 4px; justify-content: center;">
<span id="play-btn-uPha3Mah" style="color: #28a745; cursor: pointer; padding: 4px 8px; border-radius: 4px; border: 1px solid #28a745; background: ${currentStatus === AppEnums.BOT_STATUS.WAITING_FOR_TASK || currentStatus === AppEnums.BOT_STATUS.PERFORMING_TASK ? 'rgba(40, 167, 69, 0.3)' : 'rgba(40, 167, 69, 0.1)'}; transition: all 0.2s ease; font-size: 14px;" title="Play - Start waiting for tasks">▶️</span>
<span id="pause-btn-Gai2quie" style="color: #ffc107; cursor: pointer; padding: 4px 8px; border-radius: 4px; border: 1px solid #ffc107; background: ${currentStatus === AppEnums.BOT_STATUS.PAUSE ? 'rgba(255, 193, 7, 0.3)' : 'rgba(255, 193, 7, 0.1)'}; transition: all 0.2s ease; font-size: 14px;" title="Pause - Stop but keep current task">⏸️</span>
<span id="stop-btn-jooK6che" style="color: #dc3545; cursor: pointer; padding: 4px 8px; border-radius: 4px; border: 1px solid #dc3545; background: ${currentStatus === AppEnums.BOT_STATUS.STOP || currentStatus === AppEnums.BOT_STATUS.ERROR ? 'rgba(220, 53, 69, 0.3)' : 'rgba(220, 53, 69, 0.1)'}; transition: all 0.2s ease; font-size: 14px;" title="Stop - Clear task and stop">⏹️</span>
</div>
</div> </div>
`; `;
// Update content (excluding position button) // Update content (excluding position button)
if (!AppUi.dashboardOverlay.element) {
TL.error('DASHBOARD-OVERLAY', '8.1. Element is null!');
return;
}
const contentDiv = AppUi.dashboardOverlay.element.querySelector('.baf-content') || document.createElement('div'); const contentDiv = AppUi.dashboardOverlay.element.querySelector('.baf-content') || document.createElement('div');
contentDiv.className = 'baf-content'; contentDiv.className = 'baf-content';
contentDiv.innerHTML = content; contentDiv.innerHTML = content;
@@ -782,7 +884,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
} }
// Add event listener for safety toggle button // Add event listener for safety toggle button
const safetyToggleBtn = contentDiv.querySelector('#safety-toggle-btn'); const safetyToggleBtn = contentDiv.querySelector('#safety-toggle-btn-AithaiG2');
if (safetyToggleBtn) { if (safetyToggleBtn) {
safetyToggleBtn.onclick = () => { safetyToggleBtn.onclick = () => {
const currentStatus = { const currentStatus = {
@@ -800,7 +902,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
} }
// Add event listener for debug toggle button // Add event listener for debug toggle button
const debugToggleBtn = contentDiv.querySelector('#debug-toggle-btn'); const debugToggleBtn = contentDiv.querySelector('#debug-toggle-btn-Tai5guto');
if (debugToggleBtn) { if (debugToggleBtn) {
debugToggleBtn.onclick = () => { debugToggleBtn.onclick = () => {
const newDebugState = !AppSettings.getDebug(); const newDebugState = !AppSettings.getDebug();
@@ -810,29 +912,47 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
}; };
} }
// Add event listener for bot status toggle button // Add event listeners for control buttons
const botStatusToggleBtn = contentDiv.querySelector('#bot-status-toggle-btn'); const playBtn = contentDiv.querySelector('#play-btn-uPha3Mah');
if (botStatusToggleBtn) { if (playBtn) {
botStatusToggleBtn.onclick = () => { playBtn.onclick = () => {
const currentBotStatus = AppSession.getSessionStatus(); AppServices.Status.play();
let newBotStatus;
// Logic: stop/error -> start, start -> stop
if (currentBotStatus === AppEnums.BOT_STATUS.RUNNING) {
newBotStatus = AppEnums.BOT_STATUS.STOP;
} else {
// STOP or ERROR -> RUNNING
newBotStatus = AppEnums.BOT_STATUS.RUNNING;
}
AppSession.setSessionStatus(newBotStatus);
// Update the content to reflect the change
AppUi.dashboardOverlay.updateContent(); AppUi.dashboardOverlay.updateContent();
}; };
} }
const pauseBtn = contentDiv.querySelector('#pause-btn-Gai2quie');
if (pauseBtn) {
pauseBtn.onclick = () => {
AppServices.Status.pause();
AppUi.dashboardOverlay.updateContent();
};
}
const stopBtn = contentDiv.querySelector('#stop-btn-jooK6che');
if (stopBtn) {
stopBtn.onclick = () => {
AppServices.Status.stop();
AppUi.dashboardOverlay.updateContent();
};
}
// Add hover effects for control buttons
if (playBtn) {
TL.dom.setHover(playBtn, 'mouseenter', { scale: 1.2, background: 'rgba(40, 167, 69, 0.2)' });
TL.dom.setHover(playBtn, 'mouseleave', { scale: 1, background: 'rgba(40, 167, 69, 0.1)' });
}
if (pauseBtn) {
TL.dom.setHover(pauseBtn, 'mouseenter', { scale: 1.2, background: 'rgba(255, 193, 7, 0.2)' });
TL.dom.setHover(pauseBtn, 'mouseleave', { scale: 1, background: 'rgba(255, 193, 7, 0.1)' });
}
if (stopBtn) {
TL.dom.setHover(stopBtn, 'mouseenter', { scale: 1.2, background: 'rgba(220, 53, 69, 0.2)' });
TL.dom.setHover(stopBtn, 'mouseleave', { scale: 1, background: 'rgba(220, 53, 69, 0.1)' });
}
// Add event listener for startup mode toggle button // Add event listener for startup mode toggle button
const startupModeToggleBtn = contentDiv.querySelector('#startup-mode-toggle-btn'); const startupModeToggleBtn = contentDiv.querySelector('#startup-mode-toggle-btn-tha9ieCa');
if (startupModeToggleBtn) { if (startupModeToggleBtn) {
startupModeToggleBtn.onclick = () => { startupModeToggleBtn.onclick = () => {
const currentStartupMode = AppSettings.getBotStartupMode(); const currentStartupMode = AppSettings.getBotStartupMode();
@@ -844,7 +964,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
} }
// Add event listener for server toggle button // Add event listener for server toggle button
const serverToggleBtn = contentDiv.querySelector('#server-toggle-btn'); const serverToggleBtn = contentDiv.querySelector('#server-toggle-btn-Youx4pho');
if (serverToggleBtn) { if (serverToggleBtn) {
serverToggleBtn.onclick = async () => { serverToggleBtn.onclick = async () => {
const currentServerType = AppSettings.getServerType(); const currentServerType = AppSettings.getServerType();
@@ -894,8 +1014,16 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
// Initialize dashboard overlay // Initialize dashboard overlay
init: () => { init: () => {
if (AppSettings.getPopupVisible()) { try {
AppUi.dashboardOverlay.show(); const popupVisible = AppSettings.getPopupVisible();
if (popupVisible) {
AppUi.dashboardOverlay.show();
} else {
}
} catch (error) {
TL.error('DASHBOARD-OVERLAY', '1.4.4. Error initializing dashboard overlay:', error);
throw error;
} }
} }
}, },
@@ -944,85 +1072,98 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
GM_registerMenuCommand("👁️ Toggle Popup", () => { GM_registerMenuCommand("👁️ Toggle Popup", () => {
AppUi.dashboardOverlay.toggle(); AppUi.dashboardOverlay.toggle();
}); });
} catch (error) { } catch (error) {
TL.error('MENU', 'Failed to create menu:', error); TL.error('MENU', '1.3.5. Failed to create menu:', error);
throw error; throw error;
} }
} }
}, },
}; };
// ====== APP TASKS ======
const AppTasks = {
login: async (step, data) => {
if (!AppServices.isReadyToRun()) {
TL.debug('APP-TASKS', 'Bot is not ready to run');
return;
}
TL.debug('APP-TASKS', `Login task ${step}`);
//set steps
switch (step) {
case "start":
AppSession.setSessionStatus(AppEnums.BOT_STATUS.PERFORMING_TASK);
AppSession.setCurrentStep("navigating-to-login-page");
TL.browser.navigateTo(BINANCE.page.getLoginUrl());
break;
}
},
};
// ====== APP SERVICE ====== // ====== APP SERVICE ======
const AppServices = { const AppServices = {
initialize: async () => { initialize: async () => {
await AppState.initialize(); try {
await AppState.initialize();
await AppSession.initialize();
await AppUi.menu.create(); // Khởi tạo timer
AppServices.Timer.initialize();
AppUi.dashboardOverlay.init(); await AppUi.menu.create();
AppUi.dashboardOverlay.init();
await AppServices.registerSession();
// Setup observers for dashboard overlay updates const status = AppSession.getSessionStatus();
AppServices.initObservers(); if (status === AppEnums.BOT_STATUS.INITIALIZING) {
const startupMode = AppSettings.getBotStartupMode();
if (startupMode === AppEnums.BOT_STARTUP_MODE.AUTO) {
AppSession.setSessionStatus(AppEnums.BOT_STATUS.WAITING_FOR_TASK);
} else {
AppSession.setSessionStatus(AppEnums.BOT_STATUS.STOP);
}
}
await AppServices.registerSession(); AppServices.initInterval();
} catch (error) {
// Set bot status based on startup mode TL.error('APP-SERVICES', 'Error during initialization:', error);
const startupMode = AppSettings.getBotStartupMode(); throw error;
if (startupMode === AppEnums.BOT_STARTUP_MODE.AUTO) {
AppSession.setSessionStatus(AppEnums.BOT_STATUS.RUNNING);
TL.debug('APP-SERVICES', 'Auto startup mode: Bot status set to RUNNING');
} else {
AppSession.setSessionStatus(AppEnums.BOT_STATUS.STOP);
TL.debug('APP-SERVICES', 'Manual startup mode: Bot status set to STOP');
} }
// Setup interval services
AppServices.initInterval();
AppState.update({ appInitialized: true });
TL.debug('APP-SERVICES', 'AppServices initialized');
}, },
initObservers: () => {
// AppState.subscribe('server_last_seen', () => {
// if (AppSettings.getPopupVisible()) {
// AppUi.dashboardOverlay.updateContent();
// }
// });
// AppState.subscribe('is_logged_in', () => {
// if (AppSettings.getPopupVisible()) {
// AppUi.dashboardOverlay.updateContent();
// }
// });
// AppState.subscribe('current_page', () => {
// if (AppSettings.getPopupVisible()) {
// AppUi.dashboardOverlay.updateContent();
// }
// });
},
registerSession: async () => { registerSession: async () => {
const msg = await BAF.register({ session_id: AppSession.SESSION_ID }); try {
//if ok, set session token const msg = await BAF.register({ session_id: AppSession.SESSION_ID });
if (msg.ok) {
AppSession.setSessionToken(msg.data.token); if (msg.ok) {
AppSession.setSessionBinded(true); AppSession.setSessionToken(msg.data.token);
TL.debug('APP-SERVICES', `Session token: ${AppSession.getSessionToken()}`); AppSession.setSessionBinded(true);
} else { } else {
AppSession.setSessionBinded(false);
TL.error('APP-SERVICES', `1.5.3. Failed to register session: ${msg.error}`);
}
} catch (error) {
TL.error('APP-SERVICES', '1.5.3. Error during session registration:', error);
AppSession.setSessionBinded(false); AppSession.setSessionBinded(false);
TL.error('APP-SERVICES', `Failed to register session: ${msg.error}`); throw error;
} }
}, },
// Setup interval services
initInterval: () => { initInterval: () => {
setInterval(() => AppServices.heartbeat(), CONFIG.HEARTBEAT_INTERVAL); try {
setInterval(() => AppUi.dashboardOverlay.updateContent(), CONFIG.DASHBOARD_UPDATE_INTERVAL); setInterval(() => AppServices.heartbeat(), CONFIG.HEARTBEAT_INTERVAL);
setInterval(() => AppUi.dashboardOverlay.updateContent(), CONFIG.DASHBOARD_UPDATE_INTERVAL);
TL.debug('APP-SERVICES', 'Interval services started'); // Timer update interval - cập nhật timer mỗi giây
setInterval(() => {
const timerDisplay = document.querySelector('#timer-display-ohr1Youj');
if (timerDisplay) {
timerDisplay.textContent = `⏱️ ${AppServices.Timer.getDisplay()}`;
}
}, 1000);
} catch (error) {
throw error;
}
}, },
isConnected: () => { isConnected: () => {
@@ -1030,9 +1171,86 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
return serverLastSeen && new Date() - serverLastSeen < 60000; return serverLastSeen && new Date() - serverLastSeen < 60000;
}, },
isReadyToRun: () => { isReadyToRun: () => {
return AppSession.getSessionBinded() && AppSettings.getSafetyGuard() && AppSession.getSessionStatus() === AppEnums.BOT_STATUS.RUNNING; return AppSession.getSessionBinded() && AppSettings.getSafetyGuard() && AppSession.getSessionStatus() === AppEnums.BOT_STATUS.WAITING_FOR_TASK;
},
// ====== TIMER SYSTEM ======
Timer: {
// Timer state management - Quản lý trạng thái timer
getStartTime: () => {
const time = sessionStorage.getItem(SESSION_STORAGE_KEYS.TIMER_START_TIME);
return time ? parseInt(time) : null;
},
setStartTime: time => {
if (time === null || time === undefined) {
sessionStorage.removeItem(SESSION_STORAGE_KEYS.TIMER_START_TIME);
} else {
sessionStorage.setItem(SESSION_STORAGE_KEYS.TIMER_START_TIME, time.toString());
}
},
isRunning: () => sessionStorage.getItem(SESSION_STORAGE_KEYS.TIMER_IS_RUNNING) === 'true',
setRunning: running => sessionStorage.setItem(SESSION_STORAGE_KEYS.TIMER_IS_RUNNING, running ? 'true' : 'false'),
getAccumulated: () => {
const time = sessionStorage.getItem(SESSION_STORAGE_KEYS.TIMER_ACCUMULATED);
return time ? parseInt(time) : 0;
},
setAccumulated: time => sessionStorage.setItem(SESSION_STORAGE_KEYS.TIMER_ACCUMULATED, time.toString()),
// Timer control methods
start: () => {
if (!AppServices.Timer.isRunning()) {
AppServices.Timer.setStartTime(Date.now());
AppServices.Timer.setRunning(true);
TL.debug('TIMER', 'Timer started');
}
},
pause: () => {
if (AppServices.Timer.isRunning()) {
const startTime = AppServices.Timer.getStartTime();
const currentTime = Date.now();
const elapsed = currentTime - startTime;
const accumulated = AppServices.Timer.getAccumulated();
AppServices.Timer.setAccumulated(accumulated + elapsed);
AppServices.Timer.setRunning(false);
AppServices.Timer.setStartTime(null);
}
},
stop: () => {
AppServices.Timer.pause();
AppServices.Timer.setAccumulated(0);
},
getDisplay: () => {
let totalTime = AppServices.Timer.getAccumulated();
if (AppServices.Timer.isRunning()) {
const startTime = AppServices.Timer.getStartTime();
if (startTime) {
const currentTime = Date.now();
totalTime += (currentTime - startTime);
}
}
const hours = Math.floor(totalTime / 3600000);
const minutes = Math.floor((totalTime % 3600000) / 60000);
const seconds = Math.floor((totalTime % 60000) / 1000);
const display = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
TL.debug('TIMER', `Display: ${display}, Running: ${AppServices.Timer.isRunning()}, Accumulated: ${totalTime}`);
return display;
},
initialize: () => {
AppServices.Timer.setAccumulated(0);
AppServices.Timer.setRunning(false);
AppServices.Timer.setStartTime(null);
TL.debug('TIMER', 'Timer initialized');
}
}, },
// ====== HEARTBEAT SYSTEM ====== // ====== HEARTBEAT SYSTEM ======
@@ -1066,7 +1284,7 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
} }
}, },
getTask: async () => { handleNewTask: async () => {
const data = { const data = {
logged_in: AppState.getIsLoggedIn(), logged_in: AppState.getIsLoggedIn(),
current_page: AppState.getCurrentPage(), current_page: AppState.getCurrentPage(),
@@ -1075,38 +1293,89 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
current_task_data: AppSession.getCurrentTaskData(), current_task_data: AppSession.getCurrentTaskData(),
current_step: AppSession.getCurrentStep(), current_step: AppSession.getCurrentStep(),
}; };
const task = await BAF.getTask(data);
return task; const taskResponse = await BAF.getTask(data);
TL.debug('APP-SERVICES', `Task: ${JSON.stringify(taskResponse, null, 2)}`);
if (taskResponse.ok) {
const task = taskResponse.data;
AppSession.setCurrentTask(task.type);
AppSession.setCurrentTaskData(task.data || null);
switch (task.type) {
case BAF_TASKS.NO_TASK:
TL.debug('APP-TASK', "No task. Sleep now");
break;
case BAF_TASKS.LOGIN:
AppTasks.login("start", task.data);
break;
default:
TL.debug('APP-TASK', `Unknown task 🛑`);
AppSession.setSessionStatus(AppEnums.BOT_STATUS.ERROR);
break;
}
}
}, },
handleTask: (task) => { resumeTask: async () => {
TL.debug('APP-SERVICES', `Task: ${JSON.stringify(task, null, 2)}`); TL.debug('APP-SERVICES', 'Resume task');
AppSession.setCurrentTask(task.task); const task = AppSession.getCurrentTask();
AppSession.setCurrentTaskData(task.data || null); const data = AppSession.getCurrentTaskData();
AppSession.setCurrentStep(task.step || null); const step = AppSession.getCurrentStep();
switch (task.task) { switch (task) {
case BAF_TASKS.NO_TASK: case BAF_TASKS.LOGIN:
TL.debug('APP-TASK', "No task. Sleep now"); AppTasks.login(step, data);
break;
default:
TL.debug('APP-TASK', `Unknown task 🛑`);
AppSession.setSessionStatus(AppEnums.BOT_STATUS.ERROR);
break; break;
};
},
// ====== BOT STATUS CONTROL ======
Status: {
play: () => {
AppServices.Timer.start();
AppSession.setSessionStatus(AppEnums.BOT_STATUS.WAITING_FOR_TASK);
},
pause: () => {
AppServices.Timer.pause();
AppSession.setSessionStatus(AppEnums.BOT_STATUS.PAUSE);
},
stop: () => {
AppServices.Timer.stop();
AppSession.setCurrentTask(BAF_TASKS.NO_TASK);
AppSession.setCurrentTaskData(null);
AppSession.setCurrentStep(BAF_TASKS.NO_STEP);
AppSession.setSessionStatus(AppEnums.BOT_STATUS.STOP);
} }
}, },
start: async () => { start: async () => {
while (true) { while (true) {
//checking bot status: running? switch (AppSession.getSessionStatus()) {
if (AppSession.getSessionStatus() === AppEnums.BOT_STATUS.RUNNING) { case AppEnums.BOT_STATUS.INITIALIZING:
const task = await AppServices.getTask(); TL.debug('APP-SERVICES', 'Bot is initializing, waiting...');
if (task.ok) { break;
AppServices.handleTask(task.data); case AppEnums.BOT_STATUS.STOP:
} TL.debug('APP-SERVICES', 'Bot is stopped, skipping task check');
} else { break;
TL.debug('APP-SERVICES', 'Bot is stopped, skipping task check'); case AppEnums.BOT_STATUS.PAUSE:
TL.debug('APP-SERVICES', 'Bot is paused, skipping task check');
break;
case AppEnums.BOT_STATUS.WAITING_FOR_TASK:
await AppServices.handleNewTask();
break;
case AppEnums.BOT_STATUS.PERFORMING_TASK:
await AppServices.resumeTask();
break;
case AppEnums.BOT_STATUS.ERROR:
TL.debug('APP-SERVICES', 'Bot is in error state, skipping task check');
break;
default:
TL.debug('APP-SERVICES', 'Bot is in unknown state, skipping task check');
break;
} }
await TL.delay(CONFIG.TASK_INTERVAL); await TL.delay(CONFIG.TASK_INTERVAL);
@@ -1116,9 +1385,12 @@ GM_log('[TL] 🏁 Welcome to Binance Alpha Farm Agent.');
// Start the application // Start the application
try { try {
await AppServices.initialize(); await AppServices.initialize();
} catch (error) { } catch (error) {
TL.error('MAIN', 'Failed to initialize app:', error); TL.error('MAIN', 'Failed to initialize app:', error);
TL.error('MAIN', 'Error stack:', error.stack);
} }
TL.log('MAIN', 'App started'); TL.log('MAIN', 'App started');