Compare commits
2 Commits
v1.5.0+8-d
...
v1.5.1+9-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b69f6e0df7 | ||
|
|
be2794a372 |
@@ -0,0 +1 @@
|
|||||||
|
* Added inline font, remove google-font dependency in pubspec.
|
||||||
BIN
mobile/fonts/SnowburstOne.ttf
Normal file
BIN
mobile/fonts/SnowburstOne.ttf
Normal file
Binary file not shown.
BIN
mobile/fonts/WorkSans-Italic.ttf
Normal file
BIN
mobile/fonts/WorkSans-Italic.ttf
Normal file
Binary file not shown.
BIN
mobile/fonts/WorkSans.ttf
Normal file
BIN
mobile/fonts/WorkSans.ttf
Normal file
Binary file not shown.
@@ -19,11 +19,11 @@ platform :ios do
|
|||||||
desc "iOS Beta"
|
desc "iOS Beta"
|
||||||
lane :beta do
|
lane :beta do
|
||||||
increment_version_number(
|
increment_version_number(
|
||||||
version_number: "1.5.0"
|
version_number: "1.5.1"
|
||||||
|
)
|
||||||
|
increment_build_number(
|
||||||
|
build_number: latest_testflight_build_number + 1,
|
||||||
)
|
)
|
||||||
increment_build_number({
|
|
||||||
build_number: 0
|
|
||||||
})
|
|
||||||
build_app(scheme: "Runner",
|
build_app(scheme: "Runner",
|
||||||
workspace: "Runner.xcworkspace",
|
workspace: "Runner.xcworkspace",
|
||||||
xcargs: "-allowProvisioningUpdates")
|
xcargs: "-allowProvisioningUpdates")
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import 'package:immich_mobile/shared/providers/backup.provider.dart';
|
|||||||
import 'package:immich_mobile/shared/providers/server_info.provider.dart';
|
import 'package:immich_mobile/shared/providers/server_info.provider.dart';
|
||||||
import 'package:immich_mobile/shared/providers/websocket.provider.dart';
|
import 'package:immich_mobile/shared/providers/websocket.provider.dart';
|
||||||
import 'constants/hive_box.dart';
|
import 'constants/hive_box.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
await Hive.initFlutter();
|
await Hive.initFlutter();
|
||||||
@@ -94,10 +93,11 @@ class _ImmichAppState extends ConsumerState<ImmichApp> with WidgetsBindingObserv
|
|||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
brightness: Brightness.light,
|
brightness: Brightness.light,
|
||||||
primarySwatch: Colors.indigo,
|
primarySwatch: Colors.indigo,
|
||||||
textTheme: GoogleFonts.workSansTextTheme(
|
// textTheme: GoogleFonts.workSansTextTheme(
|
||||||
Theme.of(context).textTheme.apply(fontSizeFactor: 1.0),
|
// Theme.of(context).textTheme.apply(fontSizeFactor: 1.0),
|
||||||
),
|
// ),
|
||||||
snackBarTheme: SnackBarThemeData(contentTextStyle: TextStyle(fontFamily: GoogleFonts.workSans().fontFamily)),
|
fontFamily: 'WorkSans',
|
||||||
|
snackBarTheme: const SnackBarThemeData(contentTextStyle: TextStyle(fontFamily: 'WorkSans')),
|
||||||
scaffoldBackgroundColor: const Color(0xFFf6f8fe),
|
scaffoldBackgroundColor: const Color(0xFFf6f8fe),
|
||||||
appBarTheme: const AppBarTheme(
|
appBarTheme: const AppBarTheme(
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:badges/badges.dart';
|
import 'package:badges/badges.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.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/login/providers/authentication.provider.dart';
|
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
|
||||||
|
|
||||||
@@ -79,12 +78,11 @@ class ImmichSliverAppBar extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
'IMMICH',
|
'IMMICH',
|
||||||
style: GoogleFonts.snowburstOne(
|
style: TextStyle(
|
||||||
textStyle: TextStyle(
|
fontFamily: 'SnowburstOne',
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 22,
|
fontSize: 22,
|
||||||
color: Theme.of(context).primaryColor,
|
color: Theme.of(context).primaryColor,
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
@@ -121,8 +119,12 @@ class ImmichSliverAppBar extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
child: const Icon(Icons.backup_rounded)),
|
child: const Icon(Icons.backup_rounded)),
|
||||||
tooltip: 'Backup Controller',
|
tooltip: 'Backup Controller',
|
||||||
onPressed: () {
|
onPressed: () async {
|
||||||
AutoRouter.of(context).push(const BackupControllerRoute());
|
var onPop = await AutoRouter.of(context).push(const BackupControllerRoute());
|
||||||
|
|
||||||
|
if (onPop != null && onPop == true) {
|
||||||
|
onPopBack!();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
_backupState.backupProgress == BackUpProgressEnum.inProgress
|
_backupState.backupProgress == BackUpProgressEnum.inProgress
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ class HomePage extends HookConsumerWidget {
|
|||||||
return null;
|
return null;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
void reloadAllAsset() {
|
||||||
|
ref.read(assetProvider.notifier).getAllAsset();
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildBody() {
|
Widget _buildBody() {
|
||||||
if (assetGroupByDateTime.isNotEmpty) {
|
if (assetGroupByDateTime.isNotEmpty) {
|
||||||
int? lastMonth;
|
int? lastMonth;
|
||||||
@@ -86,7 +90,9 @@ class HomePage extends HookConsumerWidget {
|
|||||||
child: null,
|
child: null,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: const ImmichSliverAppBar(),
|
: ImmichSliverAppBar(
|
||||||
|
onPopBack: reloadAllAsset,
|
||||||
|
),
|
||||||
duration: const Duration(milliseconds: 350),
|
duration: const Duration(milliseconds: 350),
|
||||||
),
|
),
|
||||||
..._imageGridGroup
|
..._imageGridGroup
|
||||||
|
|||||||
@@ -1,7 +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_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.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/modules/home/providers/asset.provider.dart';
|
||||||
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
|
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
|
||||||
@@ -33,9 +32,12 @@ class LoginForm extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'IMMICH',
|
'IMMICH',
|
||||||
style: GoogleFonts.snowburstOne(
|
style: TextStyle(
|
||||||
textStyle:
|
fontFamily: 'SnowburstOne',
|
||||||
TextStyle(fontWeight: FontWeight.bold, fontSize: 48, color: Theme.of(context).primaryColor)),
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 48,
|
||||||
|
color: Theme.of(context).primaryColor,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
EmailInput(controller: usernameController),
|
EmailInput(controller: usernameController),
|
||||||
PasswordInput(controller: passwordController),
|
PasswordInput(controller: passwordController),
|
||||||
|
|||||||
@@ -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) {
|
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/shared/models/backup_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/shared/providers/backup.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';
|
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||||
|
|
||||||
class BackupControllerPage extends HookConsumerWidget {
|
class BackupControllerPage extends HookConsumerWidget {
|
||||||
@@ -23,6 +24,7 @@ class BackupControllerPage extends HookConsumerWidget {
|
|||||||
ref.read(backupProvider.notifier).getBackupInfo();
|
ref.read(backupProvider.notifier).getBackupInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ref.watch(websocketProvider.notifier).stopListenToEvent('on_upload_success');
|
||||||
return null;
|
return null;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -107,6 +109,7 @@ class BackupControllerPage extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
ref.watch(websocketProvider.notifier).listenUploadEvent();
|
||||||
AutoRouter.of(context).pop(true);
|
AutoRouter.of(context).pop(true);
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.arrow_back_ios_rounded)),
|
icon: const Icon(Icons.arrow_back_ios_rounded)),
|
||||||
|
|||||||
@@ -373,13 +373,6 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.2"
|
||||||
google_fonts:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: google_fonts
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.2.0"
|
|
||||||
graphs:
|
graphs:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ name: immich_mobile
|
|||||||
description: Immich - selfhosted backup media file on mobile phone
|
description: Immich - selfhosted backup media file on mobile phone
|
||||||
|
|
||||||
publish_to: "none"
|
publish_to: "none"
|
||||||
version: 1.5.0+8
|
version: 1.5.1+9
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.15.1 <3.0.0"
|
sdk: ">=2.15.1 <3.0.0"
|
||||||
@@ -18,7 +18,7 @@ dependencies:
|
|||||||
hive_flutter:
|
hive_flutter:
|
||||||
dio: ^4.0.4
|
dio: ^4.0.4
|
||||||
cached_network_image: ^3.2.0
|
cached_network_image: ^3.2.0
|
||||||
google_fonts: ^2.2.0
|
# google_fonts: ^2.2.0
|
||||||
percent_indicator: ^3.4.0
|
percent_indicator: ^3.4.0
|
||||||
intl: ^0.17.0
|
intl: ^0.17.0
|
||||||
auto_route: ^3.2.2
|
auto_route: ^3.2.2
|
||||||
@@ -50,6 +50,15 @@ flutter:
|
|||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
assets:
|
assets:
|
||||||
- assets/
|
- assets/
|
||||||
|
fonts:
|
||||||
|
- family: WorkSans
|
||||||
|
fonts:
|
||||||
|
- asset: fonts/WorkSans.ttf
|
||||||
|
- asset: fonts/WorkSans-Italic.ttf
|
||||||
|
style: italic
|
||||||
|
- family: SnowburstOne
|
||||||
|
fonts:
|
||||||
|
- asset: fonts/SnowburstOne.ttf
|
||||||
|
|
||||||
flutter_icons:
|
flutter_icons:
|
||||||
image_path_android: "assets/immich-logo-no-outline.png"
|
image_path_android: "assets/immich-logo-no-outline.png"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "immich",
|
"name": "immich",
|
||||||
"version": "1.3.2",
|
"version": "1.5.1",
|
||||||
"description": "",
|
"description": "",
|
||||||
"author": "",
|
"author": "",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
|||||||
@@ -115,18 +115,8 @@ export class AssetController {
|
|||||||
return this.assetService.searchAsset(authUser, searchAssetDto);
|
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('/')
|
@Get('/')
|
||||||
async getAllAssetsNoPagination(@GetAuthUser() authUser: AuthUserDto) {
|
async getAllAssets(@GetAuthUser() authUser: AuthUserDto) {
|
||||||
return await this.assetService.getAllAssetsNoPagination(authUser);
|
return await this.assetService.getAllAssetsNoPagination(authUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +127,7 @@ export class AssetController {
|
|||||||
|
|
||||||
@Get('/assetById/:assetId')
|
@Get('/assetById/:assetId')
|
||||||
async getAssetById(@GetAuthUser() authUser: AuthUserDto, @Param('assetId') assetId) {
|
async getAssetById(@GetAuthUser() authUser: AuthUserDto, @Param('assetId') assetId) {
|
||||||
return this.assetService.getAssetById(authUser, assetId);
|
return await this.assetService.getAssetById(authUser, assetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete('/')
|
@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> {
|
public async findOne(authUser: AuthUserDto, deviceId: string, assetId: string): Promise<AssetEntity> {
|
||||||
const rows = await this.assetRepository.query(
|
const rows = await this.assetRepository.query(
|
||||||
'SELECT * FROM assets a WHERE a."deviceAssetId" = $1 AND a."userId" = $2 AND a."deviceId" = $3',
|
'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;
|
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) {
|
public async getAssetById(authUser: AuthUserDto, assetId: string) {
|
||||||
return await this.assetRepository.findOne({
|
return await this.assetRepository.findOne({
|
||||||
where: {
|
where: {
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
export const serverVersion = {
|
export const serverVersion = {
|
||||||
major: 1,
|
major: 1,
|
||||||
minor: 5,
|
minor: 5,
|
||||||
patch: 0,
|
patch: 1,
|
||||||
build: 8,
|
build: 9,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user