forked from Cutlery/immich
feat(web,server): user memory settings (#3628)
* feat(web,server): user preference for time-based memories * chore: open api * dev: mobile * fix: update * mobile work --------- Co-authored-by: Alex <alex.tran1502@gmail.com> Co-authored-by: Alex Tran <Alex.Tran@conductix.com>
This commit is contained in:
parent
343087e2b4
commit
a6eb227330
18
cli/src/api/open-api/api.ts
generated
18
cli/src/api/open-api/api.ts
generated
@ -954,6 +954,12 @@ export interface CreateUserDto {
|
|||||||
* @memberof CreateUserDto
|
* @memberof CreateUserDto
|
||||||
*/
|
*/
|
||||||
'lastName': string;
|
'lastName': string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof CreateUserDto
|
||||||
|
*/
|
||||||
|
'memoriesEnabled'?: boolean;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
@ -2995,6 +3001,12 @@ export interface UpdateUserDto {
|
|||||||
* @memberof UpdateUserDto
|
* @memberof UpdateUserDto
|
||||||
*/
|
*/
|
||||||
'lastName'?: string;
|
'lastName'?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof UpdateUserDto
|
||||||
|
*/
|
||||||
|
'memoriesEnabled'?: boolean;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
@ -3124,6 +3136,12 @@ export interface UserResponseDto {
|
|||||||
* @memberof UserResponseDto
|
* @memberof UserResponseDto
|
||||||
*/
|
*/
|
||||||
'lastName': string;
|
'lastName': string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof UserResponseDto
|
||||||
|
*/
|
||||||
|
'memoriesEnabled': boolean;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
|
@ -342,7 +342,10 @@ class HomePage extends HookConsumerWidget {
|
|||||||
listener: selectionListener,
|
listener: selectionListener,
|
||||||
selectionActive: selectionEnabledHook.value,
|
selectionActive: selectionEnabledHook.value,
|
||||||
onRefresh: refreshAssets,
|
onRefresh: refreshAssets,
|
||||||
topWidget: const MemoryLane(),
|
topWidget:
|
||||||
|
(currentUser != null && currentUser.memoryEnabled)
|
||||||
|
? const MemoryLane()
|
||||||
|
: const SizedBox(),
|
||||||
),
|
),
|
||||||
error: (error, _) => Center(child: Text(error.toString())),
|
error: (error, _) => Center(child: Text(error.toString())),
|
||||||
loading: buildLoadingIndicator,
|
loading: buildLoadingIndicator,
|
||||||
|
@ -97,12 +97,11 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
|
|||||||
Future<void> logout() async {
|
Future<void> logout() async {
|
||||||
var log = Logger('AuthenticationNotifier');
|
var log = Logger('AuthenticationNotifier');
|
||||||
try {
|
try {
|
||||||
|
|
||||||
String? userEmail = Store.tryGet(StoreKey.currentUser)?.email;
|
String? userEmail = Store.tryGet(StoreKey.currentUser)?.email;
|
||||||
|
|
||||||
_apiService.authenticationApi
|
_apiService.authenticationApi
|
||||||
.logout()
|
.logout()
|
||||||
.then((_) => log.info("Logout was successfull for $userEmail"))
|
.then((_) => log.info("Logout was successful for $userEmail"))
|
||||||
.onError(
|
.onError(
|
||||||
(error, stackTrace) =>
|
(error, stackTrace) =>
|
||||||
log.severe("Error logging out $userEmail", error, stackTrace),
|
log.severe("Error logging out $userEmail", error, stackTrace),
|
||||||
@ -186,8 +185,7 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
|
|||||||
user = User.fromDto(userResponseDto);
|
user = User.fromDto(userResponseDto);
|
||||||
|
|
||||||
retResult = true;
|
retResult = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
_log.severe("Unable to get user information from the server.");
|
_log.severe("Unable to get user information from the server.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/modules/album/providers/album.provider.dart';
|
import 'package:immich_mobile/modules/album/providers/album.provider.dart';
|
||||||
import 'package:immich_mobile/modules/memories/providers/memory.provider.dart';
|
import 'package:immich_mobile/modules/memories/providers/memory.provider.dart';
|
||||||
@ -6,6 +7,9 @@ import 'package:immich_mobile/modules/search/providers/people.provider.dart';
|
|||||||
|
|
||||||
import 'package:immich_mobile/modules/search/providers/search_page_state.provider.dart';
|
import 'package:immich_mobile/modules/search/providers/search_page_state.provider.dart';
|
||||||
import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart';
|
import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart';
|
||||||
|
import 'package:immich_mobile/shared/models/store.dart';
|
||||||
|
import 'package:immich_mobile/shared/models/user.dart';
|
||||||
|
import 'package:immich_mobile/shared/providers/api.provider.dart';
|
||||||
import 'package:immich_mobile/shared/providers/server_info.provider.dart';
|
import 'package:immich_mobile/shared/providers/server_info.provider.dart';
|
||||||
|
|
||||||
class TabNavigationObserver extends AutoRouterObserver {
|
class TabNavigationObserver extends AutoRouterObserver {
|
||||||
@ -46,6 +50,20 @@ class TabNavigationObserver extends AutoRouterObserver {
|
|||||||
|
|
||||||
if (route.name == 'HomeRoute') {
|
if (route.name == 'HomeRoute') {
|
||||||
ref.invalidate(memoryFutureProvider);
|
ref.invalidate(memoryFutureProvider);
|
||||||
|
|
||||||
|
// Update user info
|
||||||
|
try {
|
||||||
|
final userResponseDto =
|
||||||
|
await ref.read(apiServiceProvider).userApi.getMyUserInfo();
|
||||||
|
|
||||||
|
if (userResponseDto == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Store.put(StoreKey.currentUser, User.fromDto(userResponseDto));
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint("Error refreshing user info $e");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ref.watch(serverInfoProvider.notifier).getServerVersion();
|
ref.watch(serverInfoProvider.notifier).getServerVersion();
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ class User {
|
|||||||
this.isPartnerSharedBy = false,
|
this.isPartnerSharedBy = false,
|
||||||
this.isPartnerSharedWith = false,
|
this.isPartnerSharedWith = false,
|
||||||
this.profileImagePath = '',
|
this.profileImagePath = '',
|
||||||
|
this.memoryEnabled = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
Id get isarId => fastHash(id);
|
Id get isarId => fastHash(id);
|
||||||
@ -30,7 +31,8 @@ class User {
|
|||||||
isPartnerSharedBy = false,
|
isPartnerSharedBy = false,
|
||||||
isPartnerSharedWith = false,
|
isPartnerSharedWith = false,
|
||||||
profileImagePath = dto.profileImagePath,
|
profileImagePath = dto.profileImagePath,
|
||||||
isAdmin = dto.isAdmin;
|
isAdmin = dto.isAdmin,
|
||||||
|
memoryEnabled = dto.memoriesEnabled;
|
||||||
|
|
||||||
@Index(unique: true, replace: false, type: IndexType.hash)
|
@Index(unique: true, replace: false, type: IndexType.hash)
|
||||||
String id;
|
String id;
|
||||||
@ -42,6 +44,7 @@ class User {
|
|||||||
bool isPartnerSharedWith;
|
bool isPartnerSharedWith;
|
||||||
bool isAdmin;
|
bool isAdmin;
|
||||||
String profileImagePath;
|
String profileImagePath;
|
||||||
|
bool memoryEnabled;
|
||||||
@Backlink(to: 'owner')
|
@Backlink(to: 'owner')
|
||||||
final IsarLinks<Album> albums = IsarLinks<Album>();
|
final IsarLinks<Album> albums = IsarLinks<Album>();
|
||||||
@Backlink(to: 'sharedUsers')
|
@Backlink(to: 'sharedUsers')
|
||||||
@ -58,7 +61,8 @@ class User {
|
|||||||
isPartnerSharedBy == other.isPartnerSharedBy &&
|
isPartnerSharedBy == other.isPartnerSharedBy &&
|
||||||
isPartnerSharedWith == other.isPartnerSharedWith &&
|
isPartnerSharedWith == other.isPartnerSharedWith &&
|
||||||
profileImagePath == other.profileImagePath &&
|
profileImagePath == other.profileImagePath &&
|
||||||
isAdmin == other.isAdmin;
|
isAdmin == other.isAdmin &&
|
||||||
|
memoryEnabled == other.memoryEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -72,5 +76,6 @@ class User {
|
|||||||
isPartnerSharedBy.hashCode ^
|
isPartnerSharedBy.hashCode ^
|
||||||
isPartnerSharedWith.hashCode ^
|
isPartnerSharedWith.hashCode ^
|
||||||
profileImagePath.hashCode ^
|
profileImagePath.hashCode ^
|
||||||
isAdmin.hashCode;
|
isAdmin.hashCode ^
|
||||||
|
memoryEnabled.hashCode;
|
||||||
}
|
}
|
||||||
|
@ -52,8 +52,18 @@ const UserSchema = CollectionSchema(
|
|||||||
name: r'lastName',
|
name: r'lastName',
|
||||||
type: IsarType.string,
|
type: IsarType.string,
|
||||||
),
|
),
|
||||||
r'updatedAt': PropertySchema(
|
r'memoryEnabled': PropertySchema(
|
||||||
id: 7,
|
id: 7,
|
||||||
|
name: r'memoryEnabled',
|
||||||
|
type: IsarType.bool,
|
||||||
|
),
|
||||||
|
r'profileImagePath': PropertySchema(
|
||||||
|
id: 8,
|
||||||
|
name: r'profileImagePath',
|
||||||
|
type: IsarType.string,
|
||||||
|
),
|
||||||
|
r'updatedAt': PropertySchema(
|
||||||
|
id: 9,
|
||||||
name: r'updatedAt',
|
name: r'updatedAt',
|
||||||
type: IsarType.dateTime,
|
type: IsarType.dateTime,
|
||||||
)
|
)
|
||||||
@ -111,6 +121,7 @@ int _userEstimateSize(
|
|||||||
bytesCount += 3 + object.firstName.length * 3;
|
bytesCount += 3 + object.firstName.length * 3;
|
||||||
bytesCount += 3 + object.id.length * 3;
|
bytesCount += 3 + object.id.length * 3;
|
||||||
bytesCount += 3 + object.lastName.length * 3;
|
bytesCount += 3 + object.lastName.length * 3;
|
||||||
|
bytesCount += 3 + object.profileImagePath.length * 3;
|
||||||
return bytesCount;
|
return bytesCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +138,9 @@ void _userSerialize(
|
|||||||
writer.writeBool(offsets[4], object.isPartnerSharedBy);
|
writer.writeBool(offsets[4], object.isPartnerSharedBy);
|
||||||
writer.writeBool(offsets[5], object.isPartnerSharedWith);
|
writer.writeBool(offsets[5], object.isPartnerSharedWith);
|
||||||
writer.writeString(offsets[6], object.lastName);
|
writer.writeString(offsets[6], object.lastName);
|
||||||
writer.writeDateTime(offsets[7], object.updatedAt);
|
writer.writeBool(offsets[7], object.memoryEnabled);
|
||||||
|
writer.writeString(offsets[8], object.profileImagePath);
|
||||||
|
writer.writeDateTime(offsets[9], object.updatedAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
User _userDeserialize(
|
User _userDeserialize(
|
||||||
@ -144,7 +157,9 @@ User _userDeserialize(
|
|||||||
isPartnerSharedBy: reader.readBoolOrNull(offsets[4]) ?? false,
|
isPartnerSharedBy: reader.readBoolOrNull(offsets[4]) ?? false,
|
||||||
isPartnerSharedWith: reader.readBoolOrNull(offsets[5]) ?? false,
|
isPartnerSharedWith: reader.readBoolOrNull(offsets[5]) ?? false,
|
||||||
lastName: reader.readString(offsets[6]),
|
lastName: reader.readString(offsets[6]),
|
||||||
updatedAt: reader.readDateTime(offsets[7]),
|
memoryEnabled: reader.readBoolOrNull(offsets[7]) ?? true,
|
||||||
|
profileImagePath: reader.readStringOrNull(offsets[8]) ?? '',
|
||||||
|
updatedAt: reader.readDateTime(offsets[9]),
|
||||||
);
|
);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
@ -171,6 +186,10 @@ P _userDeserializeProp<P>(
|
|||||||
case 6:
|
case 6:
|
||||||
return (reader.readString(offset)) as P;
|
return (reader.readString(offset)) as P;
|
||||||
case 7:
|
case 7:
|
||||||
|
return (reader.readBoolOrNull(offset) ?? true) as P;
|
||||||
|
case 8:
|
||||||
|
return (reader.readStringOrNull(offset) ?? '') as P;
|
||||||
|
case 9:
|
||||||
return (reader.readDateTime(offset)) as P;
|
return (reader.readDateTime(offset)) as P;
|
||||||
default:
|
default:
|
||||||
throw IsarError('Unknown property with id $propertyId');
|
throw IsarError('Unknown property with id $propertyId');
|
||||||
@ -960,6 +979,146 @@ extension UserQueryFilter on QueryBuilder<User, User, QFilterCondition> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterFilterCondition> memoryEnabledEqualTo(
|
||||||
|
bool value) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'memoryEnabled',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterFilterCondition> profileImagePathEqualTo(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'profileImagePath',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterFilterCondition> profileImagePathGreaterThan(
|
||||||
|
String value, {
|
||||||
|
bool include = false,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
include: include,
|
||||||
|
property: r'profileImagePath',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterFilterCondition> profileImagePathLessThan(
|
||||||
|
String value, {
|
||||||
|
bool include = false,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.lessThan(
|
||||||
|
include: include,
|
||||||
|
property: r'profileImagePath',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterFilterCondition> profileImagePathBetween(
|
||||||
|
String lower,
|
||||||
|
String upper, {
|
||||||
|
bool includeLower = true,
|
||||||
|
bool includeUpper = true,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.between(
|
||||||
|
property: r'profileImagePath',
|
||||||
|
lower: lower,
|
||||||
|
includeLower: includeLower,
|
||||||
|
upper: upper,
|
||||||
|
includeUpper: includeUpper,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterFilterCondition> profileImagePathStartsWith(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.startsWith(
|
||||||
|
property: r'profileImagePath',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterFilterCondition> profileImagePathEndsWith(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.endsWith(
|
||||||
|
property: r'profileImagePath',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterFilterCondition> profileImagePathContains(
|
||||||
|
String value,
|
||||||
|
{bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.contains(
|
||||||
|
property: r'profileImagePath',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterFilterCondition> profileImagePathMatches(
|
||||||
|
String pattern,
|
||||||
|
{bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.matches(
|
||||||
|
property: r'profileImagePath',
|
||||||
|
wildcard: pattern,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterFilterCondition> profileImagePathIsEmpty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'profileImagePath',
|
||||||
|
value: '',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterFilterCondition> profileImagePathIsNotEmpty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
property: r'profileImagePath',
|
||||||
|
value: '',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<User, User, QAfterFilterCondition> updatedAtEqualTo(
|
QueryBuilder<User, User, QAfterFilterCondition> updatedAtEqualTo(
|
||||||
DateTime value) {
|
DateTime value) {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
@ -1214,6 +1373,30 @@ extension UserQuerySortBy on QueryBuilder<User, User, QSortBy> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterSortBy> sortByMemoryEnabled() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'memoryEnabled', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterSortBy> sortByMemoryEnabledDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'memoryEnabled', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterSortBy> sortByProfileImagePath() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'profileImagePath', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterSortBy> sortByProfileImagePathDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'profileImagePath', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<User, User, QAfterSortBy> sortByUpdatedAt() {
|
QueryBuilder<User, User, QAfterSortBy> sortByUpdatedAt() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addSortBy(r'updatedAt', Sort.asc);
|
return query.addSortBy(r'updatedAt', Sort.asc);
|
||||||
@ -1324,6 +1507,30 @@ extension UserQuerySortThenBy on QueryBuilder<User, User, QSortThenBy> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterSortBy> thenByMemoryEnabled() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'memoryEnabled', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterSortBy> thenByMemoryEnabledDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'memoryEnabled', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterSortBy> thenByProfileImagePath() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'profileImagePath', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QAfterSortBy> thenByProfileImagePathDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'profileImagePath', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<User, User, QAfterSortBy> thenByUpdatedAt() {
|
QueryBuilder<User, User, QAfterSortBy> thenByUpdatedAt() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addSortBy(r'updatedAt', Sort.asc);
|
return query.addSortBy(r'updatedAt', Sort.asc);
|
||||||
@ -1384,6 +1591,20 @@ extension UserQueryWhereDistinct on QueryBuilder<User, User, QDistinct> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QDistinct> distinctByMemoryEnabled() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addDistinctBy(r'memoryEnabled');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, User, QDistinct> distinctByProfileImagePath(
|
||||||
|
{bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addDistinctBy(r'profileImagePath',
|
||||||
|
caseSensitive: caseSensitive);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<User, User, QDistinct> distinctByUpdatedAt() {
|
QueryBuilder<User, User, QDistinct> distinctByUpdatedAt() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addDistinctBy(r'updatedAt');
|
return query.addDistinctBy(r'updatedAt');
|
||||||
@ -1440,6 +1661,18 @@ extension UserQueryProperty on QueryBuilder<User, User, QQueryProperty> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, bool, QQueryOperations> memoryEnabledProperty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addPropertyName(r'memoryEnabled');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<User, String, QQueryOperations> profileImagePathProperty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addPropertyName(r'profileImagePath');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<User, DateTime, QQueryOperations> updatedAtProperty() {
|
QueryBuilder<User, DateTime, QQueryOperations> updatedAtProperty() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addPropertyName(r'updatedAt');
|
return query.addPropertyName(r'updatedAt');
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
build:
|
build:
|
||||||
flutter packages pub run build_runner build --delete-conflicting-outputs
|
dart run build_runner build --delete-conflicting-outputs
|
||||||
|
|
||||||
watch:
|
watch:
|
||||||
flutter packages pub run build_runner watch --delete-conflicting-outputs
|
dart run build_runner watch --delete-conflicting-outputs
|
||||||
|
|
||||||
create_app_icon:
|
create_app_icon:
|
||||||
flutter pub run flutter_launcher_icons:main
|
flutter pub run flutter_launcher_icons:main
|
||||||
|
1
mobile/openapi/doc/CreateUserDto.md
generated
1
mobile/openapi/doc/CreateUserDto.md
generated
@ -12,6 +12,7 @@ Name | Type | Description | Notes
|
|||||||
**externalPath** | **String** | | [optional]
|
**externalPath** | **String** | | [optional]
|
||||||
**firstName** | **String** | |
|
**firstName** | **String** | |
|
||||||
**lastName** | **String** | |
|
**lastName** | **String** | |
|
||||||
|
**memoriesEnabled** | **bool** | | [optional]
|
||||||
**password** | **String** | |
|
**password** | **String** | |
|
||||||
**storageLabel** | **String** | | [optional]
|
**storageLabel** | **String** | | [optional]
|
||||||
|
|
||||||
|
1
mobile/openapi/doc/UpdateUserDto.md
generated
1
mobile/openapi/doc/UpdateUserDto.md
generated
@ -14,6 +14,7 @@ Name | Type | Description | Notes
|
|||||||
**id** | **String** | |
|
**id** | **String** | |
|
||||||
**isAdmin** | **bool** | | [optional]
|
**isAdmin** | **bool** | | [optional]
|
||||||
**lastName** | **String** | | [optional]
|
**lastName** | **String** | | [optional]
|
||||||
|
**memoriesEnabled** | **bool** | | [optional]
|
||||||
**password** | **String** | | [optional]
|
**password** | **String** | | [optional]
|
||||||
**shouldChangePassword** | **bool** | | [optional]
|
**shouldChangePassword** | **bool** | | [optional]
|
||||||
**storageLabel** | **String** | | [optional]
|
**storageLabel** | **String** | | [optional]
|
||||||
|
1
mobile/openapi/doc/UserResponseDto.md
generated
1
mobile/openapi/doc/UserResponseDto.md
generated
@ -16,6 +16,7 @@ Name | Type | Description | Notes
|
|||||||
**id** | **String** | |
|
**id** | **String** | |
|
||||||
**isAdmin** | **bool** | |
|
**isAdmin** | **bool** | |
|
||||||
**lastName** | **String** | |
|
**lastName** | **String** | |
|
||||||
|
**memoriesEnabled** | **bool** | |
|
||||||
**oauthId** | **String** | |
|
**oauthId** | **String** | |
|
||||||
**profileImagePath** | **String** | |
|
**profileImagePath** | **String** | |
|
||||||
**shouldChangePassword** | **bool** | |
|
**shouldChangePassword** | **bool** | |
|
||||||
|
19
mobile/openapi/lib/model/create_user_dto.dart
generated
19
mobile/openapi/lib/model/create_user_dto.dart
generated
@ -17,6 +17,7 @@ class CreateUserDto {
|
|||||||
this.externalPath,
|
this.externalPath,
|
||||||
required this.firstName,
|
required this.firstName,
|
||||||
required this.lastName,
|
required this.lastName,
|
||||||
|
this.memoriesEnabled,
|
||||||
required this.password,
|
required this.password,
|
||||||
this.storageLabel,
|
this.storageLabel,
|
||||||
});
|
});
|
||||||
@ -29,6 +30,14 @@ class CreateUserDto {
|
|||||||
|
|
||||||
String lastName;
|
String lastName;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Please note: This property should have been non-nullable! Since the specification file
|
||||||
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
/// source code must fall back to having a nullable type.
|
||||||
|
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||||
|
///
|
||||||
|
bool? memoriesEnabled;
|
||||||
|
|
||||||
String password;
|
String password;
|
||||||
|
|
||||||
String? storageLabel;
|
String? storageLabel;
|
||||||
@ -39,6 +48,7 @@ class CreateUserDto {
|
|||||||
other.externalPath == externalPath &&
|
other.externalPath == externalPath &&
|
||||||
other.firstName == firstName &&
|
other.firstName == firstName &&
|
||||||
other.lastName == lastName &&
|
other.lastName == lastName &&
|
||||||
|
other.memoriesEnabled == memoriesEnabled &&
|
||||||
other.password == password &&
|
other.password == password &&
|
||||||
other.storageLabel == storageLabel;
|
other.storageLabel == storageLabel;
|
||||||
|
|
||||||
@ -49,11 +59,12 @@ class CreateUserDto {
|
|||||||
(externalPath == null ? 0 : externalPath!.hashCode) +
|
(externalPath == null ? 0 : externalPath!.hashCode) +
|
||||||
(firstName.hashCode) +
|
(firstName.hashCode) +
|
||||||
(lastName.hashCode) +
|
(lastName.hashCode) +
|
||||||
|
(memoriesEnabled == null ? 0 : memoriesEnabled!.hashCode) +
|
||||||
(password.hashCode) +
|
(password.hashCode) +
|
||||||
(storageLabel == null ? 0 : storageLabel!.hashCode);
|
(storageLabel == null ? 0 : storageLabel!.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'CreateUserDto[email=$email, externalPath=$externalPath, firstName=$firstName, lastName=$lastName, password=$password, storageLabel=$storageLabel]';
|
String toString() => 'CreateUserDto[email=$email, externalPath=$externalPath, firstName=$firstName, lastName=$lastName, memoriesEnabled=$memoriesEnabled, password=$password, storageLabel=$storageLabel]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
@ -65,6 +76,11 @@ class CreateUserDto {
|
|||||||
}
|
}
|
||||||
json[r'firstName'] = this.firstName;
|
json[r'firstName'] = this.firstName;
|
||||||
json[r'lastName'] = this.lastName;
|
json[r'lastName'] = this.lastName;
|
||||||
|
if (this.memoriesEnabled != null) {
|
||||||
|
json[r'memoriesEnabled'] = this.memoriesEnabled;
|
||||||
|
} else {
|
||||||
|
// json[r'memoriesEnabled'] = null;
|
||||||
|
}
|
||||||
json[r'password'] = this.password;
|
json[r'password'] = this.password;
|
||||||
if (this.storageLabel != null) {
|
if (this.storageLabel != null) {
|
||||||
json[r'storageLabel'] = this.storageLabel;
|
json[r'storageLabel'] = this.storageLabel;
|
||||||
@ -86,6 +102,7 @@ class CreateUserDto {
|
|||||||
externalPath: mapValueOfType<String>(json, r'externalPath'),
|
externalPath: mapValueOfType<String>(json, r'externalPath'),
|
||||||
firstName: mapValueOfType<String>(json, r'firstName')!,
|
firstName: mapValueOfType<String>(json, r'firstName')!,
|
||||||
lastName: mapValueOfType<String>(json, r'lastName')!,
|
lastName: mapValueOfType<String>(json, r'lastName')!,
|
||||||
|
memoriesEnabled: mapValueOfType<bool>(json, r'memoriesEnabled'),
|
||||||
password: mapValueOfType<String>(json, r'password')!,
|
password: mapValueOfType<String>(json, r'password')!,
|
||||||
storageLabel: mapValueOfType<String>(json, r'storageLabel'),
|
storageLabel: mapValueOfType<String>(json, r'storageLabel'),
|
||||||
);
|
);
|
||||||
|
19
mobile/openapi/lib/model/update_user_dto.dart
generated
19
mobile/openapi/lib/model/update_user_dto.dart
generated
@ -19,6 +19,7 @@ class UpdateUserDto {
|
|||||||
required this.id,
|
required this.id,
|
||||||
this.isAdmin,
|
this.isAdmin,
|
||||||
this.lastName,
|
this.lastName,
|
||||||
|
this.memoriesEnabled,
|
||||||
this.password,
|
this.password,
|
||||||
this.shouldChangePassword,
|
this.shouldChangePassword,
|
||||||
this.storageLabel,
|
this.storageLabel,
|
||||||
@ -66,6 +67,14 @@ class UpdateUserDto {
|
|||||||
///
|
///
|
||||||
String? lastName;
|
String? lastName;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Please note: This property should have been non-nullable! Since the specification file
|
||||||
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
/// source code must fall back to having a nullable type.
|
||||||
|
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||||
|
///
|
||||||
|
bool? memoriesEnabled;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Please note: This property should have been non-nullable! Since the specification file
|
/// Please note: This property should have been non-nullable! Since the specification file
|
||||||
/// does not include a default value (using the "default:" property), however, the generated
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
@ -98,6 +107,7 @@ class UpdateUserDto {
|
|||||||
other.id == id &&
|
other.id == id &&
|
||||||
other.isAdmin == isAdmin &&
|
other.isAdmin == isAdmin &&
|
||||||
other.lastName == lastName &&
|
other.lastName == lastName &&
|
||||||
|
other.memoriesEnabled == memoriesEnabled &&
|
||||||
other.password == password &&
|
other.password == password &&
|
||||||
other.shouldChangePassword == shouldChangePassword &&
|
other.shouldChangePassword == shouldChangePassword &&
|
||||||
other.storageLabel == storageLabel;
|
other.storageLabel == storageLabel;
|
||||||
@ -111,12 +121,13 @@ class UpdateUserDto {
|
|||||||
(id.hashCode) +
|
(id.hashCode) +
|
||||||
(isAdmin == null ? 0 : isAdmin!.hashCode) +
|
(isAdmin == null ? 0 : isAdmin!.hashCode) +
|
||||||
(lastName == null ? 0 : lastName!.hashCode) +
|
(lastName == null ? 0 : lastName!.hashCode) +
|
||||||
|
(memoriesEnabled == null ? 0 : memoriesEnabled!.hashCode) +
|
||||||
(password == null ? 0 : password!.hashCode) +
|
(password == null ? 0 : password!.hashCode) +
|
||||||
(shouldChangePassword == null ? 0 : shouldChangePassword!.hashCode) +
|
(shouldChangePassword == null ? 0 : shouldChangePassword!.hashCode) +
|
||||||
(storageLabel == null ? 0 : storageLabel!.hashCode);
|
(storageLabel == null ? 0 : storageLabel!.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'UpdateUserDto[email=$email, externalPath=$externalPath, firstName=$firstName, id=$id, isAdmin=$isAdmin, lastName=$lastName, password=$password, shouldChangePassword=$shouldChangePassword, storageLabel=$storageLabel]';
|
String toString() => 'UpdateUserDto[email=$email, externalPath=$externalPath, firstName=$firstName, id=$id, isAdmin=$isAdmin, lastName=$lastName, memoriesEnabled=$memoriesEnabled, password=$password, shouldChangePassword=$shouldChangePassword, storageLabel=$storageLabel]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
@ -146,6 +157,11 @@ class UpdateUserDto {
|
|||||||
} else {
|
} else {
|
||||||
// json[r'lastName'] = null;
|
// json[r'lastName'] = null;
|
||||||
}
|
}
|
||||||
|
if (this.memoriesEnabled != null) {
|
||||||
|
json[r'memoriesEnabled'] = this.memoriesEnabled;
|
||||||
|
} else {
|
||||||
|
// json[r'memoriesEnabled'] = null;
|
||||||
|
}
|
||||||
if (this.password != null) {
|
if (this.password != null) {
|
||||||
json[r'password'] = this.password;
|
json[r'password'] = this.password;
|
||||||
} else {
|
} else {
|
||||||
@ -178,6 +194,7 @@ class UpdateUserDto {
|
|||||||
id: mapValueOfType<String>(json, r'id')!,
|
id: mapValueOfType<String>(json, r'id')!,
|
||||||
isAdmin: mapValueOfType<bool>(json, r'isAdmin'),
|
isAdmin: mapValueOfType<bool>(json, r'isAdmin'),
|
||||||
lastName: mapValueOfType<String>(json, r'lastName'),
|
lastName: mapValueOfType<String>(json, r'lastName'),
|
||||||
|
memoriesEnabled: mapValueOfType<bool>(json, r'memoriesEnabled'),
|
||||||
password: mapValueOfType<String>(json, r'password'),
|
password: mapValueOfType<String>(json, r'password'),
|
||||||
shouldChangePassword: mapValueOfType<bool>(json, r'shouldChangePassword'),
|
shouldChangePassword: mapValueOfType<bool>(json, r'shouldChangePassword'),
|
||||||
storageLabel: mapValueOfType<String>(json, r'storageLabel'),
|
storageLabel: mapValueOfType<String>(json, r'storageLabel'),
|
||||||
|
10
mobile/openapi/lib/model/user_response_dto.dart
generated
10
mobile/openapi/lib/model/user_response_dto.dart
generated
@ -21,6 +21,7 @@ class UserResponseDto {
|
|||||||
required this.id,
|
required this.id,
|
||||||
required this.isAdmin,
|
required this.isAdmin,
|
||||||
required this.lastName,
|
required this.lastName,
|
||||||
|
required this.memoriesEnabled,
|
||||||
required this.oauthId,
|
required this.oauthId,
|
||||||
required this.profileImagePath,
|
required this.profileImagePath,
|
||||||
required this.shouldChangePassword,
|
required this.shouldChangePassword,
|
||||||
@ -44,6 +45,8 @@ class UserResponseDto {
|
|||||||
|
|
||||||
String lastName;
|
String lastName;
|
||||||
|
|
||||||
|
bool memoriesEnabled;
|
||||||
|
|
||||||
String oauthId;
|
String oauthId;
|
||||||
|
|
||||||
String profileImagePath;
|
String profileImagePath;
|
||||||
@ -64,6 +67,7 @@ class UserResponseDto {
|
|||||||
other.id == id &&
|
other.id == id &&
|
||||||
other.isAdmin == isAdmin &&
|
other.isAdmin == isAdmin &&
|
||||||
other.lastName == lastName &&
|
other.lastName == lastName &&
|
||||||
|
other.memoriesEnabled == memoriesEnabled &&
|
||||||
other.oauthId == oauthId &&
|
other.oauthId == oauthId &&
|
||||||
other.profileImagePath == profileImagePath &&
|
other.profileImagePath == profileImagePath &&
|
||||||
other.shouldChangePassword == shouldChangePassword &&
|
other.shouldChangePassword == shouldChangePassword &&
|
||||||
@ -81,6 +85,7 @@ class UserResponseDto {
|
|||||||
(id.hashCode) +
|
(id.hashCode) +
|
||||||
(isAdmin.hashCode) +
|
(isAdmin.hashCode) +
|
||||||
(lastName.hashCode) +
|
(lastName.hashCode) +
|
||||||
|
(memoriesEnabled.hashCode) +
|
||||||
(oauthId.hashCode) +
|
(oauthId.hashCode) +
|
||||||
(profileImagePath.hashCode) +
|
(profileImagePath.hashCode) +
|
||||||
(shouldChangePassword.hashCode) +
|
(shouldChangePassword.hashCode) +
|
||||||
@ -88,7 +93,7 @@ class UserResponseDto {
|
|||||||
(updatedAt.hashCode);
|
(updatedAt.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'UserResponseDto[createdAt=$createdAt, deletedAt=$deletedAt, email=$email, externalPath=$externalPath, firstName=$firstName, id=$id, isAdmin=$isAdmin, lastName=$lastName, oauthId=$oauthId, profileImagePath=$profileImagePath, shouldChangePassword=$shouldChangePassword, storageLabel=$storageLabel, updatedAt=$updatedAt]';
|
String toString() => 'UserResponseDto[createdAt=$createdAt, deletedAt=$deletedAt, email=$email, externalPath=$externalPath, firstName=$firstName, id=$id, isAdmin=$isAdmin, lastName=$lastName, memoriesEnabled=$memoriesEnabled, oauthId=$oauthId, profileImagePath=$profileImagePath, shouldChangePassword=$shouldChangePassword, storageLabel=$storageLabel, updatedAt=$updatedAt]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
@ -108,6 +113,7 @@ class UserResponseDto {
|
|||||||
json[r'id'] = this.id;
|
json[r'id'] = this.id;
|
||||||
json[r'isAdmin'] = this.isAdmin;
|
json[r'isAdmin'] = this.isAdmin;
|
||||||
json[r'lastName'] = this.lastName;
|
json[r'lastName'] = this.lastName;
|
||||||
|
json[r'memoriesEnabled'] = this.memoriesEnabled;
|
||||||
json[r'oauthId'] = this.oauthId;
|
json[r'oauthId'] = this.oauthId;
|
||||||
json[r'profileImagePath'] = this.profileImagePath;
|
json[r'profileImagePath'] = this.profileImagePath;
|
||||||
json[r'shouldChangePassword'] = this.shouldChangePassword;
|
json[r'shouldChangePassword'] = this.shouldChangePassword;
|
||||||
@ -136,6 +142,7 @@ class UserResponseDto {
|
|||||||
id: mapValueOfType<String>(json, r'id')!,
|
id: mapValueOfType<String>(json, r'id')!,
|
||||||
isAdmin: mapValueOfType<bool>(json, r'isAdmin')!,
|
isAdmin: mapValueOfType<bool>(json, r'isAdmin')!,
|
||||||
lastName: mapValueOfType<String>(json, r'lastName')!,
|
lastName: mapValueOfType<String>(json, r'lastName')!,
|
||||||
|
memoriesEnabled: mapValueOfType<bool>(json, r'memoriesEnabled')!,
|
||||||
oauthId: mapValueOfType<String>(json, r'oauthId')!,
|
oauthId: mapValueOfType<String>(json, r'oauthId')!,
|
||||||
profileImagePath: mapValueOfType<String>(json, r'profileImagePath')!,
|
profileImagePath: mapValueOfType<String>(json, r'profileImagePath')!,
|
||||||
shouldChangePassword: mapValueOfType<bool>(json, r'shouldChangePassword')!,
|
shouldChangePassword: mapValueOfType<bool>(json, r'shouldChangePassword')!,
|
||||||
@ -196,6 +203,7 @@ class UserResponseDto {
|
|||||||
'id',
|
'id',
|
||||||
'isAdmin',
|
'isAdmin',
|
||||||
'lastName',
|
'lastName',
|
||||||
|
'memoriesEnabled',
|
||||||
'oauthId',
|
'oauthId',
|
||||||
'profileImagePath',
|
'profileImagePath',
|
||||||
'shouldChangePassword',
|
'shouldChangePassword',
|
||||||
|
5
mobile/openapi/test/create_user_dto_test.dart
generated
5
mobile/openapi/test/create_user_dto_test.dart
generated
@ -36,6 +36,11 @@ void main() {
|
|||||||
// TODO
|
// TODO
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// bool memoriesEnabled
|
||||||
|
test('to test the property `memoriesEnabled`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
// String password
|
// String password
|
||||||
test('to test the property `password`', () async {
|
test('to test the property `password`', () async {
|
||||||
// TODO
|
// TODO
|
||||||
|
5
mobile/openapi/test/update_user_dto_test.dart
generated
5
mobile/openapi/test/update_user_dto_test.dart
generated
@ -46,6 +46,11 @@ void main() {
|
|||||||
// TODO
|
// TODO
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// bool memoriesEnabled
|
||||||
|
test('to test the property `memoriesEnabled`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
// String password
|
// String password
|
||||||
test('to test the property `password`', () async {
|
test('to test the property `password`', () async {
|
||||||
// TODO
|
// TODO
|
||||||
|
5
mobile/openapi/test/user_response_dto_test.dart
generated
5
mobile/openapi/test/user_response_dto_test.dart
generated
@ -56,6 +56,11 @@ void main() {
|
|||||||
// TODO
|
// TODO
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// bool memoriesEnabled
|
||||||
|
test('to test the property `memoriesEnabled`', () async {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
|
||||||
// String oauthId
|
// String oauthId
|
||||||
test('to test the property `oauthId`', () async {
|
test('to test the property `oauthId`', () async {
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -5396,6 +5396,9 @@
|
|||||||
"lastName": {
|
"lastName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"memoriesEnabled": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"password": {
|
"password": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -7004,6 +7007,9 @@
|
|||||||
"lastName": {
|
"lastName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"memoriesEnabled": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"password": {
|
"password": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -7092,6 +7098,9 @@
|
|||||||
"lastName": {
|
"lastName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"memoriesEnabled": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"oauthId": {
|
"oauthId": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -7123,7 +7132,8 @@
|
|||||||
"createdAt",
|
"createdAt",
|
||||||
"deletedAt",
|
"deletedAt",
|
||||||
"updatedAt",
|
"updatedAt",
|
||||||
"oauthId"
|
"oauthId",
|
||||||
|
"memoriesEnabled"
|
||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
@ -176,6 +176,7 @@ describe(AlbumService.name, () => {
|
|||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
updatedAt: new Date('2021-01-01'),
|
updatedAt: new Date('2021-01-01'),
|
||||||
externalPath: null,
|
externalPath: null,
|
||||||
|
memoriesEnabled: true,
|
||||||
},
|
},
|
||||||
ownerId: 'admin_id',
|
ownerId: 'admin_id',
|
||||||
shared: false,
|
shared: false,
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { BadRequestException } from '@nestjs/common';
|
import { BadRequestException } from '@nestjs/common';
|
||||||
import { authStub, newPartnerRepositoryMock, partnerStub } from '@test';
|
import { authStub, newPartnerRepositoryMock, partnerStub } from '@test';
|
||||||
|
import { UserResponseDto } from '../index';
|
||||||
import { IPartnerRepository, PartnerDirection } from './partner.repository';
|
import { IPartnerRepository, PartnerDirection } from './partner.repository';
|
||||||
import { PartnerService } from './partner.service';
|
import { PartnerService } from './partner.service';
|
||||||
|
|
||||||
const responseDto = {
|
const responseDto = {
|
||||||
admin: {
|
admin: <UserResponseDto>{
|
||||||
email: 'admin@test.com',
|
email: 'admin@test.com',
|
||||||
firstName: 'admin_first_name',
|
firstName: 'admin_first_name',
|
||||||
id: 'admin_id',
|
id: 'admin_id',
|
||||||
@ -18,8 +19,9 @@ const responseDto = {
|
|||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
updatedAt: new Date('2021-01-01'),
|
updatedAt: new Date('2021-01-01'),
|
||||||
externalPath: null,
|
externalPath: null,
|
||||||
|
memoriesEnabled: true,
|
||||||
},
|
},
|
||||||
user1: {
|
user1: <UserResponseDto>{
|
||||||
email: 'immich@test.com',
|
email: 'immich@test.com',
|
||||||
firstName: 'immich_first_name',
|
firstName: 'immich_first_name',
|
||||||
id: 'user-id',
|
id: 'user-id',
|
||||||
@ -33,6 +35,7 @@ const responseDto = {
|
|||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
updatedAt: new Date('2021-01-01'),
|
updatedAt: new Date('2021-01-01'),
|
||||||
externalPath: null,
|
externalPath: null,
|
||||||
|
memoriesEnabled: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Transform } from 'class-transformer';
|
import { Transform } from 'class-transformer';
|
||||||
import { IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
import { IsBoolean, IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
||||||
import { toEmail, toSanitized } from '../../domain.util';
|
import { toEmail, toSanitized } from '../../domain.util';
|
||||||
|
|
||||||
export class CreateUserDto {
|
export class CreateUserDto {
|
||||||
@ -27,6 +27,10 @@ export class CreateUserDto {
|
|||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsString()
|
@IsString()
|
||||||
externalPath?: string | null;
|
externalPath?: string | null;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
|
memoriesEnabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CreateAdminDto {
|
export class CreateAdminDto {
|
||||||
|
@ -45,4 +45,8 @@ export class UpdateUserDto {
|
|||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
shouldChangePassword?: boolean;
|
shouldChangePassword?: boolean;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
|
memoriesEnabled?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ export class UserResponseDto {
|
|||||||
deletedAt!: Date | null;
|
deletedAt!: Date | null;
|
||||||
updatedAt!: Date;
|
updatedAt!: Date;
|
||||||
oauthId!: string;
|
oauthId!: string;
|
||||||
|
memoriesEnabled!: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mapUser(entity: UserEntity): UserResponseDto {
|
export function mapUser(entity: UserEntity): UserResponseDto {
|
||||||
@ -31,5 +32,6 @@ export function mapUser(entity: UserEntity): UserResponseDto {
|
|||||||
deletedAt: entity.deletedAt,
|
deletedAt: entity.deletedAt,
|
||||||
updatedAt: entity.updatedAt,
|
updatedAt: entity.updatedAt,
|
||||||
oauthId: entity.oauthId,
|
oauthId: entity.oauthId,
|
||||||
|
memoriesEnabled: entity.memoriesEnabled,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,7 @@ export class UserCore {
|
|||||||
dto.externalPath = null;
|
dto.externalPath = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(dto.memoriesEnabled);
|
||||||
return this.userRepository.update(id, dto);
|
return this.userRepository.update(id, dto);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.error(e, 'Failed to update user info');
|
Logger.error(e, 'Failed to update user info');
|
||||||
|
@ -16,6 +16,7 @@ import { ICryptoRepository } from '../crypto';
|
|||||||
import { IJobRepository, JobName } from '../job';
|
import { IJobRepository, JobName } from '../job';
|
||||||
import { IStorageRepository } from '../storage';
|
import { IStorageRepository } from '../storage';
|
||||||
import { UpdateUserDto } from './dto/update-user.dto';
|
import { UpdateUserDto } from './dto/update-user.dto';
|
||||||
|
import { UserResponseDto } from './response-dto';
|
||||||
import { IUserRepository } from './user.repository';
|
import { IUserRepository } from './user.repository';
|
||||||
import { UserService } from './user.service';
|
import { UserService } from './user.service';
|
||||||
|
|
||||||
@ -54,6 +55,7 @@ const adminUser: UserEntity = Object.freeze({
|
|||||||
assets: [],
|
assets: [],
|
||||||
storageLabel: 'admin',
|
storageLabel: 'admin',
|
||||||
externalPath: null,
|
externalPath: null,
|
||||||
|
memoriesEnabled: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const immichUser: UserEntity = Object.freeze({
|
const immichUser: UserEntity = Object.freeze({
|
||||||
@ -73,9 +75,10 @@ const immichUser: UserEntity = Object.freeze({
|
|||||||
assets: [],
|
assets: [],
|
||||||
storageLabel: null,
|
storageLabel: null,
|
||||||
externalPath: null,
|
externalPath: null,
|
||||||
|
memoriesEnabled: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const updatedImmichUser: UserEntity = Object.freeze({
|
const updatedImmichUser = Object.freeze<UserEntity>({
|
||||||
id: immichUserAuth.id,
|
id: immichUserAuth.id,
|
||||||
email: 'immich@test.com',
|
email: 'immich@test.com',
|
||||||
password: 'immich_password',
|
password: 'immich_password',
|
||||||
@ -92,9 +95,10 @@ const updatedImmichUser: UserEntity = Object.freeze({
|
|||||||
assets: [],
|
assets: [],
|
||||||
storageLabel: null,
|
storageLabel: null,
|
||||||
externalPath: null,
|
externalPath: null,
|
||||||
|
memoriesEnabled: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const adminUserResponse = Object.freeze({
|
const adminUserResponse = Object.freeze<UserResponseDto>({
|
||||||
id: adminUserAuth.id,
|
id: adminUserAuth.id,
|
||||||
email: 'admin@test.com',
|
email: 'admin@test.com',
|
||||||
firstName: 'admin_first_name',
|
firstName: 'admin_first_name',
|
||||||
@ -108,6 +112,7 @@ const adminUserResponse = Object.freeze({
|
|||||||
updatedAt: new Date('2021-01-01'),
|
updatedAt: new Date('2021-01-01'),
|
||||||
storageLabel: 'admin',
|
storageLabel: 'admin',
|
||||||
externalPath: null,
|
externalPath: null,
|
||||||
|
memoriesEnabled: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
describe(UserService.name, () => {
|
describe(UserService.name, () => {
|
||||||
@ -158,6 +163,7 @@ describe(UserService.name, () => {
|
|||||||
updatedAt: new Date('2021-01-01'),
|
updatedAt: new Date('2021-01-01'),
|
||||||
storageLabel: 'admin',
|
storageLabel: 'admin',
|
||||||
externalPath: null,
|
externalPath: null,
|
||||||
|
memoriesEnabled: true,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
@ -54,6 +54,9 @@ export class UserEntity {
|
|||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: Date;
|
||||||
|
|
||||||
|
@Column({ default: true })
|
||||||
|
memoriesEnabled!: boolean;
|
||||||
|
|
||||||
@OneToMany(() => TagEntity, (tag) => tag.user)
|
@OneToMany(() => TagEntity, (tag) => tag.user)
|
||||||
tags!: TagEntity[];
|
tags!: TagEntity[];
|
||||||
|
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class UserMemoryPreference1691600216749 implements MigrationInterface {
|
||||||
|
name = 'UserMemoryPreference1691600216749';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "users" ADD "memoriesEnabled" boolean NOT NULL DEFAULT true`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "memoriesEnabled"`);
|
||||||
|
}
|
||||||
|
}
|
@ -143,6 +143,24 @@ describe(`${UserController.name}`, () => {
|
|||||||
});
|
});
|
||||||
expect(status).toBe(201);
|
expect(status).toBe(201);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should create a user without memories enabled', async () => {
|
||||||
|
const { status, body } = await request(server)
|
||||||
|
.post(`/user`)
|
||||||
|
.send({
|
||||||
|
email: 'no-memories@immich.app',
|
||||||
|
password: 'Password123',
|
||||||
|
firstName: 'No Memories',
|
||||||
|
lastName: 'User',
|
||||||
|
memoriesEnabled: false,
|
||||||
|
})
|
||||||
|
.set('Authorization', `Bearer ${accessToken}`);
|
||||||
|
expect(body).toMatchObject({
|
||||||
|
email: 'no-memories@immich.app',
|
||||||
|
memoriesEnabled: false,
|
||||||
|
});
|
||||||
|
expect(status).toBe(201);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('PUT /user', () => {
|
describe('PUT /user', () => {
|
||||||
@ -206,6 +224,21 @@ describe(`${UserController.name}`, () => {
|
|||||||
});
|
});
|
||||||
expect(before.updatedAt).not.toEqual(after.updatedAt);
|
expect(before.updatedAt).not.toEqual(after.updatedAt);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should update memories enabled', async () => {
|
||||||
|
const before = await api.userApi.get(server, accessToken, loginResponse.userId);
|
||||||
|
const after = await api.userApi.update(server, accessToken, {
|
||||||
|
id: before.id,
|
||||||
|
memoriesEnabled: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(after).toMatchObject({
|
||||||
|
...before,
|
||||||
|
updatedAt: expect.anything(),
|
||||||
|
memoriesEnabled: false,
|
||||||
|
});
|
||||||
|
expect(before.updatedAt).not.toEqual(after.updatedAt);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /user/count', () => {
|
describe('GET /user/count', () => {
|
||||||
|
4
server/test/fixtures/user.stub.ts
vendored
4
server/test/fixtures/user.stub.ts
vendored
@ -17,6 +17,7 @@ export const userStub = {
|
|||||||
updatedAt: new Date('2021-01-01'),
|
updatedAt: new Date('2021-01-01'),
|
||||||
tags: [],
|
tags: [],
|
||||||
assets: [],
|
assets: [],
|
||||||
|
memoriesEnabled: true,
|
||||||
}),
|
}),
|
||||||
user1: Object.freeze<UserEntity>({
|
user1: Object.freeze<UserEntity>({
|
||||||
...authStub.user1,
|
...authStub.user1,
|
||||||
@ -33,6 +34,7 @@ export const userStub = {
|
|||||||
updatedAt: new Date('2021-01-01'),
|
updatedAt: new Date('2021-01-01'),
|
||||||
tags: [],
|
tags: [],
|
||||||
assets: [],
|
assets: [],
|
||||||
|
memoriesEnabled: true,
|
||||||
}),
|
}),
|
||||||
user2: Object.freeze<UserEntity>({
|
user2: Object.freeze<UserEntity>({
|
||||||
...authStub.user2,
|
...authStub.user2,
|
||||||
@ -49,6 +51,7 @@ export const userStub = {
|
|||||||
updatedAt: new Date('2021-01-01'),
|
updatedAt: new Date('2021-01-01'),
|
||||||
tags: [],
|
tags: [],
|
||||||
assets: [],
|
assets: [],
|
||||||
|
memoriesEnabled: true,
|
||||||
}),
|
}),
|
||||||
storageLabel: Object.freeze<UserEntity>({
|
storageLabel: Object.freeze<UserEntity>({
|
||||||
...authStub.user1,
|
...authStub.user1,
|
||||||
@ -65,5 +68,6 @@ export const userStub = {
|
|||||||
updatedAt: new Date('2021-01-01'),
|
updatedAt: new Date('2021-01-01'),
|
||||||
tags: [],
|
tags: [],
|
||||||
assets: [],
|
assets: [],
|
||||||
|
memoriesEnabled: true,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
18
web/src/api/open-api/api.ts
generated
18
web/src/api/open-api/api.ts
generated
@ -954,6 +954,12 @@ export interface CreateUserDto {
|
|||||||
* @memberof CreateUserDto
|
* @memberof CreateUserDto
|
||||||
*/
|
*/
|
||||||
'lastName': string;
|
'lastName': string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof CreateUserDto
|
||||||
|
*/
|
||||||
|
'memoriesEnabled'?: boolean;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
@ -2995,6 +3001,12 @@ export interface UpdateUserDto {
|
|||||||
* @memberof UpdateUserDto
|
* @memberof UpdateUserDto
|
||||||
*/
|
*/
|
||||||
'lastName'?: string;
|
'lastName'?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof UpdateUserDto
|
||||||
|
*/
|
||||||
|
'memoriesEnabled'?: boolean;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
@ -3124,6 +3136,12 @@ export interface UserResponseDto {
|
|||||||
* @memberof UserResponseDto
|
* @memberof UserResponseDto
|
||||||
*/
|
*/
|
||||||
'lastName': string;
|
'lastName': string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof UserResponseDto
|
||||||
|
*/
|
||||||
|
'memoriesEnabled': boolean;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {
|
||||||
|
notificationController,
|
||||||
|
NotificationType,
|
||||||
|
} from '$lib/components/shared-components/notification/notification';
|
||||||
|
import { api, UserResponseDto } from '@api';
|
||||||
|
import { fade } from 'svelte/transition';
|
||||||
|
import { handleError } from '../../utils/handle-error';
|
||||||
|
import SettingSwitch from '../admin-page/settings/setting-switch.svelte';
|
||||||
|
import Button from '../elements/buttons/button.svelte';
|
||||||
|
|
||||||
|
export let user: UserResponseDto;
|
||||||
|
|
||||||
|
const handleSave = async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await api.userApi.updateUser({
|
||||||
|
updateUserDto: {
|
||||||
|
id: user.id,
|
||||||
|
memoriesEnabled: user.memoriesEnabled,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.assign(user, data);
|
||||||
|
|
||||||
|
notificationController.show({ message: 'Saved settings', type: NotificationType.Info });
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error, 'Unable to update settings');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<section class="my-4">
|
||||||
|
<div in:fade={{ duration: 500 }}>
|
||||||
|
<form autocomplete="off" on:submit|preventDefault>
|
||||||
|
<div class="ml-4 mt-4 flex flex-col gap-4">
|
||||||
|
<div class="ml-4">
|
||||||
|
<SettingSwitch
|
||||||
|
title="Time-based memories"
|
||||||
|
subtitle="Photos from previous years"
|
||||||
|
bind:checked={user.memoriesEnabled}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-end">
|
||||||
|
<Button type="submit" size="sm" on:click={() => handleSave()}>Save</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</section>
|
@ -4,10 +4,11 @@
|
|||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import SettingAccordion from '../admin-page/settings/setting-accordion.svelte';
|
import SettingAccordion from '../admin-page/settings/setting-accordion.svelte';
|
||||||
import ChangePasswordSettings from './change-password-settings.svelte';
|
import ChangePasswordSettings from './change-password-settings.svelte';
|
||||||
import OAuthSettings from './oauth-settings.svelte';
|
|
||||||
import UserAPIKeyList from './user-api-key-list.svelte';
|
|
||||||
import DeviceList from './device-list.svelte';
|
import DeviceList from './device-list.svelte';
|
||||||
|
import MemoriesSettings from './memories-settings.svelte';
|
||||||
|
import OAuthSettings from './oauth-settings.svelte';
|
||||||
import PartnerSettings from './partner-settings.svelte';
|
import PartnerSettings from './partner-settings.svelte';
|
||||||
|
import UserAPIKeyList from './user-api-key-list.svelte';
|
||||||
import UserProfileSettings from './user-profile-settings.svelte';
|
import UserProfileSettings from './user-profile-settings.svelte';
|
||||||
|
|
||||||
export let user: UserResponseDto;
|
export let user: UserResponseDto;
|
||||||
@ -39,6 +40,10 @@
|
|||||||
<DeviceList />
|
<DeviceList />
|
||||||
</SettingAccordion>
|
</SettingAccordion>
|
||||||
|
|
||||||
|
<SettingAccordion title="Memories" subtitle="Manage what you see in your memories.">
|
||||||
|
<MemoriesSettings {user} />
|
||||||
|
</SettingAccordion>
|
||||||
|
|
||||||
{#if oauthEnabled}
|
{#if oauthEnabled}
|
||||||
<SettingAccordion
|
<SettingAccordion
|
||||||
title="OAuth"
|
title="OAuth"
|
||||||
|
@ -59,7 +59,9 @@
|
|||||||
<svelte:fragment slot="content">
|
<svelte:fragment slot="content">
|
||||||
{#if assetCount}
|
{#if assetCount}
|
||||||
<AssetGrid {assetStore} {assetInteractionStore} removeAction={AssetAction.ARCHIVE}>
|
<AssetGrid {assetStore} {assetInteractionStore} removeAction={AssetAction.ARCHIVE}>
|
||||||
<MemoryLane />
|
{#if data.user.memoriesEnabled}
|
||||||
|
<MemoryLane />
|
||||||
|
{/if}
|
||||||
</AssetGrid>
|
</AssetGrid>
|
||||||
{:else}
|
{:else}
|
||||||
<EmptyPlaceholder text="CLICK TO UPLOAD YOUR FIRST PHOTO" actionHandler={() => openFileUploadDialog()} />
|
<EmptyPlaceholder text="CLICK TO UPLOAD YOUR FIRST PHOTO" actionHandler={() => openFileUploadDialog()} />
|
||||||
|
@ -15,5 +15,6 @@ export const userFactory = Sync.makeFactory<UserResponseDto>({
|
|||||||
createdAt: Sync.each(() => faker.date.past().toISOString()),
|
createdAt: Sync.each(() => faker.date.past().toISOString()),
|
||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
updatedAt: Sync.each(() => faker.date.past().toISOString()),
|
updatedAt: Sync.each(() => faker.date.past().toISOString()),
|
||||||
|
memoriesEnabled: true,
|
||||||
oauthId: '',
|
oauthId: '',
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user