Remade frontend dashboard as flutter dashboard, still WIP

This commit is contained in:
Nate Anderson
2025-06-13 09:20:42 -06:00
parent 8ea06b12f7
commit b373a93f0e
207 changed files with 9869 additions and 46 deletions
+32
View File
@@ -0,0 +1,32 @@
import 'package:json_annotation/json_annotation.dart';
part 'achievement.g.dart';
@JsonSerializable()
class Achievement {
final int id;
final String name;
final String description;
@JsonKey(name: 'xp_reward')
final int xpReward;
@JsonKey(name: 'achieved_at')
final String? achievedAt;
@JsonKey(name: 'level_at_achievement')
final int? levelAtAchievement;
Achievement({
required this.id,
required this.name,
required this.description,
required this.xpReward,
this.achievedAt,
this.levelAtAchievement,
});
factory Achievement.fromJson(Map<String, dynamic> json) =>
_$AchievementFromJson(json);
Map<String, dynamic> toJson() => _$AchievementToJson(this);
bool get isAchieved => achievedAt != null;
}
@@ -0,0 +1,26 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'achievement.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Achievement _$AchievementFromJson(Map<String, dynamic> json) => Achievement(
id: (json['id'] as num).toInt(),
name: json['name'] as String,
description: json['description'] as String,
xpReward: (json['xp_reward'] as num).toInt(),
achievedAt: json['achieved_at'] as String?,
levelAtAchievement: (json['level_at_achievement'] as num?)?.toInt(),
);
Map<String, dynamic> _$AchievementToJson(Achievement instance) =>
<String, dynamic>{
'id': instance.id,
'name': instance.name,
'description': instance.description,
'xp_reward': instance.xpReward,
'achieved_at': instance.achievedAt,
'level_at_achievement': instance.levelAtAchievement,
};
+28
View File
@@ -0,0 +1,28 @@
import 'package:json_annotation/json_annotation.dart';
part 'activity.g.dart';
@JsonSerializable()
class Activity {
final int id;
final String type;
final String application;
final Map<String, dynamic>? metadata;
final String timestamp;
@JsonKey(name: 'duration_seconds')
final int durationSeconds;
Activity({
required this.id,
required this.type,
required this.application,
this.metadata,
required this.timestamp,
required this.durationSeconds,
});
factory Activity.fromJson(Map<String, dynamic> json) =>
_$ActivityFromJson(json);
Map<String, dynamic> toJson() => _$ActivityToJson(this);
}
+25
View File
@@ -0,0 +1,25 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'activity.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Activity _$ActivityFromJson(Map<String, dynamic> json) => Activity(
id: (json['id'] as num).toInt(),
type: json['type'] as String,
application: json['application'] as String,
metadata: json['metadata'] as Map<String, dynamic>?,
timestamp: json['timestamp'] as String,
durationSeconds: (json['duration_seconds'] as num).toInt(),
);
Map<String, dynamic> _$ActivityToJson(Activity instance) => <String, dynamic>{
'id': instance.id,
'type': instance.type,
'application': instance.application,
'metadata': instance.metadata,
'timestamp': instance.timestamp,
'duration_seconds': instance.durationSeconds,
};
@@ -0,0 +1,170 @@
import 'package:json_annotation/json_annotation.dart';
part 'activity_event.g.dart';
@JsonSerializable()
class ActivityEvent {
final ActivityEventType type;
final String application;
final String? metadata;
final DateTime timestamp;
ActivityEvent({
required this.type,
required this.application,
this.metadata,
required this.timestamp,
});
factory ActivityEvent.fromJson(Map<String, dynamic> json) =>
_$ActivityEventFromJson(json);
Map<String, dynamic> toJson() => _$ActivityEventToJson(this);
}
enum ActivityEventType {
@JsonValue('coding')
coding,
@JsonValue('focused_browsing')
focusedBrowsing,
@JsonValue('collaboration')
collaboration,
@JsonValue('meetings')
meetings,
@JsonValue('misc')
misc,
@JsonValue('uncategorized')
uncategorized;
String get id {
switch (this) {
case ActivityEventType.coding:
return 'coding';
case ActivityEventType.focusedBrowsing:
return 'focused_browsing';
case ActivityEventType.collaboration:
return 'collaboration';
case ActivityEventType.meetings:
return 'meetings';
case ActivityEventType.misc:
return 'misc';
case ActivityEventType.uncategorized:
return 'uncategorized';
}
}
String get displayName {
switch (this) {
case ActivityEventType.coding:
return 'Coding';
case ActivityEventType.focusedBrowsing:
return 'Focused Browsing';
case ActivityEventType.collaboration:
return 'Collaboration';
case ActivityEventType.meetings:
return 'Meetings';
case ActivityEventType.misc:
return 'Miscellaneous';
case ActivityEventType.uncategorized:
return 'Uncategorized';
}
}
String get icon {
switch (this) {
case ActivityEventType.coding:
return '💻';
case ActivityEventType.focusedBrowsing:
return '🔍';
case ActivityEventType.collaboration:
return '🤝';
case ActivityEventType.meetings:
return '📅';
case ActivityEventType.misc:
return '📝';
case ActivityEventType.uncategorized:
return '';
}
}
static ActivityEventType categorize({
String? eventId,
String? applicationId,
String? applicationTitle,
}) {
// Direct type mappings
if (eventId != null) {
final matchType = ActivityEventType.values
.where((e) => e.id == eventId)
.firstOrNull;
if (matchType != null) {
return matchType;
}
}
if (applicationId != null) {
// Fallback to application-based categorization for 'other' type
switch (applicationId.toLowerCase()) {
case 'codium':
case 'code':
case 'vscode':
case 'nvim':
case 'vim':
case 'emacs':
return coding;
case 'com.slack.slack':
case 'slack':
case 'discord':
case 'teams':
case 'mattermost':
return collaboration;
// terminals
case 'com.mitchellh.ghostty':
case 'alacritty':
case 'kitty':
case 'gnome-terminal':
case 'konsole':
case 'foot':
switch (applicationTitle) {
case String s when s.contains('git'):
case String s when s == 'hx' || s == 'helix':
return coding;
case null:
default:
return misc;
}
case 'org.keepassxc.keepassxc':
case 'keepassxc':
case 'bitwarden':
case '1password':
return misc; // security tools now categorized as misc
case 'firefox':
case 'chrome':
case 'safari':
case 'edge':
return focusedBrowsing;
case 'zoom':
case 'zoom.us':
case 'us.zoom.xos':
return meetings;
default:
return uncategorized;
}
}
return uncategorized;
}
}
enum ZoomStatus {
@JsonValue('none')
none,
@JsonValue('zoom_focused')
zoomFocused, // Zoom window active, no media
@JsonValue('zoom_background')
zoomBackground, // Zoom running, not focused, no media
@JsonValue('background_meeting')
backgroundMeeting, // Meeting active but Zoom not focused
@JsonValue('active_meeting')
activeMeeting, // Meeting active and Zoom focused
}
@@ -0,0 +1,32 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'activity_event.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ActivityEvent _$ActivityEventFromJson(Map<String, dynamic> json) =>
ActivityEvent(
type: $enumDecode(_$ActivityEventTypeEnumMap, json['type']),
application: json['application'] as String,
metadata: json['metadata'] as String?,
timestamp: DateTime.parse(json['timestamp'] as String),
);
Map<String, dynamic> _$ActivityEventToJson(ActivityEvent instance) =>
<String, dynamic>{
'type': _$ActivityEventTypeEnumMap[instance.type]!,
'application': instance.application,
'metadata': instance.metadata,
'timestamp': instance.timestamp.toIso8601String(),
};
const _$ActivityEventTypeEnumMap = {
ActivityEventType.coding: 'coding',
ActivityEventType.focusedBrowsing: 'focused_browsing',
ActivityEventType.collaboration: 'collaboration',
ActivityEventType.meetings: 'meetings',
ActivityEventType.misc: 'misc',
ActivityEventType.uncategorized: 'uncategorized',
};
@@ -0,0 +1,73 @@
import 'package:json_annotation/json_annotation.dart';
part 'classification.g.dart';
@JsonSerializable()
class ApplicationClassification {
final int id;
@JsonKey(name: 'application_name')
final String applicationName;
@JsonKey(name: 'category_id')
final String categoryId;
@JsonKey(name: 'created_at')
final String createdAt;
@JsonKey(name: 'updated_at')
final String updatedAt;
ApplicationClassification({
required this.id,
required this.applicationName,
required this.categoryId,
required this.createdAt,
required this.updatedAt,
});
factory ApplicationClassification.fromJson(Map<String, dynamic> json) =>
_$ApplicationClassificationFromJson(json);
Map<String, dynamic> toJson() => _$ApplicationClassificationToJson(this);
}
@JsonSerializable()
class UnclassifiedApplication {
final int id;
@JsonKey(name: 'application_name')
final String applicationName;
@JsonKey(name: 'first_seen')
final String firstSeen;
@JsonKey(name: 'last_seen')
final String lastSeen;
@JsonKey(name: 'occurrence_count')
final int occurrenceCount;
UnclassifiedApplication({
required this.id,
required this.applicationName,
required this.firstSeen,
required this.lastSeen,
required this.occurrenceCount,
});
factory UnclassifiedApplication.fromJson(Map<String, dynamic> json) =>
_$UnclassifiedApplicationFromJson(json);
Map<String, dynamic> toJson() => _$UnclassifiedApplicationToJson(this);
}
@JsonSerializable()
class ClassificationRequest {
@JsonKey(name: 'application_name')
final String applicationName;
@JsonKey(name: 'category_id')
final String categoryId;
ClassificationRequest({
required this.applicationName,
required this.categoryId,
});
factory ClassificationRequest.fromJson(Map<String, dynamic> json) =>
_$ClassificationRequestFromJson(json);
Map<String, dynamic> toJson() => _$ClassificationRequestToJson(this);
}
@@ -0,0 +1,61 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'classification.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ApplicationClassification _$ApplicationClassificationFromJson(
Map<String, dynamic> json,
) => ApplicationClassification(
id: (json['id'] as num).toInt(),
applicationName: json['application_name'] as String,
categoryId: json['category_id'] as String,
createdAt: json['created_at'] as String,
updatedAt: json['updated_at'] as String,
);
Map<String, dynamic> _$ApplicationClassificationToJson(
ApplicationClassification instance,
) => <String, dynamic>{
'id': instance.id,
'application_name': instance.applicationName,
'category_id': instance.categoryId,
'created_at': instance.createdAt,
'updated_at': instance.updatedAt,
};
UnclassifiedApplication _$UnclassifiedApplicationFromJson(
Map<String, dynamic> json,
) => UnclassifiedApplication(
id: (json['id'] as num).toInt(),
applicationName: json['application_name'] as String,
firstSeen: json['first_seen'] as String,
lastSeen: json['last_seen'] as String,
occurrenceCount: (json['occurrence_count'] as num).toInt(),
);
Map<String, dynamic> _$UnclassifiedApplicationToJson(
UnclassifiedApplication instance,
) => <String, dynamic>{
'id': instance.id,
'application_name': instance.applicationName,
'first_seen': instance.firstSeen,
'last_seen': instance.lastSeen,
'occurrence_count': instance.occurrenceCount,
};
ClassificationRequest _$ClassificationRequestFromJson(
Map<String, dynamic> json,
) => ClassificationRequest(
applicationName: json['application_name'] as String,
categoryId: json['category_id'] as String,
);
Map<String, dynamic> _$ClassificationRequestToJson(
ClassificationRequest instance,
) => <String, dynamic>{
'application_name': instance.applicationName,
'category_id': instance.categoryId,
};
@@ -0,0 +1,112 @@
import 'package:json_annotation/json_annotation.dart';
part 'dashboard_stats.g.dart';
@JsonSerializable()
class DashboardStats {
final TodayStats today;
final StreakStats streaks;
@JsonKey(name: 'recent_activity')
final List<RecentActivity> recentActivity;
final int timestamp;
DashboardStats({
required this.today,
required this.streaks,
required this.recentActivity,
required this.timestamp,
});
factory DashboardStats.fromJson(Map<String, dynamic> json) =>
_$DashboardStatsFromJson(json);
Map<String, dynamic> toJson() => _$DashboardStatsToJson(this);
}
@JsonSerializable()
class TodayStats {
final int level;
final int xp;
@JsonKey(name: 'focus_time')
final int focusTime;
@JsonKey(name: 'meeting_time')
final int meetingTime;
@JsonKey(name: 'focus_sessions')
final int focusSessions;
TodayStats({
required this.level,
required this.xp,
required this.focusTime,
required this.meetingTime,
required this.focusSessions,
});
factory TodayStats.fromJson(Map<String, dynamic> json) =>
_$TodayStatsFromJson(json);
Map<String, dynamic> toJson() => _$TodayStatsToJson(this);
}
@JsonSerializable()
class StreakStats {
@JsonKey(name: 'current_streak')
final int currentStreak;
@JsonKey(name: 'longest_streak')
final int longestStreak;
StreakStats({
required this.currentStreak,
required this.longestStreak,
});
factory StreakStats.fromJson(Map<String, dynamic> json) =>
_$StreakStatsFromJson(json);
Map<String, dynamic> toJson() => _$StreakStatsToJson(this);
}
@JsonSerializable()
class RecentActivity {
final String type;
final String application;
final String timestamp;
@JsonKey(name: 'duration_seconds')
final int durationSeconds;
RecentActivity({
required this.type,
required this.application,
required this.timestamp,
required this.durationSeconds,
});
factory RecentActivity.fromJson(Map<String, dynamic> json) =>
_$RecentActivityFromJson(json);
Map<String, dynamic> toJson() => _$RecentActivityToJson(this);
}
@JsonSerializable()
class StatsHistory {
final String date;
final int level;
final int xp;
@JsonKey(name: 'focus_time')
final int focusTime;
@JsonKey(name: 'meeting_time')
final int meetingTime;
StatsHistory({
required this.date,
required this.level,
required this.xp,
required this.focusTime,
required this.meetingTime,
});
factory StatsHistory.fromJson(Map<String, dynamic> json) =>
_$StatsHistoryFromJson(json);
Map<String, dynamic> toJson() => _$StatsHistoryToJson(this);
}
@@ -0,0 +1,86 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'dashboard_stats.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
DashboardStats _$DashboardStatsFromJson(Map<String, dynamic> json) =>
DashboardStats(
today: TodayStats.fromJson(json['today'] as Map<String, dynamic>),
streaks: StreakStats.fromJson(json['streaks'] as Map<String, dynamic>),
recentActivity: (json['recent_activity'] as List<dynamic>)
.map((e) => RecentActivity.fromJson(e as Map<String, dynamic>))
.toList(),
timestamp: (json['timestamp'] as num).toInt(),
);
Map<String, dynamic> _$DashboardStatsToJson(DashboardStats instance) =>
<String, dynamic>{
'today': instance.today,
'streaks': instance.streaks,
'recent_activity': instance.recentActivity,
'timestamp': instance.timestamp,
};
TodayStats _$TodayStatsFromJson(Map<String, dynamic> json) => TodayStats(
level: (json['level'] as num).toInt(),
xp: (json['xp'] as num).toInt(),
focusTime: (json['focus_time'] as num).toInt(),
meetingTime: (json['meeting_time'] as num).toInt(),
focusSessions: (json['focus_sessions'] as num).toInt(),
);
Map<String, dynamic> _$TodayStatsToJson(TodayStats instance) =>
<String, dynamic>{
'level': instance.level,
'xp': instance.xp,
'focus_time': instance.focusTime,
'meeting_time': instance.meetingTime,
'focus_sessions': instance.focusSessions,
};
StreakStats _$StreakStatsFromJson(Map<String, dynamic> json) => StreakStats(
currentStreak: (json['current_streak'] as num).toInt(),
longestStreak: (json['longest_streak'] as num).toInt(),
);
Map<String, dynamic> _$StreakStatsToJson(StreakStats instance) =>
<String, dynamic>{
'current_streak': instance.currentStreak,
'longest_streak': instance.longestStreak,
};
RecentActivity _$RecentActivityFromJson(Map<String, dynamic> json) =>
RecentActivity(
type: json['type'] as String,
application: json['application'] as String,
timestamp: json['timestamp'] as String,
durationSeconds: (json['duration_seconds'] as num).toInt(),
);
Map<String, dynamic> _$RecentActivityToJson(RecentActivity instance) =>
<String, dynamic>{
'type': instance.type,
'application': instance.application,
'timestamp': instance.timestamp,
'duration_seconds': instance.durationSeconds,
};
StatsHistory _$StatsHistoryFromJson(Map<String, dynamic> json) => StatsHistory(
date: json['date'] as String,
level: (json['level'] as num).toInt(),
xp: (json['xp'] as num).toInt(),
focusTime: (json['focus_time'] as num).toInt(),
meetingTime: (json['meeting_time'] as num).toInt(),
);
Map<String, dynamic> _$StatsHistoryToJson(StatsHistory instance) =>
<String, dynamic>{
'date': instance.date,
'level': instance.level,
'xp': instance.xp,
'focus_time': instance.focusTime,
'meeting_time': instance.meetingTime,
};
@@ -0,0 +1,37 @@
import 'package:json_annotation/json_annotation.dart';
part 'focus_session.g.dart';
@JsonSerializable()
class FocusSession {
final int id;
@JsonKey(name: 'start_time')
final String startTime;
@JsonKey(name: 'end_time')
final String? endTime;
@JsonKey(name: 'duration_seconds')
final int? durationSeconds;
@JsonKey(name: 'xp_earned')
final int xpEarned;
final String status;
@JsonKey(name: 'created_at')
final String createdAt;
@JsonKey(name: 'updated_at')
final String updatedAt;
FocusSession({
required this.id,
required this.startTime,
this.endTime,
this.durationSeconds,
required this.xpEarned,
required this.status,
required this.createdAt,
required this.updatedAt,
});
factory FocusSession.fromJson(Map<String, dynamic> json) =>
_$FocusSessionFromJson(json);
Map<String, dynamic> toJson() => _$FocusSessionToJson(this);
}
@@ -0,0 +1,30 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'focus_session.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
FocusSession _$FocusSessionFromJson(Map<String, dynamic> json) => FocusSession(
id: (json['id'] as num).toInt(),
startTime: json['start_time'] as String,
endTime: json['end_time'] as String?,
durationSeconds: (json['duration_seconds'] as num?)?.toInt(),
xpEarned: (json['xp_earned'] as num).toInt(),
status: json['status'] as String,
createdAt: json['created_at'] as String,
updatedAt: json['updated_at'] as String,
);
Map<String, dynamic> _$FocusSessionToJson(FocusSession instance) =>
<String, dynamic>{
'id': instance.id,
'start_time': instance.startTime,
'end_time': instance.endTime,
'duration_seconds': instance.durationSeconds,
'xp_earned': instance.xpEarned,
'status': instance.status,
'created_at': instance.createdAt,
'updated_at': instance.updatedAt,
};
+41
View File
@@ -0,0 +1,41 @@
import 'package:json_annotation/json_annotation.dart';
part 'system_log.g.dart';
@JsonSerializable()
class SystemLogResponse {
final List<String> logs;
SystemLogResponse({
required this.logs,
});
factory SystemLogResponse.fromJson(Map<String, dynamic> json) =>
_$SystemLogResponseFromJson(json);
Map<String, dynamic> toJson() => _$SystemLogResponseToJson(this);
}
enum LogLevel {
@JsonValue('debug')
debug,
@JsonValue('info')
info,
@JsonValue('warn')
warn,
@JsonValue('error')
error;
String get name {
switch (this) {
case LogLevel.debug:
return 'debug';
case LogLevel.info:
return 'info';
case LogLevel.warn:
return 'warn';
case LogLevel.error:
return 'error';
}
}
}
@@ -0,0 +1,15 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'system_log.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
SystemLogResponse _$SystemLogResponseFromJson(Map<String, dynamic> json) =>
SystemLogResponse(
logs: (json['logs'] as List<dynamic>).map((e) => e as String).toList(),
);
Map<String, dynamic> _$SystemLogResponseToJson(SystemLogResponse instance) =>
<String, dynamic>{'logs': instance.logs};
@@ -0,0 +1,79 @@
import 'package:json_annotation/json_annotation.dart';
import 'dashboard_stats.dart';
part 'websocket_message.g.dart';
@JsonSerializable()
class WebSocketMessage {
final WebSocketMessageType type;
final Map<String, dynamic>? data;
final int timestamp;
WebSocketMessage({required this.type, this.data, required this.timestamp});
factory WebSocketMessage.fromJson(Map<String, dynamic> json) => _$WebSocketMessageFromJson(json);
Map<String, dynamic> toJson() => _$WebSocketMessageToJson(this);
// Factory constructors for specific message types
factory WebSocketMessage.statsUpdate(DashboardStats stats) {
return WebSocketMessage(
type: WebSocketMessageType.statsUpdate,
data: stats.toJson(),
timestamp: DateTime.now().millisecondsSinceEpoch,
);
}
factory WebSocketMessage.xpBreakdownUpdate(Map<String, int> breakdown) {
return WebSocketMessage(
type: WebSocketMessageType.xpBreakdownUpdate,
data: breakdown,
timestamp: DateTime.now().millisecondsSinceEpoch,
);
}
factory WebSocketMessage.achievementUnlocked(Map<String, dynamic> achievement) {
return WebSocketMessage(
type: WebSocketMessageType.achievementUnlocked,
data: achievement,
timestamp: DateTime.now().millisecondsSinceEpoch,
);
}
factory WebSocketMessage.levelUp(int newLevel) {
return WebSocketMessage(
type: WebSocketMessageType.levelUp,
data: {'level': newLevel},
timestamp: DateTime.now().millisecondsSinceEpoch,
);
}
factory WebSocketMessage.focusSessionComplete(Map<String, dynamic> session) {
return WebSocketMessage(
type: WebSocketMessageType.focusSessionComplete,
data: session,
timestamp: DateTime.now().millisecondsSinceEpoch,
);
}
factory WebSocketMessage.ping() {
return WebSocketMessage(type: WebSocketMessageType.ping, timestamp: DateTime.now().millisecondsSinceEpoch);
}
factory WebSocketMessage.pong() {
return WebSocketMessage(type: WebSocketMessageType.pong, timestamp: DateTime.now().millisecondsSinceEpoch);
}
}
enum WebSocketMessageType {
statsUpdate('stats_update'),
xpBreakdownUpdate('xp_breakdown_update'),
achievementUnlocked('achievement_unlocked'),
levelUp('level_up'),
focusSessionComplete('focus_session_complete'),
ping('ping'),
pong('pong');
const WebSocketMessageType(this.value);
final String value;
}
@@ -0,0 +1,31 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'websocket_message.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
WebSocketMessage _$WebSocketMessageFromJson(Map<String, dynamic> json) =>
WebSocketMessage(
type: $enumDecode(_$WebSocketMessageTypeEnumMap, json['type']),
data: json['data'] as Map<String, dynamic>?,
timestamp: (json['timestamp'] as num).toInt(),
);
Map<String, dynamic> _$WebSocketMessageToJson(WebSocketMessage instance) =>
<String, dynamic>{
'type': _$WebSocketMessageTypeEnumMap[instance.type]!,
'data': instance.data,
'timestamp': instance.timestamp,
};
const _$WebSocketMessageTypeEnumMap = {
WebSocketMessageType.statsUpdate: 'statsUpdate',
WebSocketMessageType.xpBreakdownUpdate: 'xpBreakdownUpdate',
WebSocketMessageType.achievementUnlocked: 'achievementUnlocked',
WebSocketMessageType.levelUp: 'levelUp',
WebSocketMessageType.focusSessionComplete: 'focusSessionComplete',
WebSocketMessageType.ping: 'ping',
WebSocketMessageType.pong: 'pong',
};
+11
View File
@@ -0,0 +1,11 @@
library xp_models;
// Models
export 'src/models/activity_event.dart';
export 'src/models/dashboard_stats.dart';
export 'src/models/achievement.dart';
export 'src/models/activity.dart';
export 'src/models/classification.dart';
export 'src/models/focus_session.dart';
export 'src/models/system_log.dart';
export 'src/models/websocket_message.dart';