Merge branch 'main' into fix/save-album-sort

This commit is contained in:
Yaros 2025-09-17 14:40:05 +02:00
commit aa0732158b
27 changed files with 125 additions and 96 deletions

View File

@ -100,8 +100,9 @@ jobs:
- name: Run dart format - name: Run dart format
run: make format run: make format
- name: Run dart custom_lint # TODO: Re-enable after upgrading custom_lint
run: dart run custom_lint # - name: Run dart custom_lint
# run: dart run custom_lint
# TODO: Use https://github.com/CQLabs/dcm-action # TODO: Use https://github.com/CQLabs/dcm-action
- name: Run DCM - name: Run DCM

View File

@ -4,3 +4,4 @@
/web/ @danieldietzler /web/ @danieldietzler
/machine-learning/ @mertalev /machine-learning/ @mertalev
/e2e/ @danieldietzler /e2e/ @danieldietzler
/mobile/ @shenlong-tanwen

View File

@ -3,7 +3,7 @@ version = "3.8.2"
backend = "asdf:dart" backend = "asdf:dart"
[tools.flutter] [tools.flutter]
version = "3.32.8-stable" version = "3.35.3-stable"
backend = "asdf:flutter" backend = "asdf:flutter"
[tools."github:CQLabs/homebrew-dcm"] [tools."github:CQLabs/homebrew-dcm"]

View File

@ -1,6 +1,6 @@
[tools] [tools]
node = "22.19.0" node = "22.19.0"
flutter = "3.32.8" flutter = "3.35.3"
pnpm = "10.14.0" pnpm = "10.14.0"
dart = "3.8.2" dart = "3.8.2"
@ -300,7 +300,7 @@ run = "tsc --noEmit"
depends = "web:svelte-kit-sync" depends = "web:svelte-kit-sync"
env._.path = "web/node_modules/.bin" env._.path = "web/node_modules/.bin"
dir = "web" dir = "web"
run = "svelte-check --no-tsconfig --fail-on-warnings --compiler-warnings 'reactive_declaration_non_reactive_property:ignore' --ignore src/lib/components/timeline/Timeline.svelte" run = "svelte-check --no-tsconfig --fail-on-warnings"
[tasks."web:checklist"] [tasks."web:checklist"]
run = [ run = [

View File

@ -1,3 +1,3 @@
{ {
"flutter": "3.32.8" "flutter": "3.35.3"
} }

View File

@ -1,8 +1,8 @@
{ {
"dart.flutterSdkPath": ".fvm/versions/3.32.8", "dart.flutterSdkPath": ".fvm/versions/3.35.3",
"dart.lineLength": 120, "dart.lineLength": 120,
"[dart]": { "[dart]": {
"editor.rulers": [120], "editor.rulers": [120]
}, },
"search.exclude": { "search.exclude": {
"**/.fvm": true "**/.fvm": true

View File

@ -43,8 +43,9 @@ analyzer:
- lib/**/*.g.dart - lib/**/*.g.dart
- lib/**/*.drift.dart - lib/**/*.drift.dart
plugins: # TODO: Re-enable after upgrading custom_lint
- custom_lint # plugins:
# - custom_lint
custom_lint: custom_lint:
debug: true debug: true

View File

@ -21,6 +21,6 @@
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>12.0</string> <string>13.0</string>
</dict> </dict>
</plist> </plist>

View File

@ -253,7 +253,7 @@ SPEC CHECKSUMS:
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
flutter_local_notifications: ad39620c743ea4c15127860f4b5641649a988100 flutter_local_notifications: ad39620c743ea4c15127860f4b5641649a988100
flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13 flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13

View File

@ -16,6 +16,7 @@ class BackgroundWorkerApiImpl: BackgroundWorkerFgHostApi {
private static let refreshTaskID = "app.alextran.immich.background.refreshUpload" private static let refreshTaskID = "app.alextran.immich.background.refreshUpload"
private static let processingTaskID = "app.alextran.immich.background.processingUpload" private static let processingTaskID = "app.alextran.immich.background.processingUpload"
private static let taskSemaphore = DispatchSemaphore(value: 1)
public static func registerBackgroundWorkers() { public static func registerBackgroundWorkers() {
BGTaskScheduler.shared.register( BGTaskScheduler.shared.register(
@ -59,12 +60,18 @@ class BackgroundWorkerApiImpl: BackgroundWorkerFgHostApi {
private static func handleBackgroundRefresh(task: BGAppRefreshTask) { private static func handleBackgroundRefresh(task: BGAppRefreshTask) {
scheduleRefreshWorker() scheduleRefreshWorker()
// Restrict the refresh task to run only for a maximum of (maxSeconds) seconds // If another task is running, cede the background time back to the OS
runBackgroundWorker(task: task, taskType: .refresh, maxSeconds: 20) if taskSemaphore.wait(timeout: .now()) == .success {
// Restrict the refresh task to run only for a maximum of (maxSeconds) seconds
runBackgroundWorker(task: task, taskType: .refresh, maxSeconds: 20)
} else {
task.setTaskCompleted(success: false)
}
} }
private static func handleBackgroundProcessing(task: BGProcessingTask) { private static func handleBackgroundProcessing(task: BGProcessingTask) {
scheduleProcessingWorker() scheduleProcessingWorker()
taskSemaphore.wait()
// There are no restrictions for processing tasks. Although, the OS could signal expiration at any time // There are no restrictions for processing tasks. Although, the OS could signal expiration at any time
runBackgroundWorker(task: task, taskType: .processing, maxSeconds: nil) runBackgroundWorker(task: task, taskType: .processing, maxSeconds: nil)
} }
@ -80,6 +87,7 @@ class BackgroundWorkerApiImpl: BackgroundWorkerFgHostApi {
* - maxSeconds: Optional timeout for the operation in seconds * - maxSeconds: Optional timeout for the operation in seconds
*/ */
private static func runBackgroundWorker(task: BGTask, taskType: BackgroundTaskType, maxSeconds: Int?) { private static func runBackgroundWorker(task: BGTask, taskType: BackgroundTaskType, maxSeconds: Int?) {
defer { taskSemaphore.signal() }
let semaphore = DispatchSemaphore(value: 0) let semaphore = DispatchSemaphore(value: 0)
var isSuccess = true var isSuccess = true

View File

@ -169,7 +169,7 @@ class AlbumOptionsPage extends HookConsumerWidget {
album.activityEnabled = value; album.activityEnabled = value;
} }
}, },
activeColor: activityEnabled.value ? context.primaryColor : context.themeData.disabledColor, activeThumbColor: activityEnabled.value ? context.primaryColor : context.themeData.disabledColor,
dense: true, dense: true,
title: Text( title: Text(
"comments_and_likes", "comments_and_likes",

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:auto_route/auto_route.dart'; import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -9,11 +11,13 @@ import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart'; import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart';
import 'package:immich_mobile/presentation/widgets/backup/backup_toggle_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/backup/backup_toggle_button.widget.dart';
import 'package:immich_mobile/providers/app_settings.provider.dart';
import 'package:immich_mobile/providers/background_sync.provider.dart'; import 'package:immich_mobile/providers/background_sync.provider.dart';
import 'package:immich_mobile/providers/backup/backup_album.provider.dart'; import 'package:immich_mobile/providers/backup/backup_album.provider.dart';
import 'package:immich_mobile/providers/backup/drift_backup.provider.dart'; import 'package:immich_mobile/providers/backup/drift_backup.provider.dart';
import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart';
import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/services/app_settings.service.dart';
import 'package:immich_mobile/widgets/backup/backup_info_card.dart'; import 'package:immich_mobile/widgets/backup/backup_info_card.dart';
@RoutePage() @RoutePage()
@ -25,6 +29,8 @@ class DriftBackupPage extends ConsumerStatefulWidget {
} }
class _DriftBackupPageState extends ConsumerState<DriftBackupPage> { class _DriftBackupPageState extends ConsumerState<DriftBackupPage> {
Timer? _countPoller;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -33,9 +39,42 @@ class _DriftBackupPageState extends ConsumerState<DriftBackupPage> {
return; return;
} }
if (ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableBackup)) {
_startCountPolling();
}
ref.read(driftBackupProvider.notifier).getBackupStatus(currentUser.id); ref.read(driftBackupProvider.notifier).getBackupStatus(currentUser.id);
} }
void _startCountPolling() {
_countPoller?.cancel();
_countPoller = Timer.periodic(const Duration(seconds: 5), (timer) async {
if (!mounted) {
timer.cancel();
return;
}
final currentUser = ref.read(currentUserProvider);
if (currentUser == null) {
timer.cancel();
return;
}
await ref.read(driftBackupProvider.notifier).getBackupStatus(currentUser.id);
});
}
void _stopCountPolling() {
_countPoller?.cancel();
_countPoller = null;
}
@override
void dispose() {
_stopCountPolling();
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final selectedAlbum = ref final selectedAlbum = ref
@ -55,10 +94,12 @@ class _DriftBackupPageState extends ConsumerState<DriftBackupPage> {
await backgroundManager.syncRemote(); await backgroundManager.syncRemote();
await backupNotifier.getBackupStatus(currentUser.id); await backupNotifier.getBackupStatus(currentUser.id);
await backupNotifier.startBackup(currentUser.id); await backupNotifier.startBackup(currentUser.id);
_startCountPolling();
} }
Future<void> stopBackup() async { Future<void> stopBackup() async {
await backupNotifier.cancel(); await backupNotifier.cancel();
_stopCountPolling();
} }
return Scaffold( return Scaffold(

View File

@ -112,7 +112,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
return SwitchListTile.adaptive( return SwitchListTile.adaptive(
value: showMetadata.value, value: showMetadata.value,
onChanged: newShareLink.value.isEmpty ? (value) => showMetadata.value = value : null, onChanged: newShareLink.value.isEmpty ? (value) => showMetadata.value = value : null,
activeColor: colorScheme.primary, activeThumbColor: colorScheme.primary,
dense: true, dense: true,
title: Text("show_metadata", style: themeData.textTheme.labelLarge?.copyWith(fontWeight: FontWeight.bold)).tr(), title: Text("show_metadata", style: themeData.textTheme.labelLarge?.copyWith(fontWeight: FontWeight.bold)).tr(),
); );
@ -122,7 +122,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
return SwitchListTile.adaptive( return SwitchListTile.adaptive(
value: allowDownload.value, value: allowDownload.value,
onChanged: newShareLink.value.isEmpty ? (value) => allowDownload.value = value : null, onChanged: newShareLink.value.isEmpty ? (value) => allowDownload.value = value : null,
activeColor: colorScheme.primary, activeThumbColor: colorScheme.primary,
dense: true, dense: true,
title: Text( title: Text(
"allow_public_user_to_download", "allow_public_user_to_download",
@ -135,7 +135,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
return SwitchListTile.adaptive( return SwitchListTile.adaptive(
value: allowUpload.value, value: allowUpload.value,
onChanged: newShareLink.value.isEmpty ? (value) => allowUpload.value = value : null, onChanged: newShareLink.value.isEmpty ? (value) => allowUpload.value = value : null,
activeColor: colorScheme.primary, activeThumbColor: colorScheme.primary,
dense: true, dense: true,
title: Text( title: Text(
"allow_public_user_to_upload", "allow_public_user_to_upload",
@ -148,7 +148,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
return SwitchListTile.adaptive( return SwitchListTile.adaptive(
value: editExpiry.value, value: editExpiry.value,
onChanged: newShareLink.value.isEmpty ? (value) => editExpiry.value = value : null, onChanged: newShareLink.value.isEmpty ? (value) => editExpiry.value = value : null,
activeColor: colorScheme.primary, activeThumbColor: colorScheme.primary,
dense: true, dense: true,
title: Text( title: Text(
"change_expiration_time", "change_expiration_time",

View File

@ -208,7 +208,7 @@ class DriftAlbumOptionsPage extends HookConsumerWidget {
activityEnabled.value = value; activityEnabled.value = value;
await ref.read(remoteAlbumProvider.notifier).setActivityStatus(album.id, value); await ref.read(remoteAlbumProvider.notifier).setActivityStatus(album.id, value);
}, },
activeColor: activityEnabled.value ? context.primaryColor : context.themeData.disabledColor, activeThumbColor: activityEnabled.value ? context.primaryColor : context.themeData.disabledColor,
dense: true, dense: true,
title: Text( title: Text(
"comments_and_likes", "comments_and_likes",

View File

@ -96,7 +96,7 @@ mixin CancellableImageProviderMixin<T extends Object> on CancellableImageProvide
final operation = cachedOperation; final operation = cachedOperation;
if (operation != null) { if (operation != null) {
this.cachedOperation = null; cachedOperation = null;
operation.cancel(); operation.cancel();
} }
} }

View File

@ -12,8 +12,8 @@ import 'package:immich_mobile/infrastructure/repositories/backup.repository.dart
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart'; import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart';
import 'package:immich_mobile/services/upload.service.dart'; import 'package:immich_mobile/services/upload.service.dart';
import 'package:logging/logging.dart';
import 'package:immich_mobile/utils/debug_print.dart'; import 'package:immich_mobile/utils/debug_print.dart';
import 'package:logging/logging.dart';
class EnqueueStatus { class EnqueueStatus {
final int enqueueCount; final int enqueueCount;
@ -234,10 +234,6 @@ class DriftBackupNotifier extends StateNotifier<DriftBackupState> {
switch (update.status) { switch (update.status) {
case TaskStatus.complete: case TaskStatus.complete:
if (update.task.group == kBackupGroup) {
state = state.copyWith(backupCount: state.backupCount + 1, remainderCount: state.remainderCount - 1);
}
// Remove the completed task from the upload items // Remove the completed task from the upload items
if (state.uploadItems.containsKey(taskId)) { if (state.uploadItems.containsKey(taskId)) {
Future.delayed(const Duration(milliseconds: 1000), () { Future.delayed(const Duration(milliseconds: 1000), () {

View File

@ -13,7 +13,7 @@ class MapSettingsListTile extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SwitchListTile.adaptive( return SwitchListTile.adaptive(
activeColor: context.primaryColor, activeThumbColor: context.primaryColor,
title: Text(title, style: context.textTheme.labelLarge?.copyWith(fontWeight: FontWeight.bold)).tr(), title: Text(title, style: context.textTheme.labelLarge?.copyWith(fontWeight: FontWeight.bold)).tr(),
value: selected, value: selected,
onChanged: onChanged, onChanged: onChanged,

View File

@ -350,8 +350,8 @@ class PhotoViewCoreState extends State<PhotoViewCore>
final computedScale = useImageScale ? 1.0 : scale; final computedScale = useImageScale ? 1.0 : scale;
final matrix = Matrix4.identity() final matrix = Matrix4.identity()
..translate(value.position.dx, value.position.dy) ..translateByDouble(value.position.dx, value.position.dy, 0, 1.0)
..scale(computedScale) ..scaleByDouble(computedScale, computedScale, computedScale, 1.0)
..rotateZ(value.rotation); ..rotateZ(value.rotation);
final Widget customChildLayout = CustomSingleChildLayout( final Widget customChildLayout = CustomSingleChildLayout(

View File

@ -13,40 +13,19 @@ class MediaTypePicker extends HookWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final selectedMediaType = useState(filter ?? AssetType.other); final selectedMediaType = useState(filter ?? AssetType.other);
return ListView( return RadioGroup(
shrinkWrap: true, onChanged: (value) {
children: [ selectedMediaType.value = value!;
RadioListTile( onSelect(value);
key: const Key("all"), },
title: const Text("all").tr(), groupValue: selectedMediaType.value,
value: AssetType.other, child: Column(
onChanged: (value) { children: [
selectedMediaType.value = value!; RadioListTile(key: const Key("all"), title: const Text("all").tr(), value: AssetType.other),
onSelect(value); RadioListTile(key: const Key("image"), title: const Text("image").tr(), value: AssetType.image),
}, RadioListTile(key: const Key("video"), title: const Text("video").tr(), value: AssetType.video),
groupValue: selectedMediaType.value, ],
), ),
RadioListTile(
key: const Key("image"),
title: const Text("image").tr(),
value: AssetType.image,
onChanged: (value) {
selectedMediaType.value = value!;
onSelect(value);
},
groupValue: selectedMediaType.value,
),
RadioListTile(
key: const Key("video"),
title: const Text("video").tr(),
value: AssetType.video,
onChanged: (value) {
selectedMediaType.value = value!;
onSelect(value);
},
groupValue: selectedMediaType.value,
),
],
); );
} }
} }

View File

@ -62,7 +62,7 @@ class BetaTimelineListTile extends ConsumerWidget {
trailing: Switch.adaptive( trailing: Switch.adaptive(
value: betaTimelineValue, value: betaTimelineValue,
onChanged: onSwitchChanged, onChanged: onSwitchChanged,
activeColor: context.primaryColor, activeThumbColor: context.primaryColor,
), ),
onTap: () => onSwitchChanged(!betaTimelineValue), onTap: () => onSwitchChanged(!betaTimelineValue),
), ),

View File

@ -115,7 +115,7 @@ class PrimaryColorSetting extends HookConsumerWidget {
child: SwitchListTile.adaptive( child: SwitchListTile.adaptive(
contentPadding: const EdgeInsets.symmetric(vertical: 6, horizontal: 20), contentPadding: const EdgeInsets.symmetric(vertical: 6, horizontal: 20),
dense: true, dense: true,
activeColor: context.primaryColor, activeThumbColor: context.primaryColor,
tileColor: context.colorScheme.surfaceContainerHigh, tileColor: context.colorScheme.surfaceContainerHigh,
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(15))), shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(15))),
title: Text( title: Text(

View File

@ -9,7 +9,7 @@ class SettingsRadioGroup<T> {
} }
class SettingsRadioListTile<T> extends StatelessWidget { class SettingsRadioListTile<T> extends StatelessWidget {
final List<SettingsRadioGroup> groups; final List<SettingsRadioGroup<T>> groups;
final T groupBy; final T groupBy;
final void Function(T?) onRadioChanged; final void Function(T?) onRadioChanged;
@ -17,21 +17,23 @@ class SettingsRadioListTile<T> extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return RadioGroup(
children: groups groupValue: groupBy,
.map( onChanged: onRadioChanged,
(g) => RadioListTile<T>( child: Column(
contentPadding: const EdgeInsets.symmetric(horizontal: 20), children: groups
dense: true, .map(
activeColor: context.primaryColor, (g) => RadioListTile<T>(
title: Text(g.title, style: context.textTheme.bodyLarge?.copyWith(fontWeight: FontWeight.w500)), contentPadding: const EdgeInsets.symmetric(horizontal: 20),
value: g.value, dense: true,
groupValue: groupBy, activeColor: context.primaryColor,
onChanged: onRadioChanged, title: Text(g.title, style: context.textTheme.bodyLarge?.copyWith(fontWeight: FontWeight.w500)),
controlAffinity: ListTileControlAffinity.trailing, value: g.value,
), controlAffinity: ListTileControlAffinity.trailing,
) ),
.toList(), )
.toList(),
),
); );
} }
} }

View File

@ -40,7 +40,7 @@ class SettingsSwitchListTile extends StatelessWidget {
selectedTileColor: enabled ? null : context.themeData.disabledColor, selectedTileColor: enabled ? null : context.themeData.disabledColor,
value: valueNotifier.value, value: valueNotifier.value,
onChanged: onSwitchChanged, onChanged: onSwitchChanged,
activeColor: enabled ? context.primaryColor : context.themeData.disabledColor, activeThumbColor: enabled ? context.primaryColor : context.themeData.disabledColor,
dense: true, dense: true,
secondary: icon != null ? Icon(icon!, color: valueNotifier.value ? context.primaryColor : null) : null, secondary: icon != null ? Icon(icon!, color: valueNotifier.value ? context.primaryColor : null) : null,
title: Text( title: Text(

View File

@ -1064,26 +1064,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker name: leak_tracker
sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "10.0.9" version: "11.0.2"
leak_tracker_flutter_testing: leak_tracker_flutter_testing:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker_flutter_testing name: leak_tracker_flutter_testing
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.9" version: "3.0.10"
leak_tracker_testing: leak_tracker_testing:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker_testing name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.1" version: "3.0.2"
lints: lints:
dependency: transitive dependency: transitive
description: description:
@ -1877,10 +1877,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.4" version: "0.7.6"
thumbhash: thumbhash:
dependency: "direct main" dependency: "direct main"
description: description:
@ -2037,10 +2037,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.4" version: "2.2.0"
vm_service: vm_service:
dependency: transitive dependency: transitive
description: description:
@ -2171,4 +2171,4 @@ packages:
version: "3.1.3" version: "3.1.3"
sdks: sdks:
dart: ">=3.8.0 <4.0.0" dart: ">=3.8.0 <4.0.0"
flutter: ">=3.32.8" flutter: ">=3.35.3"

View File

@ -6,7 +6,7 @@ version: 1.142.1+3015
environment: environment:
sdk: '>=3.8.0 <4.0.0' sdk: '>=3.8.0 <4.0.0'
flutter: 3.32.8 flutter: 3.35.3
isar_version: &isar_version 3.1.8 isar_version: &isar_version 3.1.8

View File

@ -56,7 +56,7 @@ RUN if [ "$(dpkg --print-architecture)" = "arm64" ]; then \
# Flutter SDK # Flutter SDK
# https://flutter.dev/docs/development/tools/sdk/releases?tab=linux # https://flutter.dev/docs/development/tools/sdk/releases?tab=linux
ENV FLUTTER_CHANNEL="stable" ENV FLUTTER_CHANNEL="stable"
ENV FLUTTER_VERSION="3.32.8" ENV FLUTTER_VERSION="3.35.3"
ENV FLUTTER_HOME=/flutter ENV FLUTTER_HOME=/flutter
ENV PATH=${PATH}:${FLUTTER_HOME}/bin ENV PATH=${PATH}:${FLUTTER_HOME}/bin

View File

@ -9,7 +9,7 @@
"build:stats": "BUILD_STATS=true vite build", "build:stats": "BUILD_STATS=true vite build",
"package": "svelte-kit package", "package": "svelte-kit package",
"preview": "vite preview", "preview": "vite preview",
"check:svelte": "svelte-check --no-tsconfig --fail-on-warnings --compiler-warnings 'reactive_declaration_non_reactive_property:ignore' --ignore src/lib/components/timeline/Timeline.svelte", "check:svelte": "svelte-check --no-tsconfig --fail-on-warnings",
"check:typescript": "tsc --noEmit", "check:typescript": "tsc --noEmit",
"check:watch": "npm run check:svelte -- --watch", "check:watch": "npm run check:svelte -- --watch",
"check:code": "npm run format && npm run lint:p && npm run check:svelte && npm run check:typescript", "check:code": "npm run format && npm run lint:p && npm run check:svelte && npm run check:typescript",