[예보:마음을 읽는] 개인 리스트 화면 - 사용자가 Firesotre에 저장한 화면을 보여준다. [ MVVM ]

2022. 4. 8. 20:49[앱개발] 예보 : 마음을 읽다.

개인 날씨 리스트 : 통계화면 (스크롤뷰)

개인화면 - 스크롤뷰

 

개인화면 - 리스트뷰 

 

개인화면의 구성은 CustomScrollView 로 구성되어 개인통계/상세/피드리스트 위젯으로 구성 하였다.

 

화면에 대한 이벤트는

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:mind_weather/domain/model/weather_model.dart';

part 'weather_event.freezed.dart';
part 'weather_event.g.dart';

@freezed
class WeatherEvent with _$WeatherEvent {
  const factory WeatherEvent.deleteWeather(WeatherModel weatherModel) =
      DeleteWeather;

  const factory WeatherEvent.geWeathers() = GetWeathers;

  const factory WeatherEvent.getByIdWeathers(String uid) = GetByIdWeathers;

  const factory WeatherEvent.getWeatherById(String uid) = GetWeatherById;

  factory WeatherEvent.fromJson(Map<String, dynamic> json) =>
      _$WeatherEventFromJson(json);
}

 

 

화면을 구성하는 ViewModel 은

import 'package:flutter/cupertino.dart';
import 'package:mind_weather/domain/model/weather_model.dart';
import 'package:mind_weather/domain/repository/weather_repository.dart';
import 'weather_event.dart';
import 'weather_state.dart';

/// 이벤트의 기능을 구현하는곳
class PersonListViewModel extends ChangeNotifier {
  final WeatherRepository weatherRepository;

  PersonListViewModel(this.weatherRepository) {
    _getWeathers();
  }

  WeatherState _weatherState = WeatherState();

  WeatherState get weatherState => _weatherState;

  Future<void> onEvent(WeatherEvent event) async {
    event.when(
        geWeathers: _getWeathers,
        getWeatherById: _getWeatherById,
        getByIdWeathers: _getByIdWeathers,
        deleteWeather: _deleteWeather);
  }

  Future<void> _deleteWeather(WeatherModel weatherModel) async {
    await weatherRepository.deleteWeather(weatherModel);
    await _getWeathers();
  }

  Future<void> _getWeathers() async {
    List<WeatherModel>? weathers = await weatherRepository.getWeathers();
    _weatherState = _weatherState.copyWith(weatherModels: weathers);
    notifyListeners();
  }

  Future<void> _getWeatherById(String uid) async {
    final weatherModel = await weatherRepository.getWeatherById(uid);
    _weatherState = _weatherState.copyWith(weatherModel: weatherModel);
  }

  Future<void> _getByIdWeathers(String uid) async {
    List<WeatherModel>? weathers = await weatherRepository.getByIdWeathers(uid);
    _weatherState = _weatherState.copyWith(weatherModels: weathers);
    notifyListeners();
  }
}

그리고 ViewModel에서 WeatherState로 상태를 관리한다.

 

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:mind_weather/domain/model/weather_model.dart';

part 'weather_state.freezed.dart';
part 'weather_state.g.dart';

@freezed
class WeatherState with _$WeatherState {
  @JsonSerializable(fieldRename: FieldRename.snake, explicitToJson: true)
  const factory WeatherState({
    WeatherModel? weatherModel,
    List<WeatherModel>? weatherModels,
  }) = _WeatherState;

  factory WeatherState.fromJson(Map<String, dynamic> json) =>
      _$WeatherStateFromJson(json);
}

ViewModel에서는 Repository를 의존성 주입하였고, 

Firestore의 유틸은 아래와 같이 구현하였다.

 

Future<List<WeatherModel>?> getByIdWeathers(String uid) async {
  final maps = await firestore
      .collection(collectionName)
      .where("user_uid", isEqualTo: uid)
      .orderBy("time_stamp", descending: true)
      .get();
  return maps.docs.map((dataShot) {
    WeatherModel model = WeatherModel.fromJson(dataShot.data());

    model = model.copyWith(uid: dataShot.id);
    return model;
  }).toList();
}

Future<List<WeatherModel>?> getWeathers() async {
  final maps = await firestore
      .collection(collectionName)
      .orderBy("time_stamp", descending: true)
      .get();
  return maps.docs.map((dataShot) {
    WeatherModel model = WeatherModel.fromJson(dataShot.data());

    model = model.copyWith(uid: dataShot.id);
    return model;
  }).toList();
}

Future<WeatherModel?> getWeatherById(String uid) async {
  WeatherModel weatherModel = (await firestore
      .collection(collectionName)
      .doc(uid)
      .get()) as WeatherModel;
  return weatherModel;
}

 

 

현재 MVVM모델로 프로젝트를 구성중이고,

 

Presentation

     ㄴ person_list

               ㄴ component

               ㄴ view_model

               ㄴ person_list_screen.dart

 

형태로 구현하였다.