friends_repository.dart 2.95 KB
import 'package:doublefeel_flutter/core/network/api/friend_api.dart';
import 'package:doublefeel_flutter/core/result/app_result.dart';
import 'package:doublefeel_flutter/data/models/friend/friend_models.dart'
    as api_models;
import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';
import 'package:intl/intl.dart';

import '../models/friend_health_data.dart';
import '../models/friend_stress_state.dart';

abstract class FriendsRepository {
  Future<List<FriendHealthData>> getFriends({bool withHealthData = true});

  Future<void> updateRemark(int userId, String remark);

  Future<void> selectWatchFaceFriend(int userId);

  Future<void> deleteFriend(int userId);
}

class FriendsRepositoryImpl implements FriendsRepository {
  const FriendsRepositoryImpl(this._friendApi);

  final FriendApi _friendApi;

  @override
  Future<List<FriendHealthData>> getFriends(
      {bool withHealthData = true}) async {
    return switch (await _friendApi.friendList(withHealthData)) {
      AppSuccess(:final data) => data.list.map(_mapFriend).toList(),
      AppFailure(:final error) => throw error,
    };
  }

  @override
  Future<void> deleteFriend(int userId) async {
    switch (await _friendApi.deleteFriend(userId)) {
      case AppSuccess():
        return;
      case AppFailure(:final error):
        throw error;
    }
  }

  @override
  Future<void> selectWatchFaceFriend(int userId) async {
    switch (await _friendApi.updateFriend(userId, showInDial: 1)) {
      case AppSuccess():
        return;
      case AppFailure(:final error):
        throw error;
    }
  }

  @override
  Future<void> updateRemark(int userId, String remark) async {
    switch (await _friendApi.updateFriend(userId, remarkName: remark)) {
      case AppSuccess():
        return;
      case AppFailure(:final error):
        throw error;
    }
  }

  FriendHealthData _mapFriend(api_models.FriendItem friend) {
    final healthData = friend.healthData;
    final nickname = friend.friendNickname?.trim();
    final remark = friend.remarkName?.trim();

    return FriendHealthData(
      friendItem: friend,
      userId: friend.friendUserId,
      avatarUrl: friend.avatar,
      name: nickname == null || nickname.isEmpty
          ? l10n.friendsUnknownFriend
          : nickname,
      remark: remark == null || remark.isEmpty ? null : remark,
      updatedAt: _updatedAt(friend.updateTime),
      sleepQualityScore: healthData?.sleepEvaluate,
      steps: healthData?.totalSteps == null
          ? null
          : l10n.friendsStepCount(healthData!.totalSteps!),
      stressState: FriendStressState.fromValue(healthData?.hrvState),
      isOnWatchFace: friend.isShowInDial,
    );
  }

  String _updatedAt(int? timestamp) {
    if (timestamp == null) return l10n.friendsWaitingForData;
    final milliseconds =
        timestamp < 1000000000000 ? timestamp * 1000 : timestamp;
    final time = DateTime.fromMillisecondsSinceEpoch(milliseconds);
    return l10n.friendsUpdatedAt(DateFormat('HH:mm').format(time));
  }
}