mirror of
https://github.com/immich-app/immich
synced 2026-08-15 13:03:57 +00:00
chore(mobile): more complicated Freezed pass (#30452)
* chore(mobile): example freezed implementation on some models
This commit is contained in:
parent
0ff47f4178
commit
235daff561
26 changed files with 272 additions and 1271 deletions
|
|
@ -1,13 +1,14 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
class CropAspectRatio {
|
||||
final int? numerator;
|
||||
final int? denominator;
|
||||
part 'aspect_ratios.freezed.dart';
|
||||
|
||||
final String? customLabel;
|
||||
final IconData? icon;
|
||||
@freezed
|
||||
abstract class CropAspectRatio with _$CropAspectRatio {
|
||||
const CropAspectRatio._();
|
||||
|
||||
const CropAspectRatio({this.numerator, this.denominator, this.customLabel, this.icon});
|
||||
const factory CropAspectRatio({int? numerator, int? denominator, String? customLabel, IconData? icon}) =
|
||||
_CropAspectRatio;
|
||||
|
||||
static const free = CropAspectRatio(customLabel: "Free", icon: Icons.crop_free);
|
||||
static const original = CropAspectRatio(customLabel: "Original", icon: Icons.crop_original);
|
||||
|
|
@ -22,24 +23,6 @@ class CropAspectRatio {
|
|||
CropAspectRatio get flipped {
|
||||
return CropAspectRatio(numerator: denominator, denominator: numerator, customLabel: customLabel, icon: icon);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other is CropAspectRatio &&
|
||||
other.numerator == numerator &&
|
||||
other.denominator == denominator &&
|
||||
other.customLabel == customLabel &&
|
||||
other.icon == icon;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return numerator.hashCode ^ denominator.hashCode ^ customLabel.hashCode ^ icon.hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
const aspectRatioFree = CropAspectRatio.free;
|
||||
|
|
|
|||
|
|
@ -1,51 +1,18 @@
|
|||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'log.model.freezed.dart';
|
||||
|
||||
/// Log levels according to dart logging [Level]
|
||||
enum LogLevel { all, finest, finer, fine, config, info, warning, severe, shout, off }
|
||||
|
||||
class LogMessage {
|
||||
final String message;
|
||||
final LogLevel level;
|
||||
final DateTime createdAt;
|
||||
final String? logger;
|
||||
final String? error;
|
||||
final String? stack;
|
||||
|
||||
const LogMessage({
|
||||
required this.message,
|
||||
required this.level,
|
||||
required this.createdAt,
|
||||
this.logger,
|
||||
this.error,
|
||||
this.stack,
|
||||
});
|
||||
|
||||
@override
|
||||
bool operator ==(covariant LogMessage other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other.message == message &&
|
||||
other.level == level &&
|
||||
other.createdAt == createdAt &&
|
||||
other.logger == logger &&
|
||||
other.error == error &&
|
||||
other.stack == stack;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return message.hashCode ^ level.hashCode ^ createdAt.hashCode ^ logger.hashCode ^ error.hashCode ^ stack.hashCode;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return '''LogMessage: {
|
||||
message: $message,
|
||||
level: $level,
|
||||
createdAt: $createdAt,
|
||||
logger: ${logger ?? '<NA>'},
|
||||
error: ${error ?? '<NA>'},
|
||||
stack: ${stack ?? '<NA>'},
|
||||
}''';
|
||||
}
|
||||
@freezed
|
||||
abstract class LogMessage with _$LogMessage {
|
||||
const factory LogMessage({
|
||||
required String message,
|
||||
required LogLevel level,
|
||||
required DateTime createdAt,
|
||||
String? logger,
|
||||
String? error,
|
||||
String? stack,
|
||||
}) = _LogMessage;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,9 @@
|
|||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:maplibre_gl/maplibre_gl.dart';
|
||||
|
||||
class Marker {
|
||||
final LatLng location;
|
||||
final String assetId;
|
||||
part 'map.model.freezed.dart';
|
||||
|
||||
const Marker({required this.location, required this.assetId});
|
||||
|
||||
@override
|
||||
bool operator ==(covariant Marker other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other.location == location && other.assetId == assetId;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => location.hashCode ^ assetId.hashCode;
|
||||
@freezed
|
||||
abstract class Marker with _$Marker {
|
||||
const factory Marker({required LatLng location, required String assetId}) = _Marker;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
|
||||
part 'memory.model.freezed.dart';
|
||||
|
||||
// TODO(agg23): Remove enum suffix
|
||||
enum MemoryTypeEnum {
|
||||
// do not change this order!
|
||||
onThisDay,
|
||||
}
|
||||
|
||||
class MemoryData {
|
||||
final int year;
|
||||
@Freezed(fromJson: false, toJson: false)
|
||||
abstract class MemoryData with _$MemoryData {
|
||||
const MemoryData._();
|
||||
|
||||
const MemoryData({required this.year});
|
||||
|
||||
MemoryData copyWith({int? year}) {
|
||||
return MemoryData(year: year ?? this.year);
|
||||
}
|
||||
const factory MemoryData({required int year}) = _MemoryData;
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, dynamic>{'year': year};
|
||||
|
|
@ -29,144 +29,25 @@ class MemoryData {
|
|||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory MemoryData.fromJson(String source) => MemoryData.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
String toString() => 'MemoryData(year: $year)';
|
||||
|
||||
@override
|
||||
bool operator ==(covariant MemoryData other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other.year == year;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => year.hashCode;
|
||||
}
|
||||
|
||||
// Model for a memory stored in the server
|
||||
class DriftMemory {
|
||||
final String id;
|
||||
final DateTime createdAt;
|
||||
final DateTime updatedAt;
|
||||
final DateTime? deletedAt;
|
||||
final String ownerId;
|
||||
|
||||
// enum
|
||||
final MemoryTypeEnum type;
|
||||
final MemoryData data;
|
||||
final bool isSaved;
|
||||
final DateTime memoryAt;
|
||||
final DateTime? seenAt;
|
||||
final DateTime? showAt;
|
||||
final DateTime? hideAt;
|
||||
final List<RemoteAsset> assets;
|
||||
|
||||
const DriftMemory({
|
||||
required this.id,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
this.deletedAt,
|
||||
required this.ownerId,
|
||||
required this.type,
|
||||
required this.data,
|
||||
required this.isSaved,
|
||||
required this.memoryAt,
|
||||
this.seenAt,
|
||||
this.showAt,
|
||||
this.hideAt,
|
||||
required this.assets,
|
||||
});
|
||||
|
||||
DriftMemory copyWith({
|
||||
String? id,
|
||||
DateTime? createdAt,
|
||||
DateTime? updatedAt,
|
||||
// TODO(agg23): DriftMemoryRepository currently mutates `assets`
|
||||
@Freezed(makeCollectionsUnmodifiable: false)
|
||||
abstract class DriftMemory with _$DriftMemory {
|
||||
const factory DriftMemory({
|
||||
required String id,
|
||||
required DateTime createdAt,
|
||||
required DateTime updatedAt,
|
||||
DateTime? deletedAt,
|
||||
String? ownerId,
|
||||
MemoryTypeEnum? type,
|
||||
MemoryData? data,
|
||||
bool? isSaved,
|
||||
DateTime? memoryAt,
|
||||
required String ownerId,
|
||||
required MemoryTypeEnum type,
|
||||
required MemoryData data,
|
||||
required bool isSaved,
|
||||
required DateTime memoryAt,
|
||||
DateTime? seenAt,
|
||||
DateTime? showAt,
|
||||
DateTime? hideAt,
|
||||
List<RemoteAsset>? assets,
|
||||
}) {
|
||||
return DriftMemory(
|
||||
id: id ?? this.id,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
deletedAt: deletedAt ?? this.deletedAt,
|
||||
ownerId: ownerId ?? this.ownerId,
|
||||
type: type ?? this.type,
|
||||
data: data ?? this.data,
|
||||
isSaved: isSaved ?? this.isSaved,
|
||||
memoryAt: memoryAt ?? this.memoryAt,
|
||||
seenAt: seenAt ?? this.seenAt,
|
||||
showAt: showAt ?? this.showAt,
|
||||
hideAt: hideAt ?? this.hideAt,
|
||||
assets: assets ?? this.assets,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return '''Memory {
|
||||
id: $id,
|
||||
createdAt: $createdAt,
|
||||
updatedAt: $updatedAt,
|
||||
deletedAt: ${deletedAt ?? "<NA>"},
|
||||
ownerId: $ownerId,
|
||||
type: $type,
|
||||
data: $data,
|
||||
isSaved: $isSaved,
|
||||
memoryAt: $memoryAt,
|
||||
seenAt: ${seenAt ?? "<NA>"},
|
||||
showAt: ${showAt ?? "<NA>"},
|
||||
hideAt: ${hideAt ?? "<NA>"},
|
||||
assets: $assets
|
||||
}''';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(covariant DriftMemory other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
final listEquals = const DeepCollectionEquality().equals;
|
||||
|
||||
return other.id == id &&
|
||||
other.createdAt == createdAt &&
|
||||
other.updatedAt == updatedAt &&
|
||||
other.deletedAt == deletedAt &&
|
||||
other.ownerId == ownerId &&
|
||||
other.type == type &&
|
||||
other.data == data &&
|
||||
other.isSaved == isSaved &&
|
||||
other.memoryAt == memoryAt &&
|
||||
other.seenAt == seenAt &&
|
||||
other.showAt == showAt &&
|
||||
other.hideAt == hideAt &&
|
||||
listEquals(other.assets, assets);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return id.hashCode ^
|
||||
createdAt.hashCode ^
|
||||
updatedAt.hashCode ^
|
||||
deletedAt.hashCode ^
|
||||
ownerId.hashCode ^
|
||||
type.hashCode ^
|
||||
data.hashCode ^
|
||||
isSaved.hashCode ^
|
||||
memoryAt.hashCode ^
|
||||
seenAt.hashCode ^
|
||||
showAt.hashCode ^
|
||||
hideAt.hashCode ^
|
||||
assets.hashCode;
|
||||
}
|
||||
required List<RemoteAsset> assets,
|
||||
}) = _DriftMemory;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,100 +1,19 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'person.model.freezed.dart';
|
||||
|
||||
// TODO: Remove PersonDto once Isar is removed
|
||||
class PersonDto {
|
||||
const PersonDto({
|
||||
required this.id,
|
||||
this.birthDate,
|
||||
required this.isHidden,
|
||||
required this.name,
|
||||
required this.thumbnailPath,
|
||||
this.updatedAt,
|
||||
});
|
||||
|
||||
final String id;
|
||||
final DateTime? birthDate;
|
||||
final bool isHidden;
|
||||
final String name;
|
||||
final String thumbnailPath;
|
||||
final DateTime? updatedAt;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Person(id: $id, birthDate: $birthDate, isHidden: $isHidden, name: $name, thumbnailPath: $thumbnailPath, updatedAt: $updatedAt)';
|
||||
}
|
||||
|
||||
PersonDto copyWith({
|
||||
String? id,
|
||||
@freezed
|
||||
abstract class PersonDto with _$PersonDto {
|
||||
const factory PersonDto({
|
||||
required String id,
|
||||
DateTime? birthDate,
|
||||
bool? isHidden,
|
||||
String? name,
|
||||
String? thumbnailPath,
|
||||
required bool isHidden,
|
||||
required String name,
|
||||
required String thumbnailPath,
|
||||
DateTime? updatedAt,
|
||||
}) {
|
||||
return PersonDto(
|
||||
id: id ?? this.id,
|
||||
birthDate: birthDate ?? this.birthDate,
|
||||
isHidden: isHidden ?? this.isHidden,
|
||||
name: name ?? this.name,
|
||||
thumbnailPath: thumbnailPath ?? this.thumbnailPath,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, dynamic>{
|
||||
'id': id,
|
||||
'birthDate': birthDate?.millisecondsSinceEpoch,
|
||||
'isHidden': isHidden,
|
||||
'name': name,
|
||||
'thumbnailPath': thumbnailPath,
|
||||
'updatedAt': updatedAt?.millisecondsSinceEpoch,
|
||||
};
|
||||
}
|
||||
|
||||
factory PersonDto.fromMap(Map<String, dynamic> map) {
|
||||
return PersonDto(
|
||||
id: map['id'] as String,
|
||||
birthDate: map['birthDate'] != null ? DateTime.fromMillisecondsSinceEpoch(map['birthDate'] as int) : null,
|
||||
isHidden: map['isHidden'] as bool,
|
||||
name: map['name'] as String,
|
||||
thumbnailPath: map['thumbnailPath'] as String,
|
||||
updatedAt: map['updatedAt'] != null ? DateTime.fromMillisecondsSinceEpoch(map['updatedAt'] as int) : null,
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory PersonDto.fromJson(String source) => PersonDto.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
bool operator ==(covariant PersonDto other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other.id == id &&
|
||||
other.birthDate == birthDate &&
|
||||
other.isHidden == isHidden &&
|
||||
other.name == name &&
|
||||
other.thumbnailPath == thumbnailPath &&
|
||||
other.updatedAt == updatedAt;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return id.hashCode ^
|
||||
birthDate.hashCode ^
|
||||
isHidden.hashCode ^
|
||||
name.hashCode ^
|
||||
thumbnailPath.hashCode ^
|
||||
updatedAt.hashCode;
|
||||
}
|
||||
}) = _PersonDto;
|
||||
}
|
||||
|
||||
// Model for a person stored in the server
|
||||
|
|
|
|||
|
|
@ -1,25 +1,15 @@
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
|
||||
class SearchResult {
|
||||
final List<BaseAsset> assets;
|
||||
final int? nextPage;
|
||||
part 'search_result.model.freezed.dart';
|
||||
|
||||
const SearchResult({required this.assets, this.nextPage});
|
||||
@Freezed(toStringOverride: false)
|
||||
abstract class SearchResult with _$SearchResult {
|
||||
const SearchResult._();
|
||||
|
||||
const factory SearchResult({required List<BaseAsset> assets, int? nextPage}) = _SearchResult;
|
||||
|
||||
// Explicitly don't log results, only attributes
|
||||
@override
|
||||
String toString() => 'SearchResult(assets: ${assets.length}, nextPage: $nextPage)';
|
||||
|
||||
@override
|
||||
bool operator ==(covariant SearchResult other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
final listEquals = const DeepCollectionEquality().equals;
|
||||
|
||||
return listEquals(other.assets, assets) && other.nextPage == nextPage;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => assets.hashCode ^ nextPage.hashCode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,11 @@
|
|||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
|
||||
class Tag {
|
||||
final String id;
|
||||
final String value;
|
||||
part 'tag.model.freezed.dart';
|
||||
|
||||
const Tag({required this.id, required this.value});
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Tag(id: $id, value: $value)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(covariant Tag other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other.id == id && other.value == value;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return id.hashCode ^ value.hashCode;
|
||||
}
|
||||
@freezed
|
||||
abstract class Tag with _$Tag {
|
||||
const factory Tag({required String id, required String value}) = _Tag;
|
||||
|
||||
static Tag fromDto(TagResponseDto dto) {
|
||||
return Tag(id: dto.id, value: dto.value);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
import 'dart:convert';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'user.model.freezed.dart';
|
||||
|
||||
enum AvatarColor {
|
||||
// do not change this order or reuse indices for other purposes, adding is OK
|
||||
primary("primary"),
|
||||
|
|
@ -164,78 +167,15 @@ profileChangedAt: $profileChangedAt
|
|||
quotaUsageInBytes.hashCode;
|
||||
}
|
||||
|
||||
class PartnerUserDto {
|
||||
final String id;
|
||||
final String email;
|
||||
final String name;
|
||||
final bool inTimeline;
|
||||
|
||||
final String? profileImagePath;
|
||||
|
||||
const PartnerUserDto({
|
||||
required this.id,
|
||||
required this.email,
|
||||
required this.name,
|
||||
required this.inTimeline,
|
||||
this.profileImagePath,
|
||||
});
|
||||
|
||||
PartnerUserDto copyWith({String? id, String? email, String? name, bool? inTimeline, String? profileImagePath}) {
|
||||
return PartnerUserDto(
|
||||
id: id ?? this.id,
|
||||
email: email ?? this.email,
|
||||
name: name ?? this.name,
|
||||
inTimeline: inTimeline ?? this.inTimeline,
|
||||
profileImagePath: profileImagePath ?? this.profileImagePath,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, dynamic>{
|
||||
'id': id,
|
||||
'email': email,
|
||||
'name': name,
|
||||
'inTimeline': inTimeline,
|
||||
'profileImagePath': profileImagePath,
|
||||
};
|
||||
}
|
||||
|
||||
factory PartnerUserDto.fromMap(Map<String, dynamic> map) {
|
||||
return PartnerUserDto(
|
||||
id: map['id'] as String,
|
||||
email: map['email'] as String,
|
||||
name: map['name'] as String,
|
||||
inTimeline: map['inTimeline'] as bool,
|
||||
profileImagePath: map['profileImagePath'] != null ? map['profileImagePath'] as String : null,
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory PartnerUserDto.fromJson(String source) => PartnerUserDto.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PartnerUserDto(id: $id, email: $email, name: $name, inTimeline: $inTimeline, profileImagePath: $profileImagePath)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(covariant PartnerUserDto other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other.id == id &&
|
||||
other.email == email &&
|
||||
other.name == name &&
|
||||
other.inTimeline == inTimeline &&
|
||||
other.profileImagePath == profileImagePath;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return id.hashCode ^ email.hashCode ^ name.hashCode ^ inTimeline.hashCode ^ profileImagePath.hashCode;
|
||||
}
|
||||
@freezed
|
||||
abstract class PartnerUserDto with _$PartnerUserDto {
|
||||
const factory PartnerUserDto({
|
||||
required String id,
|
||||
required String email,
|
||||
required String name,
|
||||
required bool inTimeline,
|
||||
String? profileImagePath,
|
||||
}) = _PartnerUserDto;
|
||||
}
|
||||
|
||||
class User {
|
||||
|
|
|
|||
|
|
@ -11,105 +11,32 @@ enum UserMetadataKey {
|
|||
license,
|
||||
}
|
||||
|
||||
class Onboarding {
|
||||
final bool isOnboarded;
|
||||
@freezed
|
||||
abstract class Onboarding with _$Onboarding {
|
||||
const Onboarding._();
|
||||
|
||||
const Onboarding({required this.isOnboarded});
|
||||
|
||||
Onboarding copyWith({bool? isOnboarded}) {
|
||||
return Onboarding(isOnboarded: isOnboarded ?? this.isOnboarded);
|
||||
}
|
||||
|
||||
Map<String, Object?> toMap() {
|
||||
final onboarding = <String, Object?>{};
|
||||
onboarding["isOnboarded"] = isOnboarded;
|
||||
return onboarding;
|
||||
}
|
||||
const factory Onboarding({required bool isOnboarded}) = _Onboarding;
|
||||
|
||||
factory Onboarding.fromMap(Map<String, Object?> map) {
|
||||
return Onboarding(isOnboarded: map["isOnboarded"]! as bool);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return '''Onboarding {
|
||||
isOnboarded: $isOnboarded,
|
||||
}''';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(covariant Onboarding other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
@freezed
|
||||
abstract class Preferences with _$Preferences {
|
||||
const Preferences._();
|
||||
|
||||
return isOnboarded == other.isOnboarded;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => isOnboarded.hashCode;
|
||||
}
|
||||
|
||||
class Preferences {
|
||||
final bool foldersEnabled;
|
||||
final bool memoriesEnabled;
|
||||
final bool peopleEnabled;
|
||||
final bool ratingsEnabled;
|
||||
final bool sharedLinksEnabled;
|
||||
final bool tagsEnabled;
|
||||
final AvatarColor userAvatarColor;
|
||||
final bool showSupportBadge;
|
||||
final int minimumFaces;
|
||||
|
||||
const Preferences({
|
||||
this.foldersEnabled = false,
|
||||
this.memoriesEnabled = true,
|
||||
this.peopleEnabled = true,
|
||||
this.ratingsEnabled = false,
|
||||
this.sharedLinksEnabled = true,
|
||||
this.tagsEnabled = false,
|
||||
this.userAvatarColor = AvatarColor.primary,
|
||||
this.showSupportBadge = true,
|
||||
this.minimumFaces = 3,
|
||||
});
|
||||
|
||||
Preferences copyWith({
|
||||
bool? foldersEnabled,
|
||||
bool? memoriesEnabled,
|
||||
bool? peopleEnabled,
|
||||
bool? ratingsEnabled,
|
||||
bool? sharedLinksEnabled,
|
||||
bool? tagsEnabled,
|
||||
AvatarColor? userAvatarColor,
|
||||
bool? showSupportBadge,
|
||||
int? minimumFaces,
|
||||
}) {
|
||||
return Preferences(
|
||||
foldersEnabled: foldersEnabled ?? this.foldersEnabled,
|
||||
memoriesEnabled: memoriesEnabled ?? this.memoriesEnabled,
|
||||
peopleEnabled: peopleEnabled ?? this.peopleEnabled,
|
||||
ratingsEnabled: ratingsEnabled ?? this.ratingsEnabled,
|
||||
sharedLinksEnabled: sharedLinksEnabled ?? this.sharedLinksEnabled,
|
||||
tagsEnabled: tagsEnabled ?? this.tagsEnabled,
|
||||
userAvatarColor: userAvatarColor ?? this.userAvatarColor,
|
||||
showSupportBadge: showSupportBadge ?? this.showSupportBadge,
|
||||
minimumFaces: minimumFaces ?? this.minimumFaces,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, Object?> toMap() {
|
||||
final preferences = <String, Object?>{};
|
||||
preferences["folders-Enabled"] = foldersEnabled;
|
||||
preferences["memories-Enabled"] = memoriesEnabled;
|
||||
preferences["people-Enabled"] = peopleEnabled;
|
||||
preferences["ratings-Enabled"] = ratingsEnabled;
|
||||
preferences["sharedLinks-Enabled"] = sharedLinksEnabled;
|
||||
preferences["tags-Enabled"] = tagsEnabled;
|
||||
preferences["avatar-Color"] = userAvatarColor.value;
|
||||
preferences["purchase-ShowSupportBadge"] = showSupportBadge;
|
||||
preferences["minimumFaces"] = minimumFaces;
|
||||
return preferences;
|
||||
}
|
||||
const factory Preferences({
|
||||
@Default(false) bool foldersEnabled,
|
||||
@Default(true) bool memoriesEnabled,
|
||||
@Default(true) bool peopleEnabled,
|
||||
@Default(false) bool ratingsEnabled,
|
||||
@Default(true) bool sharedLinksEnabled,
|
||||
@Default(false) bool tagsEnabled,
|
||||
@Default(AvatarColor.primary) AvatarColor userAvatarColor,
|
||||
@Default(true) bool showSupportBadge,
|
||||
@Default(3) int minimumFaces,
|
||||
}) = _Preferences;
|
||||
|
||||
factory Preferences.fromMap(Map<String, Object?> map) {
|
||||
return Preferences(
|
||||
|
|
@ -127,75 +54,14 @@ class Preferences {
|
|||
minimumFaces: (map["people"] as Map<String, Object?>?)?["minimumFaces"] as int? ?? 3,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return '''Preferences: {
|
||||
foldersEnabled: $foldersEnabled,
|
||||
memoriesEnabled: $memoriesEnabled,
|
||||
peopleEnabled: $peopleEnabled,
|
||||
ratingsEnabled: $ratingsEnabled,
|
||||
sharedLinksEnabled: $sharedLinksEnabled,
|
||||
tagsEnabled: $tagsEnabled,
|
||||
userAvatarColor: $userAvatarColor,
|
||||
showSupportBadge: $showSupportBadge,
|
||||
minimumFaces: $minimumFaces,
|
||||
}''';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(covariant Preferences other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
@freezed
|
||||
abstract class License with _$License {
|
||||
const License._();
|
||||
|
||||
return other.foldersEnabled == foldersEnabled &&
|
||||
other.memoriesEnabled == memoriesEnabled &&
|
||||
other.peopleEnabled == peopleEnabled &&
|
||||
other.ratingsEnabled == ratingsEnabled &&
|
||||
other.sharedLinksEnabled == sharedLinksEnabled &&
|
||||
other.tagsEnabled == tagsEnabled &&
|
||||
other.userAvatarColor == userAvatarColor &&
|
||||
other.showSupportBadge == showSupportBadge &&
|
||||
other.minimumFaces == minimumFaces;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return foldersEnabled.hashCode ^
|
||||
memoriesEnabled.hashCode ^
|
||||
peopleEnabled.hashCode ^
|
||||
ratingsEnabled.hashCode ^
|
||||
sharedLinksEnabled.hashCode ^
|
||||
tagsEnabled.hashCode ^
|
||||
userAvatarColor.hashCode ^
|
||||
showSupportBadge.hashCode ^
|
||||
minimumFaces.hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
class License {
|
||||
final DateTime activatedAt;
|
||||
final String activationKey;
|
||||
final String licenseKey;
|
||||
|
||||
const License({required this.activatedAt, required this.activationKey, required this.licenseKey});
|
||||
|
||||
License copyWith({DateTime? activatedAt, String? activationKey, String? licenseKey}) {
|
||||
return License(
|
||||
activatedAt: activatedAt ?? this.activatedAt,
|
||||
activationKey: activationKey ?? this.activationKey,
|
||||
licenseKey: licenseKey ?? this.licenseKey,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, Object?> toMap() {
|
||||
final license = <String, Object?>{};
|
||||
license["activatedAt"] = activatedAt;
|
||||
license["activationKey"] = activationKey;
|
||||
license["licenseKey"] = licenseKey;
|
||||
return license;
|
||||
}
|
||||
const factory License({required DateTime activatedAt, required String activationKey, required String licenseKey}) =
|
||||
_License;
|
||||
|
||||
factory License.fromMap(Map<String, Object?> map) {
|
||||
return License(
|
||||
|
|
@ -204,27 +70,6 @@ class License {
|
|||
licenseKey: map["licenseKey"]! as String,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return '''License {
|
||||
activatedAt: $activatedAt,
|
||||
activationKey: $activationKey,
|
||||
licenseKey: $licenseKey,
|
||||
}''';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(covariant License other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return activatedAt == other.activatedAt && activationKey == other.activationKey && licenseKey == other.licenseKey;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => activatedAt.hashCode ^ activationKey.hashCode ^ licenseKey.hashCode;
|
||||
}
|
||||
|
||||
// Model for a user metadata stored in the server
|
||||
|
|
|
|||
|
|
@ -1,34 +1,14 @@
|
|||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
import 'dart:convert';
|
||||
|
||||
class AuxilaryEndpoint {
|
||||
final String url;
|
||||
final AuxCheckStatus status;
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
const AuxilaryEndpoint({required this.url, required this.status});
|
||||
part 'auxilary_endpoint.model.freezed.dart';
|
||||
|
||||
AuxilaryEndpoint copyWith({String? url, AuxCheckStatus? status}) {
|
||||
return AuxilaryEndpoint(url: url ?? this.url, status: status ?? this.status);
|
||||
}
|
||||
@Freezed(fromJson: false, toJson: false)
|
||||
abstract class AuxilaryEndpoint with _$AuxilaryEndpoint {
|
||||
const AuxilaryEndpoint._();
|
||||
|
||||
@override
|
||||
String toString() => 'AuxilaryEndpoint(url: $url, status: $status)';
|
||||
|
||||
@override
|
||||
bool operator ==(covariant AuxilaryEndpoint other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other.url == url && other.status == status;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => url.hashCode ^ status.hashCode;
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, dynamic>{'url': url, 'status': status.toMap()};
|
||||
}
|
||||
const factory AuxilaryEndpoint({required String url, required AuxCheckStatus status}) = _AuxilaryEndpoint;
|
||||
|
||||
factory AuxilaryEndpoint.fromMap(Map<String, dynamic> map) {
|
||||
return AuxilaryEndpoint(
|
||||
|
|
@ -37,50 +17,23 @@ class AuxilaryEndpoint {
|
|||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory AuxilaryEndpoint.fromJson(String source) =>
|
||||
AuxilaryEndpoint.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
class AuxCheckStatus {
|
||||
final String name;
|
||||
const AuxCheckStatus({required this.name});
|
||||
const AuxCheckStatus._(this.name);
|
||||
// TODO(agg23): Should be an enum
|
||||
@freezed
|
||||
abstract class AuxCheckStatus with _$AuxCheckStatus {
|
||||
const AuxCheckStatus._();
|
||||
|
||||
static const loading = AuxCheckStatus._('loading');
|
||||
static const valid = AuxCheckStatus._('valid');
|
||||
static const error = AuxCheckStatus._('error');
|
||||
static const unknown = AuxCheckStatus._('unknown');
|
||||
const factory AuxCheckStatus({required String name}) = _AuxCheckStatus;
|
||||
|
||||
@override
|
||||
bool operator ==(covariant AuxCheckStatus other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other.name == name;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => name.hashCode;
|
||||
|
||||
AuxCheckStatus copyWith({String? name}) {
|
||||
return AuxCheckStatus(name: name ?? this.name);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, dynamic>{'name': name};
|
||||
}
|
||||
static const loading = AuxCheckStatus(name: 'loading');
|
||||
static const valid = AuxCheckStatus(name: 'valid');
|
||||
static const error = AuxCheckStatus(name: 'error');
|
||||
static const unknown = AuxCheckStatus(name: 'unknown');
|
||||
|
||||
factory AuxCheckStatus.fromMap(Map<String, dynamic> map) {
|
||||
return AuxCheckStatus(name: map['name'] as String);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory AuxCheckStatus.fromJson(String source) => AuxCheckStatus.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
String toString() => 'AuxCheckStatus(name: $name)';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,10 @@
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:local_auth/local_auth.dart';
|
||||
|
||||
class BiometricStatus {
|
||||
final List<BiometricType> availableBiometrics;
|
||||
final bool canAuthenticate;
|
||||
part 'biometric_status.model.freezed.dart';
|
||||
|
||||
const BiometricStatus({required this.availableBiometrics, required this.canAuthenticate});
|
||||
|
||||
@override
|
||||
String toString() => 'BiometricStatus(availableBiometrics: $availableBiometrics, canAuthenticate: $canAuthenticate)';
|
||||
|
||||
BiometricStatus copyWith({List<BiometricType>? availableBiometrics, bool? canAuthenticate}) {
|
||||
return BiometricStatus(
|
||||
availableBiometrics: availableBiometrics ?? this.availableBiometrics,
|
||||
canAuthenticate: canAuthenticate ?? this.canAuthenticate,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(covariant BiometricStatus other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
final listEquals = const DeepCollectionEquality().equals;
|
||||
|
||||
return listEquals(other.availableBiometrics, availableBiometrics) && other.canAuthenticate == canAuthenticate;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => availableBiometrics.hashCode ^ canAuthenticate.hashCode;
|
||||
@freezed
|
||||
abstract class BiometricStatus with _$BiometricStatus {
|
||||
const factory BiometricStatus({required List<BiometricType> availableBiometrics, required bool canAuthenticate}) =
|
||||
_BiometricStatus;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,85 +1,18 @@
|
|||
import 'dart:convert';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'cast_manager_state.freezed.dart';
|
||||
|
||||
enum CastDestinationType { googleCast }
|
||||
|
||||
enum CastState { idle, playing, paused, buffering }
|
||||
|
||||
class CastManagerState {
|
||||
final bool isCasting;
|
||||
final String receiverName;
|
||||
final CastState castState;
|
||||
final Duration currentTime;
|
||||
final Duration duration;
|
||||
|
||||
const CastManagerState({
|
||||
required this.isCasting,
|
||||
required this.receiverName,
|
||||
required this.castState,
|
||||
required this.currentTime,
|
||||
required this.duration,
|
||||
});
|
||||
|
||||
CastManagerState copyWith({
|
||||
bool? isCasting,
|
||||
String? receiverName,
|
||||
CastState? castState,
|
||||
Duration? currentTime,
|
||||
Duration? duration,
|
||||
}) {
|
||||
return CastManagerState(
|
||||
isCasting: isCasting ?? this.isCasting,
|
||||
receiverName: receiverName ?? this.receiverName,
|
||||
castState: castState ?? this.castState,
|
||||
currentTime: currentTime ?? this.currentTime,
|
||||
duration: duration ?? this.duration,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
final result = <String, dynamic>{};
|
||||
|
||||
result.addAll({'isCasting': isCasting});
|
||||
result.addAll({'receiverName': receiverName});
|
||||
result.addAll({'castState': castState});
|
||||
result.addAll({'currentTime': currentTime.inSeconds});
|
||||
result.addAll({'duration': duration.inSeconds});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
factory CastManagerState.fromMap(Map<String, dynamic> map) {
|
||||
return CastManagerState(
|
||||
isCasting: map['isCasting'] ?? false,
|
||||
receiverName: map['receiverName'] ?? '',
|
||||
castState: map['castState'] ?? CastState.idle,
|
||||
currentTime: Duration(seconds: map['currentTime']?.toInt() ?? 0),
|
||||
duration: Duration(seconds: map['duration']?.toInt() ?? 0),
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory CastManagerState.fromJson(String source) => CastManagerState.fromMap(json.decode(source));
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'CastManagerState(isCasting: $isCasting, receiverName: $receiverName, castState: $castState, currentTime: $currentTime, duration: $duration)';
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other is CastManagerState &&
|
||||
other.isCasting == isCasting &&
|
||||
other.receiverName == receiverName &&
|
||||
other.castState == castState &&
|
||||
other.currentTime == currentTime &&
|
||||
other.duration == duration;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
isCasting.hashCode ^ receiverName.hashCode ^ castState.hashCode ^ currentTime.hashCode ^ duration.hashCode;
|
||||
@freezed
|
||||
abstract class CastManagerState with _$CastManagerState {
|
||||
const factory CastManagerState({
|
||||
required bool isCasting,
|
||||
required String receiverName,
|
||||
required CastState castState,
|
||||
required Duration currentTime,
|
||||
required Duration duration,
|
||||
}) = _CastManagerState;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,88 +1,20 @@
|
|||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:background_downloader/background_downloader.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
class DownloadInfo {
|
||||
final String fileName;
|
||||
final double progress;
|
||||
// enum
|
||||
final TaskStatus status;
|
||||
part 'download_state.model.freezed.dart';
|
||||
|
||||
const DownloadInfo({required this.fileName, required this.progress, required this.status});
|
||||
|
||||
DownloadInfo copyWith({String? fileName, double? progress, TaskStatus? status}) {
|
||||
return DownloadInfo(
|
||||
fileName: fileName ?? this.fileName,
|
||||
progress: progress ?? this.progress,
|
||||
status: status ?? this.status,
|
||||
);
|
||||
@freezed
|
||||
abstract class DownloadInfo with _$DownloadInfo {
|
||||
const factory DownloadInfo({required String fileName, required double progress, required TaskStatus status}) =
|
||||
_DownloadInfo;
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, dynamic>{'fileName': fileName, 'progress': progress, 'status': status.index};
|
||||
}
|
||||
|
||||
factory DownloadInfo.fromMap(Map<String, dynamic> map) {
|
||||
return DownloadInfo(
|
||||
fileName: map['fileName'] as String,
|
||||
progress: map['progress'] as double,
|
||||
status: TaskStatus.values[map['status'] as int],
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory DownloadInfo.fromJson(String source) => DownloadInfo.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
String toString() => 'DownloadInfo(fileName: $fileName, progress: $progress, status: $status)';
|
||||
|
||||
@override
|
||||
bool operator ==(covariant DownloadInfo other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other.fileName == fileName && other.progress == progress && other.status == status;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => fileName.hashCode ^ progress.hashCode ^ status.hashCode;
|
||||
}
|
||||
|
||||
class DownloadState {
|
||||
// enum
|
||||
final TaskStatus downloadStatus;
|
||||
final Map<String, DownloadInfo> taskProgress;
|
||||
final bool showProgress;
|
||||
const DownloadState({required this.downloadStatus, required this.taskProgress, required this.showProgress});
|
||||
|
||||
DownloadState copyWith({TaskStatus? downloadStatus, Map<String, DownloadInfo>? taskProgress, bool? showProgress}) {
|
||||
return DownloadState(
|
||||
downloadStatus: downloadStatus ?? this.downloadStatus,
|
||||
taskProgress: taskProgress ?? this.taskProgress,
|
||||
showProgress: showProgress ?? this.showProgress,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'DownloadState(downloadStatus: $downloadStatus, taskProgress: $taskProgress, showProgress: $showProgress)';
|
||||
|
||||
@override
|
||||
bool operator ==(covariant DownloadState other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
final mapEquals = const DeepCollectionEquality().equals;
|
||||
|
||||
return other.downloadStatus == downloadStatus &&
|
||||
mapEquals(other.taskProgress, taskProgress) &&
|
||||
other.showProgress == showProgress;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => downloadStatus.hashCode ^ taskProgress.hashCode ^ showProgress.hashCode;
|
||||
@freezed
|
||||
abstract class DownloadState with _$DownloadState {
|
||||
const factory DownloadState({
|
||||
required TaskStatus downloadStatus,
|
||||
required Map<String, DownloadInfo> taskProgress,
|
||||
required bool showProgress,
|
||||
}) = _DownloadState;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,54 +1,20 @@
|
|||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
import 'dart:convert';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'search_curated_content.model.freezed.dart';
|
||||
|
||||
/// A wrapper for [CuratedLocationsResponseDto] objects
|
||||
/// and [CuratedObjectsResponseDto] to be displayed in
|
||||
/// a view
|
||||
class SearchCuratedContent {
|
||||
@freezed
|
||||
abstract class SearchCuratedContent with _$SearchCuratedContent {
|
||||
const factory SearchCuratedContent({
|
||||
/// The label to show associated with this curated object
|
||||
final String label;
|
||||
|
||||
/// The subtitle to show below the label
|
||||
final String? subtitle;
|
||||
required String label,
|
||||
|
||||
/// The id to lookup the asset from the server
|
||||
final String id;
|
||||
required String id,
|
||||
|
||||
const SearchCuratedContent({required this.label, required this.id, this.subtitle});
|
||||
|
||||
SearchCuratedContent copyWith({String? label, String? subtitle, String? id}) {
|
||||
return SearchCuratedContent(label: label ?? this.label, subtitle: subtitle ?? this.subtitle, id: id ?? this.id);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, dynamic>{'label': label, 'subtitle': subtitle, 'id': id};
|
||||
}
|
||||
|
||||
factory SearchCuratedContent.fromMap(Map<String, dynamic> map) {
|
||||
return SearchCuratedContent(
|
||||
label: map['label'] as String,
|
||||
subtitle: map['subtitle'] as String?,
|
||||
id: map['id'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory SearchCuratedContent.fromJson(String source) =>
|
||||
SearchCuratedContent.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
String toString() => 'CuratedContent(label: $label, subtitle: $subtitle, id: $id)';
|
||||
|
||||
@override
|
||||
bool operator ==(covariant SearchCuratedContent other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other.label == label && other.subtitle == subtitle && other.id == id;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => label.hashCode ^ id.hashCode;
|
||||
/// The subtitle to show below the label
|
||||
String? subtitle,
|
||||
}) = _SearchCuratedContent;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
import 'package:immich_mobile/domain/models/person.model.dart';
|
||||
import 'package:immich_mobile/utils/option.dart';
|
||||
|
||||
part 'search_filter.model.freezed.dart';
|
||||
|
||||
class SearchLocationFilter {
|
||||
String? country;
|
||||
String? state;
|
||||
|
|
@ -177,52 +180,10 @@ class SearchRatingFilter {
|
|||
int get hashCode => rating.hashCode;
|
||||
}
|
||||
|
||||
class SearchDisplayFilters {
|
||||
bool isNotInAlbum = false;
|
||||
bool isArchive = false;
|
||||
bool isFavorite = false;
|
||||
SearchDisplayFilters({required this.isNotInAlbum, required this.isArchive, required this.isFavorite});
|
||||
|
||||
SearchDisplayFilters copyWith({bool? isNotInAlbum, bool? isArchive, bool? isFavorite}) {
|
||||
return SearchDisplayFilters(
|
||||
isNotInAlbum: isNotInAlbum ?? this.isNotInAlbum,
|
||||
isArchive: isArchive ?? this.isArchive,
|
||||
isFavorite: isFavorite ?? this.isFavorite,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, dynamic>{'isNotInAlbum': isNotInAlbum, 'isArchive': isArchive, 'isFavorite': isFavorite};
|
||||
}
|
||||
|
||||
factory SearchDisplayFilters.fromMap(Map<String, dynamic> map) {
|
||||
return SearchDisplayFilters(
|
||||
isNotInAlbum: map['isNotInAlbum'] as bool,
|
||||
isArchive: map['isArchive'] as bool,
|
||||
isFavorite: map['isFavorite'] as bool,
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory SearchDisplayFilters.fromJson(String source) =>
|
||||
SearchDisplayFilters.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'SearchDisplayFilters(isNotInAlbum: $isNotInAlbum, isArchive: $isArchive, isFavorite: $isFavorite)';
|
||||
|
||||
@override
|
||||
bool operator ==(covariant SearchDisplayFilters other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other.isNotInAlbum == isNotInAlbum && other.isArchive == isArchive && other.isFavorite == isFavorite;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => isNotInAlbum.hashCode ^ isArchive.hashCode ^ isFavorite.hashCode;
|
||||
@freezed
|
||||
abstract class SearchDisplayFilters with _$SearchDisplayFilters {
|
||||
const factory SearchDisplayFilters({required bool isNotInAlbum, required bool isArchive, required bool isFavorite}) =
|
||||
_SearchDisplayFilters;
|
||||
}
|
||||
|
||||
class SearchFilter {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class SimilarPhotosAction extends ActionBuilder {
|
|||
location: .new(),
|
||||
camera: .new(),
|
||||
date: .new(),
|
||||
display: .new(isNotInAlbum: false, isArchive: false, isFavorite: false),
|
||||
display: const .new(isNotInAlbum: false, isArchive: false, isFavorite: false),
|
||||
rating: .new(),
|
||||
mediaType: .other,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ class DriftSearchPage extends HookConsumerWidget {
|
|||
location: SearchLocationFilter(),
|
||||
camera: SearchCameraFilter(),
|
||||
date: SearchDateFilter(),
|
||||
display: SearchDisplayFilters(isNotInAlbum: false, isArchive: false, isFavorite: false),
|
||||
display: const SearchDisplayFilters(isNotInAlbum: false, isArchive: false, isFavorite: false),
|
||||
rating: SearchRatingFilter(),
|
||||
mediaType: AssetType.other,
|
||||
language: "${context.locale.languageCode}-${context.locale.countryCode}",
|
||||
|
|
@ -455,9 +455,9 @@ class DriftSearchPage extends HookConsumerWidget {
|
|||
|
||||
void handleOnSelect(Map<DisplayOption, bool> value) {
|
||||
display = display.copyWith(
|
||||
isNotInAlbum: value[DisplayOption.notInAlbum],
|
||||
isArchive: value[DisplayOption.archive],
|
||||
isFavorite: value[DisplayOption.favorite],
|
||||
isNotInAlbum: value[DisplayOption.notInAlbum] ?? display.isNotInAlbum,
|
||||
isArchive: value[DisplayOption.archive] ?? display.isArchive,
|
||||
isFavorite: value[DisplayOption.favorite] ?? display.isFavorite,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -465,7 +465,7 @@ class DriftSearchPage extends HookConsumerWidget {
|
|||
displayOptionCurrentFilterWidget.value = null;
|
||||
search(
|
||||
filter.value.copyWith(
|
||||
display: SearchDisplayFilters(isNotInAlbum: false, isArchive: false, isFavorite: false),
|
||||
display: const SearchDisplayFilters(isNotInAlbum: false, isArchive: false, isFavorite: false),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,45 +12,17 @@ import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
|
|||
|
||||
part 'timeline.state.freezed.dart';
|
||||
|
||||
class TimelineArgs {
|
||||
final double maxWidth;
|
||||
final double maxHeight;
|
||||
final double spacing;
|
||||
final int columnCount;
|
||||
final bool showStorageIndicator;
|
||||
final bool withStack;
|
||||
final GroupAssetsBy? groupBy;
|
||||
|
||||
const TimelineArgs({
|
||||
required this.maxWidth,
|
||||
required this.maxHeight,
|
||||
this.spacing = kTimelineSpacing,
|
||||
this.columnCount = kTimelineColumnCount,
|
||||
this.showStorageIndicator = false,
|
||||
this.withStack = false,
|
||||
this.groupBy,
|
||||
});
|
||||
|
||||
@override
|
||||
bool operator ==(covariant TimelineArgs other) {
|
||||
return spacing == other.spacing &&
|
||||
maxWidth == other.maxWidth &&
|
||||
maxHeight == other.maxHeight &&
|
||||
columnCount == other.columnCount &&
|
||||
showStorageIndicator == other.showStorageIndicator &&
|
||||
withStack == other.withStack &&
|
||||
groupBy == other.groupBy;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
maxWidth.hashCode ^
|
||||
maxHeight.hashCode ^
|
||||
spacing.hashCode ^
|
||||
columnCount.hashCode ^
|
||||
showStorageIndicator.hashCode ^
|
||||
withStack.hashCode ^
|
||||
groupBy.hashCode;
|
||||
@freezed
|
||||
abstract class TimelineArgs with _$TimelineArgs {
|
||||
const factory TimelineArgs({
|
||||
required double maxWidth,
|
||||
required double maxHeight,
|
||||
@Default(kTimelineSpacing) double spacing,
|
||||
@Default(kTimelineColumnCount) int columnCount,
|
||||
@Default(false) bool showStorageIndicator,
|
||||
@Default(false) bool withStack,
|
||||
GroupAssetsBy? groupBy,
|
||||
}) = _TimelineArgs;
|
||||
}
|
||||
|
||||
@freezed
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ import 'package:collection/collection.dart';
|
|||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'timeline_drag_region.freezed.dart';
|
||||
|
||||
class TimelineDragRegion extends StatefulWidget {
|
||||
final Widget child;
|
||||
|
|
@ -206,21 +209,7 @@ class _TimelineAssetIndexProxy extends RenderProxyBox {
|
|||
_TimelineAssetIndexProxy({required this.index});
|
||||
}
|
||||
|
||||
class TimelineAssetIndex {
|
||||
final int assetIndex;
|
||||
final int segmentIndex;
|
||||
|
||||
const TimelineAssetIndex({required this.assetIndex, required this.segmentIndex});
|
||||
|
||||
@override
|
||||
bool operator ==(covariant TimelineAssetIndex other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other.assetIndex == assetIndex && other.segmentIndex == segmentIndex;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => assetIndex.hashCode ^ segmentIndex.hashCode;
|
||||
@freezed
|
||||
abstract class TimelineAssetIndex with _$TimelineAssetIndex {
|
||||
const factory TimelineAssetIndex({required int assetIndex, required int segmentIndex}) = _TimelineAssetIndex;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,87 +44,22 @@ abstract class DriftUploadStatus with _$DriftUploadStatus {
|
|||
|
||||
enum BackupError { none, syncFailed }
|
||||
|
||||
class DriftBackupState {
|
||||
final int totalCount;
|
||||
final int backupCount;
|
||||
final int remainderCount;
|
||||
final int processingCount;
|
||||
@freezed
|
||||
abstract class DriftBackupState with _$DriftBackupState {
|
||||
const DriftBackupState._();
|
||||
|
||||
final bool isSyncing;
|
||||
final BackupError error;
|
||||
|
||||
final Map<String, DriftUploadStatus> uploadItems;
|
||||
|
||||
final Map<String, double> iCloudDownloadProgress;
|
||||
|
||||
const DriftBackupState({
|
||||
required this.totalCount,
|
||||
required this.backupCount,
|
||||
required this.remainderCount,
|
||||
required this.processingCount,
|
||||
required this.isSyncing,
|
||||
this.error = BackupError.none,
|
||||
required this.uploadItems,
|
||||
this.iCloudDownloadProgress = const {},
|
||||
});
|
||||
|
||||
DriftBackupState copyWith({
|
||||
int? totalCount,
|
||||
int? backupCount,
|
||||
int? remainderCount,
|
||||
int? processingCount,
|
||||
bool? isSyncing,
|
||||
BackupError? error,
|
||||
Map<String, DriftUploadStatus>? uploadItems,
|
||||
Map<String, double>? iCloudDownloadProgress,
|
||||
}) {
|
||||
return DriftBackupState(
|
||||
totalCount: totalCount ?? this.totalCount,
|
||||
backupCount: backupCount ?? this.backupCount,
|
||||
remainderCount: remainderCount ?? this.remainderCount,
|
||||
processingCount: processingCount ?? this.processingCount,
|
||||
isSyncing: isSyncing ?? this.isSyncing,
|
||||
error: error ?? this.error,
|
||||
uploadItems: uploadItems ?? this.uploadItems,
|
||||
iCloudDownloadProgress: iCloudDownloadProgress ?? this.iCloudDownloadProgress,
|
||||
);
|
||||
}
|
||||
const factory DriftBackupState({
|
||||
required int totalCount,
|
||||
required int backupCount,
|
||||
required int remainderCount,
|
||||
required int processingCount,
|
||||
required bool isSyncing,
|
||||
@Default(BackupError.none) BackupError error,
|
||||
required Map<String, DriftUploadStatus> uploadItems,
|
||||
@Default({}) Map<String, double> iCloudDownloadProgress,
|
||||
}) = _DriftBackupState;
|
||||
|
||||
int get errorCount => uploadItems.values.where((item) => item.isFailed == true).length;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DriftBackupState(totalCount: $totalCount, backupCount: $backupCount, remainderCount: $remainderCount, processingCount: $processingCount, isSyncing: $isSyncing, error: $error, uploadItems: $uploadItems, iCloudDownloadProgress: $iCloudDownloadProgress)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(covariant DriftBackupState other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
final mapEquals = const DeepCollectionEquality().equals;
|
||||
|
||||
return other.totalCount == totalCount &&
|
||||
other.backupCount == backupCount &&
|
||||
other.remainderCount == remainderCount &&
|
||||
other.processingCount == processingCount &&
|
||||
other.isSyncing == isSyncing &&
|
||||
other.error == error &&
|
||||
mapEquals(other.iCloudDownloadProgress, iCloudDownloadProgress) &&
|
||||
mapEquals(other.uploadItems, uploadItems);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return totalCount.hashCode ^
|
||||
backupCount.hashCode ^
|
||||
remainderCount.hashCode ^
|
||||
processingCount.hashCode ^
|
||||
isSyncing.hashCode ^
|
||||
error.hashCode ^
|
||||
uploadItems.hashCode ^
|
||||
iCloudDownloadProgress.hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
final driftBackupProvider = StateNotifierProvider<DriftBackupNotifier, DriftBackupState>((ref) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/album/album.model.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
|
|
@ -17,30 +17,17 @@ import 'package:immich_mobile/providers/user.provider.dart';
|
|||
import 'package:immich_mobile/services/foreground_upload.service.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
class RemoteAlbumState {
|
||||
final List<RemoteAlbum> albums;
|
||||
part 'remote_album.provider.freezed.dart';
|
||||
|
||||
const RemoteAlbumState({required this.albums});
|
||||
@Freezed(toStringOverride: false)
|
||||
abstract class RemoteAlbumState with _$RemoteAlbumState {
|
||||
const RemoteAlbumState._();
|
||||
|
||||
RemoteAlbumState copyWith({List<RemoteAlbum>? albums}) {
|
||||
return RemoteAlbumState(albums: albums ?? this.albums);
|
||||
}
|
||||
const factory RemoteAlbumState({required List<RemoteAlbum> albums}) = _RemoteAlbumState;
|
||||
|
||||
// Explicitly don't log albums
|
||||
@override
|
||||
String toString() => 'RemoteAlbumState(albums: ${albums.length})';
|
||||
|
||||
@override
|
||||
bool operator ==(covariant RemoteAlbumState other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
final listEquals = const DeepCollectionEquality().equals;
|
||||
|
||||
return listEquals(other.albums, albums);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => albums.hashCode;
|
||||
}
|
||||
|
||||
class RemoteAlbumNotifier extends Notifier<RemoteAlbumState> {
|
||||
|
|
|
|||
|
|
@ -1,34 +1,19 @@
|
|||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/services/search.service.dart';
|
||||
import 'package:openapi/api.dart';
|
||||
|
||||
class SearchSuggestionArgs {
|
||||
SearchSuggestionType type;
|
||||
final String? locationCountry;
|
||||
final String? locationState;
|
||||
final String? make;
|
||||
final String? model;
|
||||
part 'search_filter.provider.freezed.dart';
|
||||
|
||||
SearchSuggestionArgs({required this.type, this.locationCountry, this.locationState, this.make, this.model});
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other is SearchSuggestionArgs &&
|
||||
other.type == type &&
|
||||
other.locationCountry == locationCountry &&
|
||||
other.locationState == locationState &&
|
||||
other.make == make &&
|
||||
other.model == model;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return type.hashCode ^ locationCountry.hashCode ^ locationState.hashCode ^ make.hashCode ^ model.hashCode;
|
||||
}
|
||||
@freezed
|
||||
abstract class SearchSuggestionArgs with _$SearchSuggestionArgs {
|
||||
const factory SearchSuggestionArgs({
|
||||
required SearchSuggestionType type,
|
||||
String? locationCountry,
|
||||
String? locationState,
|
||||
String? make,
|
||||
String? model,
|
||||
}) = _SearchSuggestionArgs;
|
||||
}
|
||||
|
||||
final getSearchSuggestionsProvider = FutureProvider.autoDispose.family<List<String>, SearchSuggestionArgs>((
|
||||
|
|
|
|||
|
|
@ -1,22 +1,27 @@
|
|||
// ignore_for_file: use-ref-and-state-synchronously
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||
import 'package:immich_mobile/domain/services/timeline.service.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
|
||||
|
||||
part 'multiselect.provider.freezed.dart';
|
||||
|
||||
final multiSelectProvider = NotifierProvider<MultiSelectNotifier, MultiSelectState>(
|
||||
MultiSelectNotifier.new,
|
||||
dependencies: [timelineServiceProvider],
|
||||
);
|
||||
|
||||
class MultiSelectState {
|
||||
final Set<BaseAsset> selectedAssets;
|
||||
final Set<BaseAsset> lockedSelectionAssets;
|
||||
final bool forceEnable;
|
||||
@freezed
|
||||
abstract class MultiSelectState with _$MultiSelectState {
|
||||
const MultiSelectState._();
|
||||
|
||||
const MultiSelectState({required this.selectedAssets, required this.lockedSelectionAssets, this.forceEnable = false});
|
||||
const factory MultiSelectState({
|
||||
required Set<BaseAsset> selectedAssets,
|
||||
required Set<BaseAsset> lockedSelectionAssets,
|
||||
@Default(false) bool forceEnable,
|
||||
}) = _MultiSelectState;
|
||||
|
||||
bool get isEnabled => selectedAssets.isNotEmpty;
|
||||
|
||||
|
|
@ -29,37 +34,6 @@ class MultiSelectState {
|
|||
bool get onlyLocal => selectedAssets.any((asset) => asset.storage == AssetState.local);
|
||||
|
||||
bool get onlyRemote => selectedAssets.any((asset) => asset.storage == AssetState.remote);
|
||||
|
||||
MultiSelectState copyWith({
|
||||
Set<BaseAsset>? selectedAssets,
|
||||
Set<BaseAsset>? lockedSelectionAssets,
|
||||
bool? forceEnable,
|
||||
}) {
|
||||
return MultiSelectState(
|
||||
selectedAssets: selectedAssets ?? this.selectedAssets,
|
||||
lockedSelectionAssets: lockedSelectionAssets ?? this.lockedSelectionAssets,
|
||||
forceEnable: forceEnable ?? this.forceEnable,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'MultiSelectState(selectedAssets: $selectedAssets, lockedSelectionAssets: $lockedSelectionAssets, forceEnable: $forceEnable)';
|
||||
|
||||
@override
|
||||
bool operator ==(covariant MultiSelectState other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
final setEquals = const DeepCollectionEquality().equals;
|
||||
|
||||
return setEquals(other.selectedAssets, selectedAssets) &&
|
||||
setEquals(other.lockedSelectionAssets, lockedSelectionAssets) &&
|
||||
other.forceEnable == forceEnable;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => selectedAssets.hashCode ^ lockedSelectionAssets.hashCode ^ forceEnable.hashCode;
|
||||
}
|
||||
|
||||
class MultiSelectNotifier extends Notifier<MultiSelectState> {
|
||||
|
|
|
|||
|
|
@ -1,60 +1,18 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:immich_mobile/domain/services/user.service.dart';
|
||||
import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
|
||||
import 'package:immich_mobile/utils/debug_print.dart';
|
||||
|
||||
part 'upload_profile_image.provider.freezed.dart';
|
||||
|
||||
enum UploadProfileStatus { idle, loading, success, failure }
|
||||
|
||||
class UploadProfileImageState {
|
||||
// enum
|
||||
final UploadProfileStatus status;
|
||||
final String profileImagePath;
|
||||
const UploadProfileImageState({required this.status, required this.profileImagePath});
|
||||
|
||||
UploadProfileImageState copyWith({UploadProfileStatus? status, String? profileImagePath}) {
|
||||
return UploadProfileImageState(
|
||||
status: status ?? this.status,
|
||||
profileImagePath: profileImagePath ?? this.profileImagePath,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
final result = <String, dynamic>{};
|
||||
|
||||
result.addAll({'status': status.index});
|
||||
result.addAll({'profileImagePath': profileImagePath});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
factory UploadProfileImageState.fromMap(Map<String, dynamic> map) {
|
||||
return UploadProfileImageState(
|
||||
status: UploadProfileStatus.values[map['status'] ?? 0],
|
||||
profileImagePath: map['profileImagePath'] ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory UploadProfileImageState.fromJson(String source) => UploadProfileImageState.fromMap(json.decode(source));
|
||||
|
||||
@override
|
||||
String toString() => 'UploadProfileImageState(status: $status, profileImagePath: $profileImagePath)';
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other is UploadProfileImageState && other.status == status && other.profileImagePath == profileImagePath;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => status.hashCode ^ profileImagePath.hashCode;
|
||||
@freezed
|
||||
abstract class UploadProfileImageState with _$UploadProfileImageState {
|
||||
const factory UploadProfileImageState({required UploadProfileStatus status, required String profileImagePath}) =
|
||||
_UploadProfileImageState;
|
||||
}
|
||||
|
||||
class UploadProfileImageNotifier extends StateNotifier<UploadProfileImageState> {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import 'dart:io';
|
|||
|
||||
import 'package:background_downloader/background_downloader.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/constants/constants.dart';
|
||||
import 'package:immich_mobile/domain/models/asset/asset_metadata.model.dart';
|
||||
|
|
@ -25,6 +26,8 @@ import 'package:logging/logging.dart';
|
|||
import 'package:openapi/api.dart' as api;
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
part 'background_upload.service.freezed.dart';
|
||||
|
||||
final backgroundUploadServiceProvider = Provider((ref) {
|
||||
final service = BackgroundUploadService(
|
||||
ref.watch(uploadRepositoryProvider),
|
||||
|
|
@ -39,20 +42,15 @@ final backgroundUploadServiceProvider = Provider((ref) {
|
|||
});
|
||||
|
||||
/// Metadata for upload tasks to track live photo handling
|
||||
class UploadTaskMetadata {
|
||||
final String localAssetId;
|
||||
final bool isLivePhotos;
|
||||
final String livePhotoVideoId;
|
||||
@Freezed(fromJson: false, toJson: false)
|
||||
abstract class UploadTaskMetadata with _$UploadTaskMetadata {
|
||||
const UploadTaskMetadata._();
|
||||
|
||||
const UploadTaskMetadata({required this.localAssetId, required this.isLivePhotos, required this.livePhotoVideoId});
|
||||
|
||||
UploadTaskMetadata copyWith({String? localAssetId, bool? isLivePhotos, String? livePhotoVideoId}) {
|
||||
return UploadTaskMetadata(
|
||||
localAssetId: localAssetId ?? this.localAssetId,
|
||||
isLivePhotos: isLivePhotos ?? this.isLivePhotos,
|
||||
livePhotoVideoId: livePhotoVideoId ?? this.livePhotoVideoId,
|
||||
);
|
||||
}
|
||||
const factory UploadTaskMetadata({
|
||||
required String localAssetId,
|
||||
required bool isLivePhotos,
|
||||
required String livePhotoVideoId,
|
||||
}) = _UploadTaskMetadata;
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, dynamic>{
|
||||
|
|
@ -70,28 +68,10 @@ class UploadTaskMetadata {
|
|||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory UploadTaskMetadata.fromJson(String source) =>
|
||||
UploadTaskMetadata.fromMap(json.decode(source) as Map<String, dynamic>);
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'UploadTaskMetadata(localAssetId: $localAssetId, isLivePhotos: $isLivePhotos, livePhotoVideoId: $livePhotoVideoId)';
|
||||
|
||||
@override
|
||||
bool operator ==(covariant UploadTaskMetadata other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return other.localAssetId == localAssetId &&
|
||||
other.isLivePhotos == isLivePhotos &&
|
||||
other.livePhotoVideoId == livePhotoVideoId;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => localAssetId.hashCode ^ isLivePhotos.hashCode ^ livePhotoVideoId.hashCode;
|
||||
String toJson() => json.encode(toMap());
|
||||
}
|
||||
|
||||
/// Service for handling background uploads using iOS URLSession (background_downloader)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ class CameraPicker extends HookConsumerWidget {
|
|||
final selectedMake = useState<String?>(filter?.make);
|
||||
final selectedModel = useState<String?>(filter?.model);
|
||||
|
||||
final make = ref.watch(getSearchSuggestionsProvider(SearchSuggestionArgs(type: SearchSuggestionType.cameraMake)));
|
||||
final make = ref.watch(
|
||||
getSearchSuggestionsProvider(const SearchSuggestionArgs(type: SearchSuggestionType.cameraMake)),
|
||||
);
|
||||
|
||||
final models = ref.watch(
|
||||
getSearchSuggestionsProvider(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue