diff --git a/gui/project_tile.py b/gui/project_tile.py index 51e3662..7f156b7 100644 --- a/gui/project_tile.py +++ b/gui/project_tile.py @@ -668,18 +668,18 @@ pause # Update UI optimistically immediately self.update_activity_status(False) - success = activity_service.stop_activity() + success = activity_service.stop_activity(self.project.name) logger.info(f"Activity stop result: success={success}") if not success: # Revert on failure - check if we're still the active project - current = activity_service.get_current_activity() - if current and current.get('projectName') == self.project.name: + current = activity_service.get_current_activity(self.project.name) + if current: logger.error(f"Failed to stop activity for {self.project.name}, reverting UI") self.update_activity_status(True, activity_service.user_name, True) else: - logger.error(f"Failed to stop activity, but no current activity found") + logger.error(f"Failed to stop activity, project not found in active list") def _toggle_activity(self): """Toggle activity for this project""" @@ -705,9 +705,7 @@ pause ) return - current_activity = activity_service.get_current_activity() - is_this_project_active = (current_activity and - current_activity.get('projectName') == self.project.name) + is_this_project_active = activity_service.is_project_active_for_user(self.project.name) logger.info(f"Current activity status: {is_this_project_active}") @@ -872,11 +870,9 @@ pause logger.debug(f"check_activity called for project: {self.project.name}") # First check if this is our own current activity - current_activity = activity_service.get_current_activity() - is_own_current = (current_activity and - current_activity.get('projectName') == self.project.name) + is_own_current = activity_service.is_project_active_for_user(self.project.name) - logger.debug(f"Current activity check - is_own_current: {is_own_current}, current_activity: {current_activity}") + logger.debug(f"Current activity check - is_own_current: {is_own_current}") # Get all activities for this project from server active_users = [] diff --git a/services/activity_sync.py b/services/activity_sync.py index d9c83fd..56e0c6a 100644 --- a/services/activity_sync.py +++ b/services/activity_sync.py @@ -22,7 +22,7 @@ class ActivitySyncService: self.connected = False self.on_activities_update = None self.activities = [] - self.current_activity = None + self.active_projects = [] # Changed from single current_activity to list # Load settings self.load_settings() @@ -143,7 +143,7 @@ class ActivitySyncService: logger.error(f"Error disconnecting: {e}") def start_activity(self, project_name: str, project_path: str, description: str = ""): - """Start a new activity""" + """Start a new activity (adds to active projects list)""" logger.debug(f"start_activity called for: {project_name}") if not self.connected or not self.sio: @@ -151,15 +151,22 @@ class ActivitySyncService: return False try: - # Set current activity immediately - self.current_activity = { + # Check if project is already active + existing = next((p for p in self.active_projects if p['projectName'] == project_name), None) + if existing: + logger.info(f"Project {project_name} is already active") + return True + + # Add to active projects list + new_activity = { 'projectName': project_name, 'projectPath': project_path, 'userId': self.user_id, 'userName': self.user_name, 'isActive': True } - logger.debug(f"Set current_activity: {self.current_activity}") + self.active_projects.append(new_activity) + logger.debug(f"Added to active_projects: {new_activity}") # Emit to server self.sio.emit('activity-start', { @@ -172,29 +179,45 @@ class ActivitySyncService: return True except Exception as e: logger.error(f"Failed to start activity: {e}") - self.current_activity = None + # Remove from list on failure + self.active_projects = [p for p in self.active_projects if p['projectName'] != project_name] return False - def stop_activity(self): - """Stop the current activity""" - logger.debug(f"stop_activity called, current: {self.current_activity}") + def stop_activity(self, project_name: str = None): + """Stop activity for a specific project or all activities if no project specified""" + logger.debug(f"stop_activity called for project: {project_name}") if not self.connected or not self.sio: logger.warning("Not connected to activity server") return False try: - # Store project name for logging - project_name = self.current_activity.get('projectName') if self.current_activity else 'None' - - # Clear current activity immediately - self.current_activity = None - logger.debug("Cleared current_activity") - - # Emit to server - self.sio.emit('activity-stop') - - logger.info(f"Stopped activity for project: {project_name}") + if project_name: + # Stop specific project + activity = next((p for p in self.active_projects if p['projectName'] == project_name), None) + if not activity: + logger.warning(f"Project {project_name} is not in active projects") + return False + + # Remove from active projects + self.active_projects = [p for p in self.active_projects if p['projectName'] != project_name] + logger.debug(f"Removed {project_name} from active_projects") + + # Emit to server with project name + self.sio.emit('activity-stop', {'projectName': project_name}) + + logger.info(f"Stopped activity for project: {project_name}") + else: + # Stop all activities (backward compatibility) + project_names = [p['projectName'] for p in self.active_projects] + self.active_projects = [] + logger.debug("Cleared all active_projects") + + # Emit to server (server should handle stopping all activities for this user) + self.sio.emit('activity-stop') + + logger.info(f"Stopped all activities: {project_names}") + return True except Exception as e: logger.error(f"Failed to stop activity: {e}") @@ -238,10 +261,27 @@ class ActivitySyncService: return activity return None - def get_current_activity(self) -> Optional[Dict]: - """Get current user's activity""" - logger.debug(f"get_current_activity called, returning: {self.current_activity}") - return self.current_activity + def get_current_activity(self, project_name: str = None) -> Optional[Dict]: + """Get current user's activity for a specific project or first active project""" + if project_name: + # Return specific project if active + activity = next((p for p in self.active_projects if p['projectName'] == project_name), None) + logger.debug(f"get_current_activity for {project_name}, returning: {activity}") + return activity + else: + # Return first active project for backward compatibility + activity = self.active_projects[0] if self.active_projects else None + logger.debug(f"get_current_activity called, returning: {activity}") + return activity + + def get_all_current_activities(self) -> List[Dict]: + """Get all current user's active projects""" + logger.debug(f"get_all_current_activities called, returning {len(self.active_projects)} activities") + return self.active_projects.copy() + + def is_project_active_for_user(self, project_name: str) -> bool: + """Check if a specific project is active for the current user""" + return any(p['projectName'] == project_name for p in self.active_projects) def _fetch_initial_activities(self): """Fetch initial activities after connection"""