119 lines
3.3 KiB
Dart
119 lines
3.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
import '../models/group_model.dart';
|
|
import '../models/group_member_model.dart';
|
|
import '../services/service_locator.dart';
|
|
import '../services/api/api_client.dart';
|
|
|
|
class GroupProvider extends ChangeNotifier {
|
|
List<GroupModel> _groups = [];
|
|
final Map<String, List<GroupMemberModel>> _membersCache = {};
|
|
LoadStatus _status = LoadStatus.idle;
|
|
String? _error;
|
|
|
|
List<GroupModel> get groups => List.unmodifiable(_groups);
|
|
LoadStatus get status => _status;
|
|
String? get error => _error;
|
|
bool get isLoading => _status == LoadStatus.loading;
|
|
|
|
int get totalCount => _groups.length;
|
|
int get activeCount => _groups.where((g) => g.isActive).length;
|
|
|
|
List<GroupMemberModel> membersOf(String groupId) =>
|
|
List.unmodifiable(_membersCache[groupId] ?? []);
|
|
|
|
Future<void> loadGroups() async {
|
|
_status = LoadStatus.loading;
|
|
_error = null;
|
|
notifyListeners();
|
|
|
|
try {
|
|
_groups = await ServiceLocator().groups.getGroups();
|
|
_status = LoadStatus.success;
|
|
} on ApiException catch (e) {
|
|
_error = e.message;
|
|
_status = LoadStatus.error;
|
|
} catch (e) {
|
|
_error = 'خطا در دریافت گروهها';
|
|
_status = LoadStatus.error;
|
|
}
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<GroupModel?> createGroup(String name) async {
|
|
_error = null;
|
|
try {
|
|
final group = await ServiceLocator().groups.createGroup(name);
|
|
_groups = [..._groups, group];
|
|
_membersCache[group.id] = [];
|
|
notifyListeners();
|
|
return group;
|
|
} on ApiException catch (e) {
|
|
_error = e.message;
|
|
notifyListeners();
|
|
return null;
|
|
} catch (e) {
|
|
_error = 'خطا در ایجاد گروه';
|
|
notifyListeners();
|
|
return null;
|
|
}
|
|
}
|
|
|
|
Future<bool> inviteMember(String groupId, String username) async {
|
|
_error = null;
|
|
try {
|
|
await ServiceLocator().groups.inviteMember(groupId, username);
|
|
// We don't necessarily add to cache here because it's an invitation.
|
|
// But we can reload members to be sure.
|
|
await loadGroupMembers(groupId);
|
|
return true;
|
|
} on ApiException catch (e) {
|
|
_error = e.message;
|
|
notifyListeners();
|
|
return false;
|
|
} catch (e) {
|
|
_error = 'خطا در دعوت عضو';
|
|
notifyListeners();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<bool> removeMember(String groupId, String userId) async {
|
|
_error = null;
|
|
try {
|
|
await ServiceLocator().groups.removeMember(groupId, userId);
|
|
_membersCache[groupId]?.removeWhere((m) => m.userId == userId);
|
|
notifyListeners();
|
|
return true;
|
|
} on ApiException catch (e) {
|
|
_error = e.message;
|
|
notifyListeners();
|
|
return false;
|
|
} catch (e) {
|
|
_error = 'خطا در حذف عضو';
|
|
notifyListeners();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<void> loadGroupMembers(String groupId) async {
|
|
try {
|
|
final members = await ServiceLocator().groups.getGroupMembers(groupId);
|
|
_membersCache[groupId] = members.toList();
|
|
notifyListeners();
|
|
} on ApiException catch (e) {
|
|
_error = e.message;
|
|
notifyListeners();
|
|
} catch (_) {
|
|
// Silently fail — members may just not be loaded
|
|
}
|
|
}
|
|
|
|
void clearError() {
|
|
_error = null;
|
|
notifyListeners();
|
|
}
|
|
}
|
|
|
|
// Re-export to avoid importing user_provider for the enum
|
|
enum LoadStatus { idle, loading, success, error }
|