mirror of
https://github.com/immich-app/immich.git
synced 2024-12-25 10:43:13 +02:00
Optimization/fix slow backup when asset list is long. (#104)
* Handle pause/restart listening to event on_upload_success and reload asset list after navigating back from BackupControllerPage * Remove unused api endpoint
This commit is contained in:
parent
2ff25b49f4
commit
be2794a372
@ -21,9 +21,9 @@ platform :ios do
|
||||
increment_version_number(
|
||||
version_number: "1.5.0"
|
||||
)
|
||||
increment_build_number({
|
||||
build_number: 0
|
||||
})
|
||||
increment_build_number(
|
||||
build_number: latest_testflight_build_number + 1,
|
||||
)
|
||||
build_app(scheme: "Runner",
|
||||
workspace: "Runner.xcworkspace",
|
||||
xcargs: "-allowProvisioningUpdates")
|
||||
|
@ -121,8 +121,12 @@ class ImmichSliverAppBar extends ConsumerWidget {
|
||||
),
|
||||
child: const Icon(Icons.backup_rounded)),
|
||||
tooltip: 'Backup Controller',
|
||||
onPressed: () {
|
||||
AutoRouter.of(context).push(const BackupControllerRoute());
|
||||
onPressed: () async {
|
||||
var onPop = await AutoRouter.of(context).push(const BackupControllerRoute());
|
||||
|
||||
if (onPop != null && onPop == true) {
|
||||
onPopBack!();
|
||||
}
|
||||
},
|
||||
),
|
||||
_backupState.backupProgress == BackUpProgressEnum.inProgress
|
||||
|
@ -33,6 +33,10 @@ class HomePage extends HookConsumerWidget {
|
||||
return null;
|
||||
}, []);
|
||||
|
||||
void reloadAllAsset() {
|
||||
ref.read(assetProvider.notifier).getAllAsset();
|
||||
}
|
||||
|
||||
Widget _buildBody() {
|
||||
if (assetGroupByDateTime.isNotEmpty) {
|
||||
int? lastMonth;
|
||||
@ -86,7 +90,9 @@ class HomePage extends HookConsumerWidget {
|
||||
child: null,
|
||||
),
|
||||
)
|
||||
: const ImmichSliverAppBar(),
|
||||
: ImmichSliverAppBar(
|
||||
onPopBack: reloadAllAsset,
|
||||
),
|
||||
duration: const Duration(milliseconds: 350),
|
||||
),
|
||||
..._imageGridGroup
|
||||
|
@ -106,6 +106,20 @@ class WebsocketNotifier extends StateNotifier<WebscoketState> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stopListenToEvent(String eventName) {
|
||||
debugPrint("[Websocket] Stop listening to event $eventName");
|
||||
state.socket?.off(eventName);
|
||||
}
|
||||
|
||||
listenUploadEvent() {
|
||||
debugPrint("[Websocket] Start listening to event on_upload_success");
|
||||
state.socket?.on('on_upload_success', (data) {
|
||||
var jsonString = jsonDecode(data.toString());
|
||||
ImmichAsset newAsset = ImmichAsset.fromMap(jsonString);
|
||||
ref.watch(assetProvider.notifier).onNewAssetUploaded(newAsset);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
final websocketProvider = StateNotifierProvider<WebsocketNotifier, WebscoketState>((ref) {
|
||||
|
@ -6,6 +6,7 @@ import 'package:immich_mobile/modules/login/models/authentication_state.model.da
|
||||
import 'package:immich_mobile/shared/models/backup_state.model.dart';
|
||||
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
|
||||
import 'package:immich_mobile/shared/providers/backup.provider.dart';
|
||||
import 'package:immich_mobile/shared/providers/websocket.provider.dart';
|
||||
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||
|
||||
class BackupControllerPage extends HookConsumerWidget {
|
||||
@ -23,6 +24,7 @@ class BackupControllerPage extends HookConsumerWidget {
|
||||
ref.read(backupProvider.notifier).getBackupInfo();
|
||||
}
|
||||
|
||||
ref.watch(websocketProvider.notifier).stopListenToEvent('on_upload_success');
|
||||
return null;
|
||||
}, []);
|
||||
|
||||
@ -107,6 +109,7 @@ class BackupControllerPage extends HookConsumerWidget {
|
||||
),
|
||||
leading: IconButton(
|
||||
onPressed: () {
|
||||
ref.watch(websocketProvider.notifier).listenUploadEvent();
|
||||
AutoRouter.of(context).pop(true);
|
||||
},
|
||||
icon: const Icon(Icons.arrow_back_ios_rounded)),
|
||||
|
@ -115,18 +115,8 @@ export class AssetController {
|
||||
return this.assetService.searchAsset(authUser, searchAssetDto);
|
||||
}
|
||||
|
||||
@Get('/new')
|
||||
async getNewAssets(@GetAuthUser() authUser: AuthUserDto, @Query(ValidationPipe) query: GetNewAssetQueryDto) {
|
||||
return await this.assetService.getNewAssets(authUser, query.latestDate);
|
||||
}
|
||||
|
||||
@Get('/all')
|
||||
async getAllAssets(@GetAuthUser() authUser: AuthUserDto, @Query(ValidationPipe) query: GetAllAssetQueryDto) {
|
||||
return await this.assetService.getAllAssets(authUser, query);
|
||||
}
|
||||
|
||||
@Get('/')
|
||||
async getAllAssetsNoPagination(@GetAuthUser() authUser: AuthUserDto) {
|
||||
async getAllAssets(@GetAuthUser() authUser: AuthUserDto) {
|
||||
return await this.assetService.getAllAssetsNoPagination(authUser);
|
||||
}
|
||||
|
||||
@ -137,7 +127,7 @@ export class AssetController {
|
||||
|
||||
@Get('/assetById/:assetId')
|
||||
async getAssetById(@GetAuthUser() authUser: AuthUserDto, @Param('assetId') assetId) {
|
||||
return this.assetService.getAssetById(authUser, assetId);
|
||||
return await this.assetService.getAssetById(authUser, assetId);
|
||||
}
|
||||
|
||||
@Delete('/')
|
||||
|
@ -76,42 +76,6 @@ export class AssetService {
|
||||
}
|
||||
}
|
||||
|
||||
public async getAllAssets(authUser: AuthUserDto, query: GetAllAssetQueryDto): Promise<GetAllAssetReponseDto> {
|
||||
try {
|
||||
const assets = await this.assetRepository
|
||||
.createQueryBuilder('a')
|
||||
.where('a."userId" = :userId', { userId: authUser.id })
|
||||
.andWhere('a."createdAt" < :lastQueryCreatedAt', {
|
||||
lastQueryCreatedAt: query.nextPageKey || new Date().toISOString(),
|
||||
})
|
||||
.orderBy('a."createdAt"::date', 'DESC')
|
||||
.take(5000)
|
||||
.getMany();
|
||||
|
||||
if (assets.length > 0) {
|
||||
const data = _.groupBy(assets, (a) => new Date(a.createdAt).toISOString().slice(0, 10));
|
||||
const formattedData = [];
|
||||
Object.keys(data).forEach((v) => formattedData.push({ date: v, assets: data[v] }));
|
||||
|
||||
const response = new GetAllAssetReponseDto();
|
||||
response.count = assets.length;
|
||||
response.data = formattedData;
|
||||
response.nextPageKey = assets[assets.length - 1].createdAt;
|
||||
|
||||
return response;
|
||||
} else {
|
||||
const response = new GetAllAssetReponseDto();
|
||||
response.count = 0;
|
||||
response.data = [];
|
||||
response.nextPageKey = 'null';
|
||||
|
||||
return response;
|
||||
}
|
||||
} catch (e) {
|
||||
Logger.error(e, 'getAllAssets');
|
||||
}
|
||||
}
|
||||
|
||||
public async findOne(authUser: AuthUserDto, deviceId: string, assetId: string): Promise<AssetEntity> {
|
||||
const rows = await this.assetRepository.query(
|
||||
'SELECT * FROM assets a WHERE a."deviceAssetId" = $1 AND a."userId" = $2 AND a."deviceId" = $3',
|
||||
@ -125,18 +89,6 @@ export class AssetService {
|
||||
return rows[0] as AssetEntity;
|
||||
}
|
||||
|
||||
public async getNewAssets(authUser: AuthUserDto, latestDate: string) {
|
||||
return await this.assetRepository.find({
|
||||
where: {
|
||||
userId: authUser.id,
|
||||
createdAt: MoreThan(latestDate),
|
||||
},
|
||||
order: {
|
||||
createdAt: 'ASC', // ASC order to add existed asset the latest group first before creating a new date group.
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public async getAssetById(authUser: AuthUserDto, assetId: string) {
|
||||
return await this.assetRepository.findOne({
|
||||
where: {
|
||||
|
Loading…
Reference in New Issue
Block a user