|
6 | 6 |
|
7 | 7 | import * as vscode from 'vscode'; |
8 | 8 |
|
9 | | -import type { AuthService } from '../services/authService'; |
10 | | -import type { ConfigManager } from '../utils/configManager'; |
11 | | -import type { WebSocketClient } from '../services/wsClient'; |
12 | 9 | import type { Logger } from '../utils/logger'; |
13 | | -import type { UserDTO, UserStatus, UserStatusType } from '@devradar/shared'; |
| 10 | +import type { ActivityPayload, UserDTO, UserStatus, UserStatusType } from '@devradar/shared'; |
14 | 11 |
|
15 | 12 | /** |
16 | 13 | * Friend item with status information. |
@@ -221,19 +218,80 @@ export class FriendsProvider |
221 | 218 | FriendTreeItem | GroupTreeItem | undefined |
222 | 219 | >(); |
223 | 220 | private friends = new Map<string, FriendInfo>(); |
224 | | - private isAuthenticated = false; |
225 | 221 |
|
226 | 222 | readonly onDidChangeTreeData = this.onDidChangeTreeDataEmitter.event; |
227 | 223 |
|
228 | | - constructor( |
229 | | - private readonly authService: AuthService, |
230 | | - private readonly configManager: ConfigManager, |
231 | | - private readonly logger: Logger |
232 | | - ) { |
| 224 | + constructor(private readonly logger: Logger) { |
233 | 225 | this.disposables.push(this.onDidChangeTreeDataEmitter); |
234 | 226 | } |
235 | 227 |
|
236 | | - // ... (keeping method order) |
| 228 | + /** |
| 229 | + * Returns a tree item for the given element. |
| 230 | + */ |
| 231 | + getTreeItem(element: FriendTreeItem | GroupTreeItem): vscode.TreeItem { |
| 232 | + return element; |
| 233 | + } |
| 234 | + |
| 235 | + /** |
| 236 | + * Returns children for the given element or root elements if no element is provided. |
| 237 | + */ |
| 238 | + getChildren(element?: FriendTreeItem | GroupTreeItem): (FriendTreeItem | GroupTreeItem)[] { |
| 239 | + if (element instanceof GroupTreeItem) { |
| 240 | + // Return friends filtered by the group's status |
| 241 | + const statusGroup = element.statusGroup; |
| 242 | + const friendsList = Array.from(this.friends.values()); |
| 243 | + |
| 244 | + if (statusGroup === 'all') { |
| 245 | + return friendsList.map((friend) => new FriendTreeItem(friend)); |
| 246 | + } |
| 247 | + |
| 248 | + return friendsList |
| 249 | + .filter((friend) => friend.status === statusGroup) |
| 250 | + .map((friend) => new FriendTreeItem(friend)); |
| 251 | + } |
| 252 | + |
| 253 | + // Root level: return groups with counts |
| 254 | + const friendsList = Array.from(this.friends.values()); |
| 255 | + const groups: GroupTreeItem[] = []; |
| 256 | + |
| 257 | + const onlineCount = friendsList.filter((f) => f.status === 'online').length; |
| 258 | + const idleCount = friendsList.filter((f) => f.status === 'idle').length; |
| 259 | + const dndCount = friendsList.filter((f) => f.status === 'dnd').length; |
| 260 | + const offlineCount = friendsList.filter((f) => f.status === 'offline').length; |
| 261 | + |
| 262 | + if (onlineCount > 0) groups.push(new GroupTreeItem('online', onlineCount)); |
| 263 | + if (idleCount > 0) groups.push(new GroupTreeItem('idle', idleCount)); |
| 264 | + if (dndCount > 0) groups.push(new GroupTreeItem('dnd', dndCount)); |
| 265 | + if (offlineCount > 0) groups.push(new GroupTreeItem('offline', offlineCount)); |
| 266 | + |
| 267 | + return groups; |
| 268 | + } |
| 269 | + |
| 270 | + /** |
| 271 | + * Refreshes the friends tree view. |
| 272 | + */ |
| 273 | + refresh(): void { |
| 274 | + this.onDidChangeTreeDataEmitter.fire(undefined); |
| 275 | + } |
| 276 | + |
| 277 | + /** |
| 278 | + * Builds activity info from ActivityPayload. |
| 279 | + */ |
| 280 | + private buildActivityInfo(activity: ActivityPayload): FriendInfo['activity'] { |
| 281 | + const result: FriendInfo['activity'] = { |
| 282 | + sessionDuration: activity.sessionDuration, |
| 283 | + }; |
| 284 | + if (activity.fileName !== undefined) { |
| 285 | + result.fileName = activity.fileName; |
| 286 | + } |
| 287 | + if (activity.language !== undefined) { |
| 288 | + result.language = activity.language; |
| 289 | + } |
| 290 | + if (activity.project !== undefined) { |
| 291 | + result.project = activity.project; |
| 292 | + } |
| 293 | + return result; |
| 294 | + } |
237 | 295 |
|
238 | 296 | /** |
239 | 297 | * Handles friend status update from WebSocket. |
@@ -284,55 +342,6 @@ export class FriendsProvider |
284 | 342 | ); |
285 | 343 | } |
286 | 344 |
|
287 | | - /** |
288 | | - * Fetches friends list from server. |
289 | | - */ |
290 | | - private async fetchFriends(): Promise<void> { |
291 | | - try { |
292 | | - const token = this.authService.getToken(); |
293 | | - if (!token) { |
294 | | - return; |
295 | | - } |
296 | | - |
297 | | - this.logger.debug('Fetching friends list from server...'); |
298 | | - const serverUrl = this.configManager.get('serverUrl'); |
299 | | - |
300 | | - const response = await fetch(`${serverUrl}/api/v1/friends?limit=100`, { |
301 | | - headers: { |
302 | | - Authorization: `Bearer ${token}`, |
303 | | - }, |
304 | | - }); |
305 | | - |
306 | | - if (!response.ok) { |
307 | | - throw new Error(`Failed to fetch friends: ${String(response.status)}`); |
308 | | - } |
309 | | - |
310 | | - const json = (await response.json()) as { data: any[] }; |
311 | | - const friendsList = json.data; |
312 | | - |
313 | | - this.friends.clear(); |
314 | | - |
315 | | - for (const friendData of friendsList) { |
316 | | - const friend: FriendInfo = { |
317 | | - id: friendData.id, |
318 | | - username: friendData.username, |
319 | | - displayName: friendData.displayName, |
320 | | - avatarUrl: friendData.avatarUrl, |
321 | | - status: friendData.status, |
322 | | - activity: friendData.activity, |
323 | | - lastUpdated: Date.now(), |
324 | | - }; |
325 | | - this.friends.set(friend.id, friend); |
326 | | - } |
327 | | - |
328 | | - this.onDidChangeTreeDataEmitter.fire(undefined); |
329 | | - this.logger.info(`Fetched ${String(this.friends.size)} friends`); |
330 | | - } catch (error) { |
331 | | - this.logger.error('Failed to fetch friends', error); |
332 | | - void vscode.window.showErrorMessage('DevRadar: Failed to load friends list'); |
333 | | - } |
334 | | - } |
335 | | - |
336 | 345 | /** |
337 | 346 | * Adds a friend to the list (called when receiving initial state). |
338 | 347 | */ |
|
0 commit comments