mirror of
https://github.com/immich-app/immich.git
synced 2025-07-09 03:04:16 -04:00
feat(mobile): people sync
This commit is contained in:
parent
4b7fb162ee
commit
55e7622e32
2
mobile/drift_schemas/main/drift_schema_v1.json
generated
2
mobile/drift_schemas/main/drift_schema_v1.json
generated
File diff suppressed because one or more lines are too long
10
mobile/lib/domain/models/face_model.dart
Normal file
10
mobile/lib/domain/models/face_model.dart
Normal file
@ -0,0 +1,10 @@
|
||||
enum SourceType {
|
||||
// do not change this order!
|
||||
machineLearning,
|
||||
exif,
|
||||
manual,
|
||||
}
|
||||
|
||||
class Face {
|
||||
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
import 'dart:convert';
|
||||
|
||||
class Person {
|
||||
const Person({
|
||||
// TODO: Remove PersonDto once Isar is removed
|
||||
class PersonDto {
|
||||
const PersonDto({
|
||||
required this.id,
|
||||
this.birthDate,
|
||||
required this.isHidden,
|
||||
@ -22,7 +23,7 @@ class Person {
|
||||
return 'Person(id: $id, birthDate: $birthDate, isHidden: $isHidden, name: $name, thumbnailPath: $thumbnailPath, updatedAt: $updatedAt)';
|
||||
}
|
||||
|
||||
Person copyWith({
|
||||
PersonDto copyWith({
|
||||
String? id,
|
||||
DateTime? birthDate,
|
||||
bool? isHidden,
|
||||
@ -30,7 +31,7 @@ class Person {
|
||||
String? thumbnailPath,
|
||||
DateTime? updatedAt,
|
||||
}) {
|
||||
return Person(
|
||||
return PersonDto(
|
||||
id: id ?? this.id,
|
||||
birthDate: birthDate ?? this.birthDate,
|
||||
isHidden: isHidden ?? this.isHidden,
|
||||
@ -51,8 +52,8 @@ class Person {
|
||||
};
|
||||
}
|
||||
|
||||
factory Person.fromMap(Map<String, dynamic> map) {
|
||||
return Person(
|
||||
factory PersonDto.fromMap(Map<String, dynamic> map) {
|
||||
return PersonDto(
|
||||
id: map['id'] as String,
|
||||
birthDate: map['birthDate'] != null
|
||||
? DateTime.fromMillisecondsSinceEpoch(map['birthDate'] as int)
|
||||
@ -68,11 +69,11 @@ class Person {
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory Person.fromJson(String source) =>
|
||||
Person.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
factory PersonDto.fromJson(String source) =>
|
||||
PersonDto.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
bool operator ==(covariant Person other) {
|
||||
bool operator ==(covariant PersonDto other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other.id == id &&
|
||||
@ -93,3 +94,60 @@ class Person {
|
||||
updatedAt.hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
// Model for a person stored in the server
|
||||
class Person {
|
||||
final String id;
|
||||
final DateTime createdAt;
|
||||
final DateTime updatedAt;
|
||||
final String ownerId;
|
||||
final String name;
|
||||
final String? thumbnailPath;
|
||||
final bool isHidden;
|
||||
final DateTime? birthDate;
|
||||
final String? faceAssetId;
|
||||
final bool isFavorite;
|
||||
final String? color;
|
||||
|
||||
const Person({
|
||||
required this.id,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
required this.ownerId,
|
||||
required this.name,
|
||||
this.thumbnailPath,
|
||||
required this.isHidden,
|
||||
this.birthDate,
|
||||
this.faceAssetId,
|
||||
required this.isFavorite,
|
||||
this.color,
|
||||
});
|
||||
|
||||
Person copyWith({
|
||||
String? id,
|
||||
DateTime? createdAt,
|
||||
DateTime? updatedAt,
|
||||
String? ownerId,
|
||||
String? name,
|
||||
String? thumbnailPath,
|
||||
bool? isHidden,
|
||||
DateTime? birthDate,
|
||||
String? faceAssetId,
|
||||
bool? isFavorite,
|
||||
String? color,
|
||||
}) {
|
||||
return Person(
|
||||
id: id ?? this.id,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
ownerId: ownerId ?? this.ownerId,
|
||||
name: name ?? this.name,
|
||||
thumbnailPath: thumbnailPath ?? this.thumbnailPath,
|
||||
isHidden: isHidden ?? this.isHidden,
|
||||
birthDate: birthDate ?? this.birthDate,
|
||||
faceAssetId: faceAssetId ?? this.faceAssetId,
|
||||
isFavorite: isFavorite ?? this.isFavorite,
|
||||
color: color ?? this.color,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -173,6 +173,14 @@ class SyncStreamService {
|
||||
data.cast(),
|
||||
debugLabel: 'partner',
|
||||
);
|
||||
// case SyncEntityType.personV1:
|
||||
// return _syncStreamRepository.updatePeopleV1(data.cast());
|
||||
// case SyncEntityType.personDeleteV1:
|
||||
// return _syncStreamRepository.deletePeopleV1(data.cast());
|
||||
// case SyncEntityType.faceV1:
|
||||
// return _syncStreamRepository.updateFacesV1(data.cast());
|
||||
// case SyncEntityType.faceDeleteV1:
|
||||
// return _syncStreamRepository.deleteFacesV1(data.cast());
|
||||
default:
|
||||
_logger.warning("Unknown sync data type: $type");
|
||||
}
|
||||
|
40
mobile/lib/infrastructure/entities/asset_face.entity.dart
Normal file
40
mobile/lib/infrastructure/entities/asset_face.entity.dart
Normal file
@ -0,0 +1,40 @@
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:immich_mobile/domain/models/face_model.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/person.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart';
|
||||
|
||||
class AssetFaceEntity extends Table with DriftDefaultsMixin {
|
||||
const AssetFaceEntity();
|
||||
|
||||
TextColumn get id => text()();
|
||||
|
||||
TextColumn get personId =>
|
||||
text().nullable().references(PersonEntity, #id, onDelete: KeyAction.setNull)();
|
||||
|
||||
TextColumn get assetId =>
|
||||
text().references(RemoteAssetEntity, #id, onDelete: KeyAction.cascade)();
|
||||
|
||||
IntColumn get imageHeight => integer()();
|
||||
|
||||
IntColumn get imageWidth => integer()();
|
||||
|
||||
IntColumn get boundingBoxX1 => integer()();
|
||||
|
||||
IntColumn get boundingBoxY1 => integer()();
|
||||
|
||||
IntColumn get boundingBoxX2 => integer()();
|
||||
|
||||
IntColumn get boundingBoxY2 => integer()();
|
||||
|
||||
IntColumn get sourceType => intEnum<SourceType>()();
|
||||
|
||||
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
|
||||
|
||||
DateTimeColumn get updatedAt => dateTime().withDefault(currentDateAndTime)();
|
||||
|
||||
DateTimeColumn get deletedAt => dateTime().nullable()();
|
||||
|
||||
@override
|
||||
Set<Column> get primaryKey => {id};
|
||||
}
|
1179
mobile/lib/infrastructure/entities/asset_face.entity.drift.dart
generated
Normal file
1179
mobile/lib/infrastructure/entities/asset_face.entity.drift.dart
generated
Normal file
File diff suppressed because it is too large
Load Diff
35
mobile/lib/infrastructure/entities/person.entity.dart
Normal file
35
mobile/lib/infrastructure/entities/person.entity.dart
Normal file
@ -0,0 +1,35 @@
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/asset_face.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart';
|
||||
|
||||
class PersonEntity extends Table with DriftDefaultsMixin {
|
||||
const PersonEntity();
|
||||
|
||||
TextColumn get id => text()();
|
||||
|
||||
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
|
||||
|
||||
DateTimeColumn get updatedAt => dateTime().withDefault(currentDateAndTime)();
|
||||
|
||||
TextColumn get ownerId =>
|
||||
text().references(UserEntity, #id, onDelete: KeyAction.cascade)();
|
||||
|
||||
TextColumn get name => text()();
|
||||
|
||||
TextColumn get thumbnailPath => text().nullable()();
|
||||
|
||||
BoolColumn get isHidden => boolean()();
|
||||
|
||||
DateTimeColumn get birthDate => dateTime().nullable()();
|
||||
|
||||
TextColumn get faceAssetId =>
|
||||
text().nullable().references(AssetFaceEntity, #id, onDelete: KeyAction.setNull)();
|
||||
|
||||
BoolColumn get isFavorite => boolean()();
|
||||
|
||||
TextColumn get color => text().nullable()();
|
||||
|
||||
@override
|
||||
Set<Column> get primaryKey => {id};
|
||||
}
|
1031
mobile/lib/infrastructure/entities/person.entity.drift.dart
generated
Normal file
1031
mobile/lib/infrastructure/entities/person.entity.drift.dart
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,7 @@ import 'dart:async';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:drift_flutter/drift_flutter.dart';
|
||||
import 'package:immich_mobile/domain/interfaces/db.interface.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/asset_face.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/exif.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/local_album.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/local_album_asset.entity.dart';
|
||||
@ -10,6 +11,7 @@ import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/memory.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/memory_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/partner.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/person.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/remote_album.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/remote_album_asset.entity.dart';
|
||||
import 'package:immich_mobile/infrastructure/entities/remote_album_user.entity.dart';
|
||||
@ -52,6 +54,8 @@ class IsarDatabaseRepository implements IDatabaseRepository {
|
||||
MemoryEntity,
|
||||
MemoryAssetEntity,
|
||||
StackEntity,
|
||||
PersonEntity,
|
||||
AssetFaceEntity,
|
||||
],
|
||||
include: {
|
||||
'package:immich_mobile/infrastructure/entities/merged_asset.drift',
|
||||
|
@ -29,9 +29,13 @@ import 'package:immich_mobile/infrastructure/entities/memory_asset.entity.drift.
|
||||
as i13;
|
||||
import 'package:immich_mobile/infrastructure/entities/stack.entity.drift.dart'
|
||||
as i14;
|
||||
import 'package:immich_mobile/infrastructure/entities/merged_asset.drift.dart'
|
||||
import 'package:immich_mobile/infrastructure/entities/asset_face.entity.drift.dart'
|
||||
as i15;
|
||||
import 'package:drift/internal/modular.dart' as i16;
|
||||
import 'package:immich_mobile/infrastructure/entities/person.entity.drift.dart'
|
||||
as i16;
|
||||
import 'package:immich_mobile/infrastructure/entities/merged_asset.drift.dart'
|
||||
as i17;
|
||||
import 'package:drift/internal/modular.dart' as i18;
|
||||
|
||||
abstract class $Drift extends i0.GeneratedDatabase {
|
||||
$Drift(i0.QueryExecutor e) : super(e);
|
||||
@ -61,8 +65,11 @@ abstract class $Drift extends i0.GeneratedDatabase {
|
||||
late final i13.$MemoryAssetEntityTable memoryAssetEntity =
|
||||
i13.$MemoryAssetEntityTable(this);
|
||||
late final i14.$StackEntityTable stackEntity = i14.$StackEntityTable(this);
|
||||
i15.MergedAssetDrift get mergedAssetDrift => i16.ReadDatabaseContainer(this)
|
||||
.accessor<i15.MergedAssetDrift>(i15.MergedAssetDrift.new);
|
||||
late final i15.$AssetFaceEntityTable assetFaceEntity =
|
||||
i15.$AssetFaceEntityTable(this);
|
||||
late final i16.$PersonEntityTable personEntity = i16.$PersonEntityTable(this);
|
||||
i17.MergedAssetDrift get mergedAssetDrift => i18.ReadDatabaseContainer(this)
|
||||
.accessor<i17.MergedAssetDrift>(i17.MergedAssetDrift.new);
|
||||
@override
|
||||
Iterable<i0.TableInfo<i0.Table, Object?>> get allTables =>
|
||||
allSchemaEntities.whereType<i0.TableInfo<i0.Table, Object?>>();
|
||||
@ -84,7 +91,9 @@ abstract class $Drift extends i0.GeneratedDatabase {
|
||||
remoteAlbumUserEntity,
|
||||
memoryEntity,
|
||||
memoryAssetEntity,
|
||||
stackEntity
|
||||
stackEntity,
|
||||
assetFaceEntity,
|
||||
personEntity
|
||||
];
|
||||
@override
|
||||
i0.StreamQueryUpdateRules get streamUpdateRules =>
|
||||
@ -216,6 +225,27 @@ abstract class $Drift extends i0.GeneratedDatabase {
|
||||
i0.TableUpdate('stack_entity', kind: i0.UpdateKind.delete),
|
||||
],
|
||||
),
|
||||
i0.WritePropagation(
|
||||
on: i0.TableUpdateQuery.onTableName('remote_asset_entity',
|
||||
limitUpdateKind: i0.UpdateKind.delete),
|
||||
result: [
|
||||
i0.TableUpdate('asset_face_entity', kind: i0.UpdateKind.delete),
|
||||
],
|
||||
),
|
||||
i0.WritePropagation(
|
||||
on: i0.TableUpdateQuery.onTableName('user_entity',
|
||||
limitUpdateKind: i0.UpdateKind.delete),
|
||||
result: [
|
||||
i0.TableUpdate('person_entity', kind: i0.UpdateKind.delete),
|
||||
],
|
||||
),
|
||||
i0.WritePropagation(
|
||||
on: i0.TableUpdateQuery.onTableName('asset_face_entity',
|
||||
limitUpdateKind: i0.UpdateKind.delete),
|
||||
result: [
|
||||
i0.TableUpdate('person_entity', kind: i0.UpdateKind.update),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
@override
|
||||
@ -255,4 +285,8 @@ class $DriftManager {
|
||||
i13.$$MemoryAssetEntityTableTableManager(_db, _db.memoryAssetEntity);
|
||||
i14.$$StackEntityTableTableManager get stackEntity =>
|
||||
i14.$$StackEntityTableTableManager(_db, _db.stackEntity);
|
||||
i15.$$AssetFaceEntityTableTableManager get assetFaceEntity =>
|
||||
i15.$$AssetFaceEntityTableTableManager(_db, _db.assetFaceEntity);
|
||||
i16.$$PersonEntityTableTableManager get personEntity =>
|
||||
i16.$$PersonEntityTableTableManager(_db, _db.personEntity);
|
||||
}
|
||||
|
@ -56,6 +56,8 @@ class SyncApiRepository {
|
||||
SyncRequestType.memoryToAssetsV1,
|
||||
SyncRequestType.stacksV1,
|
||||
SyncRequestType.partnerStacksV1,
|
||||
SyncRequestType.peopleV1,
|
||||
SyncRequestType.facesV1,
|
||||
],
|
||||
).toJson(),
|
||||
);
|
||||
@ -160,7 +162,6 @@ const _kResponseMap = <SyncEntityType, Function(Object)>{
|
||||
SyncEntityType.albumToAssetV1: SyncAlbumToAssetV1.fromJson,
|
||||
SyncEntityType.albumToAssetBackfillV1: SyncAlbumToAssetV1.fromJson,
|
||||
SyncEntityType.albumToAssetDeleteV1: SyncAlbumToAssetDeleteV1.fromJson,
|
||||
SyncEntityType.syncAckV1: _SyncAckV1.fromJson,
|
||||
SyncEntityType.memoryV1: SyncMemoryV1.fromJson,
|
||||
SyncEntityType.memoryDeleteV1: SyncMemoryDeleteV1.fromJson,
|
||||
SyncEntityType.memoryToAssetV1: SyncMemoryAssetV1.fromJson,
|
||||
@ -170,6 +171,11 @@ const _kResponseMap = <SyncEntityType, Function(Object)>{
|
||||
SyncEntityType.partnerStackV1: SyncStackV1.fromJson,
|
||||
SyncEntityType.partnerStackBackfillV1: SyncStackV1.fromJson,
|
||||
SyncEntityType.partnerStackDeleteV1: SyncStackDeleteV1.fromJson,
|
||||
SyncEntityType.personV1: SyncPersonV1.fromJson,
|
||||
SyncEntityType.personDeleteV1: SyncPersonDeleteV1.fromJson,
|
||||
SyncEntityType.faceV1: SyncFaceV1.fromJson,
|
||||
SyncEntityType.faceDeleteV1: SyncFaceDeleteV1.fromJson,
|
||||
SyncEntityType.syncAckV1: _SyncAckV1.fromJson,
|
||||
};
|
||||
|
||||
class _SyncAckV1 {
|
||||
|
@ -237,7 +237,7 @@ class SearchFilter {
|
||||
String? filename;
|
||||
String? description;
|
||||
String? language;
|
||||
Set<Person> people;
|
||||
Set<PersonDto> people;
|
||||
SearchLocationFilter location;
|
||||
SearchCameraFilter camera;
|
||||
SearchDateFilter date;
|
||||
@ -282,7 +282,7 @@ class SearchFilter {
|
||||
String? filename,
|
||||
String? description,
|
||||
String? language,
|
||||
Set<Person>? people,
|
||||
Set<PersonDto>? people,
|
||||
SearchLocationFilter? location,
|
||||
SearchCameraFilter? camera,
|
||||
SearchDateFilter? date,
|
||||
|
@ -147,7 +147,7 @@ class SearchPage extends HookConsumerWidget {
|
||||
);
|
||||
|
||||
showPeoplePicker() {
|
||||
handleOnSelect(Set<Person> value) {
|
||||
handleOnSelect(Set<PersonDto> value) {
|
||||
filter.value = filter.value.copyWith(
|
||||
people: value,
|
||||
);
|
||||
|
@ -69,6 +69,8 @@ final _features = [
|
||||
await db.memoryEntity.deleteAll();
|
||||
await db.memoryAssetEntity.deleteAll();
|
||||
await db.stackEntity.deleteAll();
|
||||
await db.personEntity.deleteAll();
|
||||
await db.assetFaceEntity.deleteAll();
|
||||
},
|
||||
),
|
||||
_Feature(
|
||||
|
@ -9,7 +9,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'people.provider.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future<List<Person>> getAllPeople(
|
||||
Future<List<PersonDto>> getAllPeople(
|
||||
Ref ref,
|
||||
) async {
|
||||
final PersonService personService = ref.read(personServiceProvider);
|
||||
|
@ -6,11 +6,12 @@ part of 'people.provider.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getAllPeopleHash() => r'226947af3b09ce62224916543958dd1d5e2ba651';
|
||||
String _$getAllPeopleHash() => r'2c5e6a207683f15ab209650615fdf9cb7f76c736';
|
||||
|
||||
/// See also [getAllPeople].
|
||||
@ProviderFor(getAllPeople)
|
||||
final getAllPeopleProvider = AutoDisposeFutureProvider<List<Person>>.internal(
|
||||
final getAllPeopleProvider =
|
||||
AutoDisposeFutureProvider<List<PersonDto>>.internal(
|
||||
getAllPeople,
|
||||
name: r'getAllPeopleProvider',
|
||||
debugGetCreateSourceHash:
|
||||
@ -21,7 +22,7 @@ final getAllPeopleProvider = AutoDisposeFutureProvider<List<Person>>.internal(
|
||||
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
typedef GetAllPeopleRef = AutoDisposeFutureProviderRef<List<Person>>;
|
||||
typedef GetAllPeopleRef = AutoDisposeFutureProviderRef<List<PersonDto>>;
|
||||
String _$personAssetsHash() => r'c1d35ee0e024bd6915e21bc724be4b458a14bc24';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
|
@ -43,6 +43,8 @@ class AuthRepository extends DatabaseRepository {
|
||||
_drift.memoryEntity.deleteAll(),
|
||||
_drift.memoryAssetEntity.deleteAll(),
|
||||
_drift.stackEntity.deleteAll(),
|
||||
_drift.personEntity.deleteAll(),
|
||||
_drift.assetFaceEntity.deleteAll(),
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
@ -13,19 +13,19 @@ class PersonApiRepository extends ApiRepository {
|
||||
|
||||
PersonApiRepository(this._api);
|
||||
|
||||
Future<List<Person>> getAll() async {
|
||||
Future<List<PersonDto>> getAll() async {
|
||||
final dto = await checkNull(_api.getAllPeople());
|
||||
return dto.people.map(_toPerson).toList();
|
||||
}
|
||||
|
||||
Future<Person> update(String id, {String? name}) async {
|
||||
Future<PersonDto> update(String id, {String? name}) async {
|
||||
final dto = await checkNull(
|
||||
_api.updatePerson(id, PersonUpdateDto(name: name)),
|
||||
);
|
||||
return _toPerson(dto);
|
||||
}
|
||||
|
||||
static Person _toPerson(PersonResponseDto dto) => Person(
|
||||
static PersonDto _toPerson(PersonResponseDto dto) => PersonDto(
|
||||
birthDate: dto.birthDate,
|
||||
id: dto.id,
|
||||
isHidden: dto.isHidden,
|
||||
|
@ -28,7 +28,7 @@ class PersonService {
|
||||
this._assetRepository,
|
||||
);
|
||||
|
||||
Future<List<Person>> getAllPeople() async {
|
||||
Future<List<PersonDto>> getAllPeople() async {
|
||||
try {
|
||||
return await _personApiRepository.getAll();
|
||||
} catch (error, stack) {
|
||||
@ -48,7 +48,7 @@ class PersonService {
|
||||
return [];
|
||||
}
|
||||
|
||||
Future<Person?> updateName(String id, String name) async {
|
||||
Future<PersonDto?> updateName(String id, String name) async {
|
||||
try {
|
||||
return await _personApiRepository.update(id, name: name);
|
||||
} catch (error, stack) {
|
||||
|
@ -14,8 +14,8 @@ import 'package:immich_mobile/widgets/common/search_field.dart';
|
||||
class PeoplePicker extends HookConsumerWidget {
|
||||
const PeoplePicker({super.key, required this.onSelect, this.filter});
|
||||
|
||||
final Function(Set<Person>) onSelect;
|
||||
final Set<Person>? filter;
|
||||
final Function(Set<PersonDto>) onSelect;
|
||||
final Set<PersonDto>? filter;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
@ -24,7 +24,7 @@ class PeoplePicker extends HookConsumerWidget {
|
||||
final searchQuery = useState('');
|
||||
final people = ref.watch(getAllPeopleProvider);
|
||||
final headers = ApiService.getRequestHeaders();
|
||||
final selectedPeople = useState<Set<Person>>(filter ?? {});
|
||||
final selectedPeople = useState<Set<PersonDto>>(filter ?? {});
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
|
@ -101,6 +101,14 @@ void main() {
|
||||
debugLabel: any(named: 'debugLabel'),
|
||||
),
|
||||
).thenAnswer(successHandler);
|
||||
// when(() => mockSyncStreamRepo.updatePeopleV1(any()))
|
||||
// .thenAnswer(successHandler);
|
||||
// when(() => mockSyncStreamRepo.deletePeopleV1(any()))
|
||||
// .thenAnswer(successHandler);
|
||||
// when(() => mockSyncStreamRepo.updateFacesV1(any()))
|
||||
// .thenAnswer(successHandler);
|
||||
// when(() => mockSyncStreamRepo.deleteFacesV1(any()))
|
||||
// .thenAnswer(successHandler);
|
||||
|
||||
sut = SyncStreamService(
|
||||
syncApiRepository: mockSyncApiRepo,
|
||||
|
Loading…
x
Reference in New Issue
Block a user