didvan-app/lib/providers/user.dart

376 lines
12 KiB
Dart
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ignore: depend_on_referenced_packages
import 'package:collection/collection.dart';
import 'package:didvan/main.dart';
import 'package:didvan/models/enums.dart';
import 'package:didvan/models/user.dart';
import 'package:didvan/models/view/alert_data.dart';
import 'package:didvan/providers/core.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart';
import 'package:didvan/services/notification/firebase_api.dart';
import 'package:didvan/services/storage/storage.dart';
import 'package:didvan/utils/action_sheet.dart';
class UserProvider extends CoreProvier {
late User user;
bool isAuthenticated = false;
int _unreadMessageCount = 0;
// --- ADDED ---
String? _welcomeMessage;
bool _isLoadingWelcome = true;
String? get welcomeMessage => _welcomeMessage;
bool get isLoadingWelcome => _isLoadingWelcome;
// --- END ADDED ---
set unreadMessageCount(int value) {
if (value < 0) {
return;
}
_unreadMessageCount = value;
notifyListeners();
}
int get unreadMessageCount => _unreadMessageCount;
// static final List<MapEntry> _radarMarkQueue = [];
// static final List<MapEntry> _newsMarkQueue = [];
// static final List<MapEntry> _studioMarkQueue = [];
static final List<MapEntry> _statisticMarkQueue = [];
static final List<Map> _itemMarkQueue = [];
// --- ADDED ---
Future<void> fetchWelcomeMessage() async {
if (!_isLoadingWelcome) {
_isLoadingWelcome = true;
notifyListeners(); // برای نمایش لودینگ اگر قبلا مخفی شده بود
}
try {
const String url = 'https://api.didvan.app/ai/aiwellcom';
// اطمینان از اینکه توکن وجود دارد قبل از ارسال درخواست
if (RequestService.token == null) {
print("UserProvider: fetchWelcomeMessage skipped, token is null.");
_isLoadingWelcome = false; // توکن نیست، لودینگ تمام
notifyListeners();
return;
}
print("UserProvider: Fetching welcome message..."); // Log start
final service = RequestService(url, useAutherization: true);
await service.post();
if (service.isSuccess) {
print("UserProvider: Welcome message API success."); // Log success
final period = service.data('period');
final userData = service.data('user'); // Rename to avoid conflict with class member 'user'
if (period != null && userData is Map && userData.containsKey('fullName')) {
final fullName = userData['fullName'];
_welcomeMessage = '$period بخیر $fullName 👋';
print("UserProvider: Welcome message set: $_welcomeMessage"); // Log message content
} else {
print("UserProvider: Welcome message API success but data format unexpected.");
_welcomeMessage = null; // Clear if data format is wrong
}
} else {
print("UserProvider: Welcome message API failed. Status: ${service.statusCode}, Error: ${service.errorMessage}"); // Log failure
_welcomeMessage = null; // Clear on API error
}
} catch (e) {
print("UserProvider: Exception fetching welcome message: $e"); // Log exception
_welcomeMessage = null; // Clear on exception
} finally {
// همیشه لودینگ رو false کن و UI رو آپدیت کن
_isLoadingWelcome = false;
print("UserProvider: fetchWelcomeMessage finished. isLoadingWelcome: $_isLoadingWelcome"); // Log end
notifyListeners();
}
}
// --- END ADDED ---
Future<String?> setAndGetToken({String? newToken}) async {
try {
if (newToken == null) {
final token = await StorageService.getValue(key: 'token');
return token;
}
await StorageService.setValue(key: 'token', value: newToken);
return null;
} catch (e) {
return null;
}
}
Future<bool> getUserInfo() async {
isAuthenticated = true; // Assume authenticated until proven otherwise
print("UserProvider: Getting user info..."); // Log start
final RequestService service = RequestService(RequestHelper.userInfo);
await service.httpGet();
if (service.statusCode == 401) {
print("UserProvider: getUserInfo failed - Unauthorized (401).");
isAuthenticated = false; // Not authenticated
return false;
}
if (service.isSuccess) {
if (service.result['user'] == null) {
print("UserProvider: getUserInfo success but user data is null.");
isAuthenticated = false; // Treat as not authenticated if user data is null
return false;
}
try {
print("UserProvider: User info fetched successfully."); // Log success
user = User.fromJson(service.result['user']);
await StorageService.setValue(
key: 'notificationTimeRangeStart',
value: service.result['user']['start'],
);
await StorageService.setValue(
key: 'notificationTimeRangeEnd',
value: service.result['user']['end'],
);
// توکن فایربیس رو ثبت کن
await _registerFirebaseToken();
notifyListeners(); // اول اطلاعات کاربر رو آپدیت کن
// --- ADDED ---
// حالا که اطلاعات کاربر و توکن لود شده، پیام خوشامدگویی رو بگیر
await fetchWelcomeMessage();
// --- END ADDED ---
return true;
} catch (e) {
print("UserProvider: Exception processing user info: $e");
isAuthenticated = false; // Error processing, assume not authenticated
return false;
}
}
// If service failed for reasons other than 401
print("UserProvider: getUserInfo failed. Status: ${service.statusCode}, Error: ${service.errorMessage}");
isAuthenticated = false; // Failed to get user info
// Consider throwing an error or handling it based on app logic
// throw 'Getting user from API failed!'; // Or return false
return false;
}
Future<void> _registerFirebaseToken() async {
if (FirebaseApi.fcmToken != null) {
final service = RequestService(RequestHelper.firebaseToken, body: {
'token': FirebaseApi.fcmToken,
});
await service.put();
}
}
Future<bool> setProfilePhoto(dynamic file) async {
appState = AppState.isolatedBusy;
final RequestService service =
RequestService(RequestHelper.updateProfilePhoto);
await service.multipart(
file: file,
method: 'PUT',
fileName: 'user-profile',
fieldName: 'photo',
mediaExtension: 'jpg',
mediaFormat: 'image',
);
if (service.isSuccess) {
user = user.copyWith(photo: service.result['photo']);
appState = AppState.idle;
return true;
}
appState = AppState.failed;
return false;
}
Future<bool> deleteProfilePhoto() async {
appState = AppState.isolatedBusy;
final RequestService service =
RequestService(RequestHelper.updateProfilePhoto);
await service.delete();
if (service.isSuccess) {
user = user.copyWith(photo: null);
appState = AppState.idle;
return true;
}
appState = AppState.idle;
return false;
}
Future<bool?> checkUsername(String username) async {
if (user.username == username) return true;
final RequestService service = RequestService(
RequestHelper.checkUsername,
body: {'username': username},
);
await service.post();
if (service.isSuccess) {
return service.result['available'];
}
return null;
}
Future<void> editProfile(
String fullName,
String? username,
String? email,
) async {
appState = AppState.isolatedBusy;
final service = RequestService(
RequestHelper.updateProfile,
body: {
'fullName': fullName,
'email': email,
'username': username,
},
);
await service.put();
if (service.isSuccess) {
user = user.copyWith(
fullName: fullName,
email: email,
username: username,
photo: user.photo);
appState = AppState.idle;
ActionSheetUtils(navigatorKey.currentContext!).pop();
ActionSheetUtils(navigatorKey.currentContext!).showAlert(
AlertData(
message: 'پروفایل با موفقیت ویرایش شد',
aLertType: ALertType.success,
),
);
return;
}
appState = AppState.idle;
ActionSheetUtils(navigatorKey.currentContext!).showAlert(
AlertData(
message: service.errorMessage,
),
);
}
static Future<void> changeItemMark(String type, int id, bool? value,
{String? description}) async {
_itemMarkQueue.add({
'type': type,
'id': id,
'value': value,
'description': description,
});
Future.delayed(const Duration(milliseconds: 500), () async {
final lastChange =
_itemMarkQueue.lastWhereOrNull((item) => item['id'] == id);
if (lastChange == null) return;
final service = RequestService(
RequestHelper.editItemBookmark(type, id),
body: {'description': lastChange['description']},
);
if (lastChange['value'] == true) {
await service.post();
} else if (lastChange['value'] == false) {
await service.delete();
} else {
service.put();
}
_itemMarkQueue.removeWhere((element) => element['id'] == id);
});
}
static Future<void> changeItemLiked(
String type,
int id,
bool value,
) async {
if (type == 'infography') {
type = 'banner';
}
final service = RequestService(
RequestHelper.editItemLike(type, id),
);
if (value) {
await service.post();
} else {
await service.delete();
}
}
// static Future<void> changeRadarMark(int id, bool value) async {
//   _radarMarkQueue.add(MapEntry(id, value));
//   Future.delayed(const Duration(milliseconds: 500), () async {
//     final MapEntry? lastChange =
//         _radarMarkQueue.lastWhereOrNull((item) => item.key == id);
//     if (lastChange == null) return;
//     final service = RequestService(RequestHelper.mark(id, 'radar'));
//     if (lastChange.value) {
//       await service.post();
//     } else {
//       await service.delete();
//     }
//     _radarMarkQueue.removeWhere((element) => element.key == id);
//   });
// }
// static Future<void> changeStudioMark(int id, bool value) async {
//   _studioMarkQueue.add(MapEntry(id, value));
//   Future.delayed(const Duration(milliseconds: 500), () async {
//     final MapEntry? lastChange =
//         _studioMarkQueue.lastWhereOrNull((item) => item.key == id);
//     if (lastChange == null) return;
//     final service = RequestService(RequestHelper.mark(id, 'studio'));
//     if (lastChange.value) {
//       await service.post();
//     } else {
//       await service.delete();
//     }
//     _studioMarkQueue.removeWhere((element) => element.key == id);
//   });
// }
// static Future<void> changeNewsMark(int id, bool value) async {
//   _newsMarkQueue.add(MapEntry(id, value));
//   Future.delayed(const Duration(milliseconds: 500), () async {
//     final MapEntry? lastChange =
//         _newsMarkQueue.lastWhereOrNull((item) => item.key == id);
//     if (lastChange == null) return;
//     final service = RequestService(RequestHelper.mark(id, 'news'));
//     if (lastChange.value) {
//       await service.post();
//     } else {
//       await service.delete();
//   ----------------------------------------------------------------
//   }
//     _newsMarkQueue.removeWhere((element) => element.key == id);
//   });
// }
static Future<void> changeStatisticMark(int id, bool value) async {
_statisticMarkQueue.add(MapEntry(id, value));
Future.delayed(const Duration(milliseconds: 500), () async {
final MapEntry? lastChange =
_statisticMarkQueue.lastWhereOrNull((item) => item.key == id);
if (lastChange == null) return;
final service = RequestService(RequestHelper.mark(id, 'statistic'));
if (lastChange.value) {
await service.post();
} else {
await service.delete();
}
_statisticMarkQueue.removeWhere((element) => element.key == id);
});
}
// Future<void> getUnreadMessageCount() async {
//   final RequestService service = RequestService(RequestHelper.directs);
//   await service.httpGet();
//   if (service.isSuccess) {
//     _unreadMessageCount = service.result['unread'] ?? 0;
//   }
// }
}