mirror of
https://github.com/immich-app/immich.git
synced 2025-01-01 08:31:59 +00:00
Implemented load new image when navigating back from backup page (#9)
This commit is contained in:
parent
1d3ee2008c
commit
c24fb403c5
12 changed files with 133 additions and 38 deletions
8
.github/workflows/Build+push Immich.yml
vendored
8
.github/workflows/Build+push Immich.yml
vendored
|
@ -6,10 +6,10 @@ on:
|
||||||
# * is a special character in YAML so you have to quote this string
|
# * is a special character in YAML so you have to quote this string
|
||||||
#- cron: '0 0 * * *'
|
#- cron: '0 0 * * *'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
#push:
|
# push:
|
||||||
#branches: [ main ]
|
#branches: [ main ]
|
||||||
pull_request:
|
# pull_request:
|
||||||
branches: [ main ]
|
# branches: [ main ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
buildandpush:
|
buildandpush:
|
||||||
|
@ -18,7 +18,7 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2.4.0
|
uses: actions/checkout@v2.4.0
|
||||||
with:
|
with:
|
||||||
ref: 'main' # branch
|
ref: "main" # branch
|
||||||
# https://github.com/docker/setup-qemu-action#usage
|
# https://github.com/docker/setup-qemu-action#usage
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v1.2.0
|
uses: docker/setup-qemu-action@v1.2.0
|
||||||
|
|
|
@ -79,7 +79,7 @@ flutter run --release
|
||||||
|
|
||||||
# Known Issue
|
# Known Issue
|
||||||
|
|
||||||
TensorFlow doesn't run with older CPU architecture, it requires CPU with AVX and AVX2 instruction set. If you encounter error `illegal instruction core dump` when running the docker-compose command above, check for your CPU flags with the command ad make sure you see `AVX` and `AVX2`. Otherwise, switch to a different VM/desktop with different architecture.
|
TensorFlow doesn't run with older CPU architecture, it requires CPU with AVX and AVX2 instruction set. If you encounter the error `illegal instruction core dump` when running the docker-compose command above, check for your CPU flags with the command and make sure you see `AVX` and `AVX2`. Otherwise, switch to a different VM/desktop with different architecture.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
more /proc/cpuinfo | grep flags
|
more /proc/cpuinfo | grep flags
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/modules/home/models/get_all_asset_respose.model.dart';
|
import 'package:immich_mobile/modules/home/models/get_all_asset_respose.model.dart';
|
||||||
import 'package:immich_mobile/modules/home/services/asset.service.dart';
|
import 'package:immich_mobile/modules/home/services/asset.service.dart';
|
||||||
|
import 'package:immich_mobile/shared/models/immich_asset.model.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
|
||||||
class AssetNotifier extends StateNotifier<List<ImmichAssetGroupByDate>> {
|
class AssetNotifier extends StateNotifier<List<ImmichAssetGroupByDate>> {
|
||||||
final imagePerPage = 100;
|
|
||||||
final AssetService _assetService = AssetService();
|
final AssetService _assetService = AssetService();
|
||||||
|
|
||||||
AssetNotifier() : super([]);
|
AssetNotifier() : super([]);
|
||||||
|
|
||||||
late String? nextPageKey = "";
|
late String? nextPageKey = "";
|
||||||
bool isFetching = false;
|
bool isFetching = false;
|
||||||
|
|
||||||
|
// Get All assets
|
||||||
getImmichAssets() async {
|
getImmichAssets() async {
|
||||||
GetAllAssetResponse? res = await _assetService.getAllAsset();
|
GetAllAssetResponse? res = await _assetService.getAllAsset();
|
||||||
nextPageKey = res?.nextPageKey;
|
nextPageKey = res?.nextPageKey;
|
||||||
|
@ -21,10 +25,11 @@ class AssetNotifier extends StateNotifier<List<ImmichAssetGroupByDate>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getMoreAsset() async {
|
// Get Asset From The Past
|
||||||
|
getOlderAsset() async {
|
||||||
if (nextPageKey != null && !isFetching) {
|
if (nextPageKey != null && !isFetching) {
|
||||||
isFetching = true;
|
isFetching = true;
|
||||||
GetAllAssetResponse? res = await _assetService.getMoreAsset(nextPageKey);
|
GetAllAssetResponse? res = await _assetService.getOlderAsset(nextPageKey);
|
||||||
|
|
||||||
if (res != null) {
|
if (res != null) {
|
||||||
nextPageKey = res.nextPageKey;
|
nextPageKey = res.nextPageKey;
|
||||||
|
@ -48,6 +53,40 @@ class AssetNotifier extends StateNotifier<List<ImmichAssetGroupByDate>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get newer asset from the current time
|
||||||
|
getNewAsset() async {
|
||||||
|
if (state.isNotEmpty) {
|
||||||
|
var latestGroup = state.first;
|
||||||
|
|
||||||
|
// Sort the last asset group and put the lastest asset in front.
|
||||||
|
latestGroup.assets.sortByCompare<DateTime>((e) => DateTime.parse(e.createdAt), (a, b) => b.compareTo(a));
|
||||||
|
var latestAsset = latestGroup.assets.first;
|
||||||
|
var formatDateTemplate = 'y-MM-dd';
|
||||||
|
var latestAssetDateText = DateFormat(formatDateTemplate).format(DateTime.parse(latestAsset.createdAt));
|
||||||
|
|
||||||
|
List<ImmichAsset> newAssets = await _assetService.getNewAsset(latestAsset.createdAt);
|
||||||
|
|
||||||
|
if (newAssets.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grouping by data
|
||||||
|
var groupByDateList = groupBy<ImmichAsset, String>(
|
||||||
|
newAssets, (asset) => DateFormat(formatDateTemplate).format(DateTime.parse(asset.createdAt)));
|
||||||
|
|
||||||
|
groupByDateList.forEach((groupDateInFormattedText, assets) {
|
||||||
|
if (groupDateInFormattedText != latestAssetDateText) {
|
||||||
|
ImmichAssetGroupByDate newGroup = ImmichAssetGroupByDate(assets: assets, date: groupDateInFormattedText);
|
||||||
|
state = [newGroup, ...state];
|
||||||
|
} else {
|
||||||
|
latestGroup.assets.insertAll(0, assets);
|
||||||
|
|
||||||
|
state = [latestGroup, ...state.sublist(1)];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
clearAllAsset() {
|
clearAllAsset() {
|
||||||
state = [];
|
state = [];
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:immich_mobile/modules/home/models/get_all_asset_respose.model.dart';
|
import 'package:immich_mobile/modules/home/models/get_all_asset_respose.model.dart';
|
||||||
|
import 'package:immich_mobile/shared/models/immich_asset.model.dart';
|
||||||
import 'package:immich_mobile/shared/services/network.service.dart';
|
import 'package:immich_mobile/shared/services/network.service.dart';
|
||||||
|
|
||||||
class AssetService {
|
class AssetService {
|
||||||
|
@ -17,9 +18,10 @@ class AssetService {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint("Error getAllAsset ${e.toString()}");
|
debugPrint("Error getAllAsset ${e.toString()}");
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<GetAllAssetResponse?> getMoreAsset(String? nextPageKey) async {
|
Future<GetAllAssetResponse?> getOlderAsset(String? nextPageKey) async {
|
||||||
try {
|
try {
|
||||||
var res = await _networkService.getRequest(
|
var res = await _networkService.getRequest(
|
||||||
url: "asset/all?nextPageKey=$nextPageKey",
|
url: "asset/all?nextPageKey=$nextPageKey",
|
||||||
|
@ -34,5 +36,26 @@ class AssetService {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint("Error getAllAsset ${e.toString()}");
|
debugPrint("Error getAllAsset ${e.toString()}");
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<ImmichAsset>> getNewAsset(String latestDate) async {
|
||||||
|
try {
|
||||||
|
var res = await _networkService.getRequest(
|
||||||
|
url: "asset/new?latestDate=$latestDate",
|
||||||
|
);
|
||||||
|
|
||||||
|
List<dynamic> decodedData = jsonDecode(res.toString());
|
||||||
|
|
||||||
|
List<ImmichAsset> result = List.from(decodedData.map((a) => ImmichAsset.fromMap(a)));
|
||||||
|
if (result.isNotEmpty) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint("Error getAllAsset ${e.toString()}");
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/modules/home/providers/asset.provider.dart';
|
|
||||||
|
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
import 'package:immich_mobile/shared/models/backup_state.model.dart';
|
import 'package:immich_mobile/shared/models/backup_state.model.dart';
|
||||||
|
@ -12,9 +11,11 @@ class ImmichSliverAppBar extends ConsumerWidget {
|
||||||
const ImmichSliverAppBar({
|
const ImmichSliverAppBar({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.imageGridGroup,
|
required this.imageGridGroup,
|
||||||
|
this.onPopBack,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final List<Widget> imageGridGroup;
|
final List<Widget> imageGridGroup;
|
||||||
|
final Function? onPopBack;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
@ -75,15 +76,7 @@ class ImmichSliverAppBar extends ConsumerWidget {
|
||||||
var onPop = await AutoRouter.of(context).push(const BackupControllerRoute());
|
var onPop = await AutoRouter.of(context).push(const BackupControllerRoute());
|
||||||
|
|
||||||
if (onPop == true) {
|
if (onPop == true) {
|
||||||
// Remove and force getting new widget again if there is not many widget on screen.
|
onPopBack!();
|
||||||
// Otherwise do nothing.
|
|
||||||
if (imageGridGroup.isNotEmpty && imageGridGroup.length < 20) {
|
|
||||||
print("Get more access");
|
|
||||||
ref.read(assetProvider.notifier).getMoreAsset();
|
|
||||||
} else if (imageGridGroup.isEmpty) {
|
|
||||||
print("get immich asset");
|
|
||||||
ref.read(assetProvider.notifier).getImmichAssets();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
import 'package:auto_route/annotations.dart';
|
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/src/widgets/framework.dart';
|
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/modules/home/providers/asset.provider.dart';
|
import 'package:immich_mobile/modules/home/providers/asset.provider.dart';
|
||||||
import 'package:immich_mobile/modules/login/models/authentication_state.model.dart';
|
import 'package:immich_mobile/modules/login/models/authentication_state.model.dart';
|
||||||
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
|
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
|
||||||
|
|
||||||
class ProfileDrawer extends ConsumerWidget {
|
class ProfileDrawer extends ConsumerWidget {
|
||||||
const ProfileDrawer({Key? key}) : super(key: key);
|
const ProfileDrawer({Key? key}) : super(key: key);
|
||||||
|
@ -58,6 +55,7 @@ class ProfileDrawer extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
bool res = await ref.read(authenticationProvider.notifier).logout();
|
bool res = await ref.read(authenticationProvider.notifier).logout();
|
||||||
|
|
||||||
ref.read(assetProvider.notifier).clearAllAsset();
|
ref.read(assetProvider.notifier).clearAllAsset();
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
|
|
|
@ -24,7 +24,7 @@ class HomePage extends HookConsumerWidget {
|
||||||
var endOfPage = _scrollController.position.maxScrollExtent;
|
var endOfPage = _scrollController.position.maxScrollExtent;
|
||||||
|
|
||||||
if (_scrollController.offset >= endOfPage - (endOfPage * 0.1) && !_scrollController.position.outOfRange) {
|
if (_scrollController.offset >= endOfPage - (endOfPage * 0.1) && !_scrollController.position.outOfRange) {
|
||||||
ref.read(assetProvider.notifier).getMoreAsset();
|
ref.read(assetProvider.notifier).getOlderAsset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_scrollController.offset >= 400) {
|
if (_scrollController.offset >= 400) {
|
||||||
|
@ -44,6 +44,18 @@ class HomePage extends HookConsumerWidget {
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
onPopBackFromBackupPage() {
|
||||||
|
ref.read(assetProvider.notifier).getNewAsset();
|
||||||
|
// Remove and force getting new widget again if there is not many widget on screen.
|
||||||
|
// Otherwise do nothing.
|
||||||
|
|
||||||
|
if (imageGridGroup.isNotEmpty && imageGridGroup.length < 20) {
|
||||||
|
ref.read(assetProvider.notifier).getOlderAsset();
|
||||||
|
} else if (imageGridGroup.isEmpty) {
|
||||||
|
ref.read(assetProvider.notifier).getImmichAssets();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildBody() {
|
Widget _buildBody() {
|
||||||
if (assetGroup.isNotEmpty) {
|
if (assetGroup.isNotEmpty) {
|
||||||
String lastGroupDate = assetGroup[0].date;
|
String lastGroupDate = assetGroup[0].date;
|
||||||
|
@ -56,11 +68,14 @@ class HomePage extends HookConsumerWidget {
|
||||||
int? previousMonth = DateTime.tryParse(lastGroupDate)?.month;
|
int? previousMonth = DateTime.tryParse(lastGroupDate)?.month;
|
||||||
|
|
||||||
// Add Monthly Title Group if started at the beginning of the month
|
// Add Monthly Title Group if started at the beginning of the month
|
||||||
if ((currentMonth! - previousMonth!) != 0) {
|
|
||||||
|
if (currentMonth != null && previousMonth != null) {
|
||||||
|
if ((currentMonth - previousMonth) != 0) {
|
||||||
imageGridGroup.add(
|
imageGridGroup.add(
|
||||||
MonthlyTitleText(isoDate: dateTitle),
|
MonthlyTitleText(isoDate: dateTitle),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add Daily Title Group
|
// Add Daily Title Group
|
||||||
imageGridGroup.add(
|
imageGridGroup.add(
|
||||||
|
@ -84,7 +99,10 @@ class HomePage extends HookConsumerWidget {
|
||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
slivers: [
|
slivers: [
|
||||||
ImmichSliverAppBar(imageGridGroup: imageGridGroup),
|
ImmichSliverAppBar(
|
||||||
|
imageGridGroup: imageGridGroup,
|
||||||
|
onPopBack: onPopBackFromBackupPage,
|
||||||
|
),
|
||||||
...imageGridGroup,
|
...imageGridGroup,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:immich_mobile/constants/hive_box.dart';
|
import 'package:immich_mobile/constants/hive_box.dart';
|
||||||
import 'package:chewie/chewie.dart';
|
import 'package:chewie/chewie.dart';
|
||||||
|
@ -17,6 +18,7 @@ class VideoViewerPage extends StatelessWidget {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: Colors.black,
|
backgroundColor: Colors.black,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
systemOverlayStyle: SystemUiOverlayStyle.light,
|
||||||
backgroundColor: Colors.black,
|
backgroundColor: Colors.black,
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
@ -24,7 +26,7 @@ class VideoViewerPage extends StatelessWidget {
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.arrow_back_ios)),
|
icon: const Icon(Icons.arrow_back_ios)),
|
||||||
),
|
),
|
||||||
body: Center(
|
body: SafeArea(
|
||||||
child: VideoThumbnailPlayer(
|
child: VideoThumbnailPlayer(
|
||||||
url: videoUrl,
|
url: videoUrl,
|
||||||
jwtToken: jwtToken,
|
jwtToken: jwtToken,
|
||||||
|
@ -64,7 +66,6 @@ class _VideoThumbnailPlayerState extends State<VideoThumbnailPlayer> {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint("ERROR initialize video player");
|
debugPrint("ERROR initialize video player");
|
||||||
print(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import { Response as Res } from 'express';
|
||||||
import { promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
import { stat } from 'fs';
|
import { stat } from 'fs';
|
||||||
import { pipeline } from 'stream';
|
import { pipeline } from 'stream';
|
||||||
|
import { GetNewAssetQueryDto } from './dto/get-new-asset-query.dto';
|
||||||
|
|
||||||
const fileInfo = promisify(stat);
|
const fileInfo = promisify(stat);
|
||||||
|
|
||||||
|
@ -141,6 +142,11 @@ export class AssetController {
|
||||||
console.log('SHOULD NOT BE HERE');
|
console.log('SHOULD NOT BE HERE');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get('/new')
|
||||||
|
async getNewAssets(@GetAuthUser() authUser: AuthUserDto, @Query(ValidationPipe) query: GetNewAssetQueryDto) {
|
||||||
|
return await this.assetService.getNewAssets(authUser, query.latestDate);
|
||||||
|
}
|
||||||
|
|
||||||
@Get('/all')
|
@Get('/all')
|
||||||
async getAllAssets(@GetAuthUser() authUser: AuthUserDto, @Query(ValidationPipe) query: GetAllAssetQueryDto) {
|
async getAllAssets(@GetAuthUser() authUser: AuthUserDto, @Query(ValidationPipe) query: GetAllAssetQueryDto) {
|
||||||
return await this.assetService.getAllAssets(authUser, query);
|
return await this.assetService.getAllAssets(authUser, query);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BadRequestException, Injectable, Logger } from '@nestjs/common';
|
import { BadRequestException, Injectable, Logger } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { Repository } from 'typeorm';
|
import { MoreThan, Repository } from 'typeorm';
|
||||||
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
||||||
import { CreateAssetDto } from './dto/create-asset.dto';
|
import { CreateAssetDto } from './dto/create-asset.dto';
|
||||||
import { UpdateAssetDto } from './dto/update-asset.dto';
|
import { UpdateAssetDto } from './dto/update-asset.dto';
|
||||||
|
@ -8,6 +8,7 @@ import { AssetEntity, AssetType } from './entities/asset.entity';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { GetAllAssetQueryDto } from './dto/get-all-asset-query.dto';
|
import { GetAllAssetQueryDto } from './dto/get-all-asset-query.dto';
|
||||||
import { GetAllAssetReponseDto } from './dto/get-all-asset-response.dto';
|
import { GetAllAssetReponseDto } from './dto/get-all-asset-response.dto';
|
||||||
|
import { Greater } from '@tensorflow/tfjs-core';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AssetService {
|
export class AssetService {
|
||||||
|
@ -53,8 +54,6 @@ export class AssetService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getAllAssets(authUser: AuthUserDto, query: GetAllAssetQueryDto): Promise<GetAllAssetReponseDto> {
|
public async getAllAssets(authUser: AuthUserDto, query: GetAllAssetQueryDto): Promise<GetAllAssetReponseDto> {
|
||||||
// Each page will take 100 images.
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const assets = await this.assetRepository
|
const assets = await this.assetRepository
|
||||||
.createQueryBuilder('a')
|
.createQueryBuilder('a')
|
||||||
|
@ -63,7 +62,7 @@ export class AssetService {
|
||||||
lastQueryCreatedAt: query.nextPageKey || new Date().toISOString(),
|
lastQueryCreatedAt: query.nextPageKey || new Date().toISOString(),
|
||||||
})
|
})
|
||||||
.orderBy('a."createdAt"::date', 'DESC')
|
.orderBy('a."createdAt"::date', 'DESC')
|
||||||
// .take(500)
|
.take(5000)
|
||||||
.getMany();
|
.getMany();
|
||||||
|
|
||||||
if (assets.length > 0) {
|
if (assets.length > 0) {
|
||||||
|
@ -102,4 +101,16 @@ export class AssetService {
|
||||||
|
|
||||||
return rows[0] as AssetEntity;
|
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.
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { IsNotEmpty } from 'class-validator';
|
import { IsNotEmpty } from 'class-validator';
|
||||||
|
|
||||||
class GetAssetDto {
|
export class GetAssetDto {
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
deviceId: string;
|
deviceId: string;
|
||||||
}
|
}
|
||||||
|
|
6
server/src/api-v1/asset/dto/get-new-asset-query.dto.ts
Normal file
6
server/src/api-v1/asset/dto/get-new-asset-query.dto.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import { IsNotEmpty } from 'class-validator';
|
||||||
|
|
||||||
|
export class GetNewAssetQueryDto {
|
||||||
|
@IsNotEmpty()
|
||||||
|
latestDate: string;
|
||||||
|
}
|
Loading…
Reference in a new issue