mirror of
https://github.com/immich-app/immich.git
synced 2026-05-24 16:42:30 -04:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1cfd8adecf | |||
| 6769e61f09 | |||
| 47c6bd7fd4 |
@@ -230,6 +230,10 @@ jobs:
|
||||
- name: Generate platform APIs
|
||||
run: mise //mobile:codegen:pigeon
|
||||
|
||||
- name: Resolve iOS Swift Packages
|
||||
working-directory: ./mobile
|
||||
run: flutter build ios --config-only --no-codesign
|
||||
|
||||
- name: Setup Ruby
|
||||
uses: ruby/setup-ruby@6aaa311d81eba98ae12eaffbcb63296ace0efcde # v1.307.0
|
||||
with:
|
||||
|
||||
@@ -1,9 +1,31 @@
|
||||
# @generated - this file is auto-generated by `mise lock` https://mise.en.dev/dev-tools/mise-lock.html
|
||||
|
||||
[[tools."aqua:flutter/flutter"]]
|
||||
version = "3.41.9"
|
||||
version = "3.44.0"
|
||||
backend = "aqua:flutter/flutter"
|
||||
|
||||
[tools."aqua:flutter/flutter"."platforms.linux-arm64"]
|
||||
url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.44.0-stable.tar.xz"
|
||||
|
||||
[tools."aqua:flutter/flutter"."platforms.linux-arm64-musl"]
|
||||
url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.44.0-stable.tar.xz"
|
||||
|
||||
[tools."aqua:flutter/flutter"."platforms.linux-x64"]
|
||||
url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.44.0-stable.tar.xz"
|
||||
|
||||
[tools."aqua:flutter/flutter"."platforms.linux-x64-musl"]
|
||||
url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.44.0-stable.tar.xz"
|
||||
|
||||
[tools."aqua:flutter/flutter"."platforms.macos-arm64"]
|
||||
checksum = "blake3:fb03aa5d9790205c948922ec3f0751c16e4575b09d6ae9dd4fbeb664a69f0e00"
|
||||
url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/macos/flutter_macos_arm64_3.44.0-stable.zip"
|
||||
|
||||
[tools."aqua:flutter/flutter"."platforms.macos-x64"]
|
||||
url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/macos/flutter_macos_3.44.0-stable.zip"
|
||||
|
||||
[tools."aqua:flutter/flutter"."platforms.windows-x64"]
|
||||
url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/windows/flutter_windows_3.44.0-stable.zip"
|
||||
|
||||
[[tools.flutter]]
|
||||
version = "3.41.9-stable"
|
||||
backend = "asdf:flutter"
|
||||
|
||||
@@ -16,7 +16,7 @@ config_roots = [
|
||||
|
||||
[tools]
|
||||
node = "24.15.0"
|
||||
"aqua:flutter/flutter" = "3.41.9"
|
||||
"aqua:flutter/flutter" = "3.44.0"
|
||||
pnpm = "10.33.4"
|
||||
terragrunt = "1.0.3"
|
||||
opentofu = "1.11.6"
|
||||
|
||||
Vendored
-1
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"dart.flutterSdkPath": ".fvm/versions/3.41.9",
|
||||
"dart.lineLength": 120,
|
||||
"[dart]": {
|
||||
"editor.rulers": [
|
||||
|
||||
@@ -5,3 +5,7 @@ android.nonTransitiveRClass=false
|
||||
android.nonFinalResIds=false
|
||||
org.gradle.caching=true
|
||||
org.gradle.parallel=true
|
||||
# This builtInKotlin flag was added automatically by Flutter migrator
|
||||
android.builtInKotlin=false
|
||||
# This newDsl flag was added automatically by Flutter migrator
|
||||
android.newDsl=false
|
||||
|
||||
@@ -1,58 +1,23 @@
|
||||
PODS:
|
||||
- background_downloader (0.0.1):
|
||||
- Flutter
|
||||
- bonsoir_darwin (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- connectivity_plus (0.0.1):
|
||||
- Flutter
|
||||
- cupertino_http (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- device_info_plus (0.0.1):
|
||||
- Flutter
|
||||
- Flutter (1.0.0)
|
||||
- flutter_local_notifications (0.0.1):
|
||||
- Flutter
|
||||
- flutter_native_splash (2.4.3):
|
||||
- Flutter
|
||||
- flutter_secure_storage (6.0.0):
|
||||
- Flutter
|
||||
- flutter_udid (0.0.1):
|
||||
- Flutter
|
||||
- KeychainAccess
|
||||
- flutter_web_auth_2 (5.0.0):
|
||||
- Flutter
|
||||
- fluttertoast (0.0.2):
|
||||
- Flutter
|
||||
- geolocator_apple (1.2.0):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- home_widget (0.0.1):
|
||||
- Flutter
|
||||
- image_picker_ios (0.0.1):
|
||||
- Flutter
|
||||
- integration_test (0.0.1):
|
||||
- Flutter
|
||||
- KeychainAccess (4.2.2)
|
||||
- local_auth_darwin (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- MapLibre (6.14.0)
|
||||
- maplibre_gl (0.0.1):
|
||||
- Flutter
|
||||
- MapLibre (= 6.14.0)
|
||||
- native_video_player (1.0.0):
|
||||
- Flutter
|
||||
- network_info_plus (0.0.1):
|
||||
- Flutter
|
||||
- package_info_plus (0.4.5):
|
||||
- Flutter
|
||||
- permission_handler_apple (9.3.0):
|
||||
- Flutter
|
||||
- photo_manager (3.9.0):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- share_handler_ios (0.0.14):
|
||||
- Flutter
|
||||
- share_handler_ios/share_handler_ios_models (= 0.0.14)
|
||||
@@ -61,144 +26,56 @@ PODS:
|
||||
- Flutter
|
||||
- share_handler_ios_models
|
||||
- share_handler_ios_models (0.0.9)
|
||||
- share_plus (0.0.1):
|
||||
- Flutter
|
||||
- shared_preferences_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- url_launcher_ios (0.0.1):
|
||||
- Flutter
|
||||
- wakelock_plus (0.0.1):
|
||||
- Flutter
|
||||
|
||||
DEPENDENCIES:
|
||||
- background_downloader (from `.symlinks/plugins/background_downloader/ios`)
|
||||
- bonsoir_darwin (from `.symlinks/plugins/bonsoir_darwin/darwin`)
|
||||
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
||||
- cupertino_http (from `.symlinks/plugins/cupertino_http/darwin`)
|
||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
|
||||
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
||||
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
|
||||
- flutter_udid (from `.symlinks/plugins/flutter_udid/ios`)
|
||||
- flutter_web_auth_2 (from `.symlinks/plugins/flutter_web_auth_2/ios`)
|
||||
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
||||
- geolocator_apple (from `.symlinks/plugins/geolocator_apple/darwin`)
|
||||
- home_widget (from `.symlinks/plugins/home_widget/ios`)
|
||||
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
||||
- integration_test (from `.symlinks/plugins/integration_test/ios`)
|
||||
- local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`)
|
||||
- maplibre_gl (from `.symlinks/plugins/maplibre_gl/ios`)
|
||||
- native_video_player (from `.symlinks/plugins/native_video_player/ios`)
|
||||
- network_info_plus (from `.symlinks/plugins/network_info_plus/ios`)
|
||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||
- photo_manager (from `.symlinks/plugins/photo_manager/darwin`)
|
||||
- share_handler_ios (from `.symlinks/plugins/share_handler_ios/ios`)
|
||||
- share_handler_ios_models (from `.symlinks/plugins/share_handler_ios/ios/Models`)
|
||||
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- KeychainAccess
|
||||
- MapLibre
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
background_downloader:
|
||||
:path: ".symlinks/plugins/background_downloader/ios"
|
||||
bonsoir_darwin:
|
||||
:path: ".symlinks/plugins/bonsoir_darwin/darwin"
|
||||
connectivity_plus:
|
||||
:path: ".symlinks/plugins/connectivity_plus/ios"
|
||||
cupertino_http:
|
||||
:path: ".symlinks/plugins/cupertino_http/darwin"
|
||||
device_info_plus:
|
||||
:path: ".symlinks/plugins/device_info_plus/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_local_notifications:
|
||||
:path: ".symlinks/plugins/flutter_local_notifications/ios"
|
||||
flutter_native_splash:
|
||||
:path: ".symlinks/plugins/flutter_native_splash/ios"
|
||||
flutter_secure_storage:
|
||||
:path: ".symlinks/plugins/flutter_secure_storage/ios"
|
||||
flutter_udid:
|
||||
:path: ".symlinks/plugins/flutter_udid/ios"
|
||||
flutter_web_auth_2:
|
||||
:path: ".symlinks/plugins/flutter_web_auth_2/ios"
|
||||
fluttertoast:
|
||||
:path: ".symlinks/plugins/fluttertoast/ios"
|
||||
geolocator_apple:
|
||||
:path: ".symlinks/plugins/geolocator_apple/darwin"
|
||||
home_widget:
|
||||
:path: ".symlinks/plugins/home_widget/ios"
|
||||
image_picker_ios:
|
||||
:path: ".symlinks/plugins/image_picker_ios/ios"
|
||||
integration_test:
|
||||
:path: ".symlinks/plugins/integration_test/ios"
|
||||
local_auth_darwin:
|
||||
:path: ".symlinks/plugins/local_auth_darwin/darwin"
|
||||
maplibre_gl:
|
||||
:path: ".symlinks/plugins/maplibre_gl/ios"
|
||||
native_video_player:
|
||||
:path: ".symlinks/plugins/native_video_player/ios"
|
||||
network_info_plus:
|
||||
:path: ".symlinks/plugins/network_info_plus/ios"
|
||||
package_info_plus:
|
||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||
permission_handler_apple:
|
||||
:path: ".symlinks/plugins/permission_handler_apple/ios"
|
||||
photo_manager:
|
||||
:path: ".symlinks/plugins/photo_manager/darwin"
|
||||
share_handler_ios:
|
||||
:path: ".symlinks/plugins/share_handler_ios/ios"
|
||||
share_handler_ios_models:
|
||||
:path: ".symlinks/plugins/share_handler_ios/ios/Models"
|
||||
share_plus:
|
||||
:path: ".symlinks/plugins/share_plus/ios"
|
||||
shared_preferences_foundation:
|
||||
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
||||
url_launcher_ios:
|
||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||
wakelock_plus:
|
||||
:path: ".symlinks/plugins/wakelock_plus/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
background_downloader: 50e91d979067b82081aba359d7d916b3ba5fadad
|
||||
bonsoir_darwin: 29c7ccf356646118844721f36e1de4b61f6cbd0e
|
||||
connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
|
||||
cupertino_http: 94ac07f5ff090b8effa6c5e2c47871d48ab7c86c
|
||||
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
|
||||
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
|
||||
flutter_local_notifications: ad39620c743ea4c15127860f4b5641649a988100
|
||||
flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
|
||||
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
|
||||
flutter_udid: 92a5d31fe0526b7b6002a2318df702e12e7eb300
|
||||
flutter_web_auth_2: 646fc9df97a01c59e5eea99b237da2c6360f8439
|
||||
fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1
|
||||
geolocator_apple: ab36aa0e8b7d7a2d7639b3b4e48308394e8cef5e
|
||||
home_widget: f169fc41fd807b4d46ab6615dc44d62adbf9f64f
|
||||
image_picker_ios: e0ece4aa2a75771a7de3fa735d26d90817041326
|
||||
integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e
|
||||
KeychainAccess: c0c4f7f38f6fc7bbe58f5702e25f7bd2f65abf51
|
||||
local_auth_darwin: c3ee6cce0a8d56be34c8ccb66ba31f7f180aaebb
|
||||
MapLibre: 69e572367f4ef6287e18246cfafc39c80cdcabcd
|
||||
maplibre_gl: 3c924e44725147b03dda33430ad216005b40555f
|
||||
native_video_player: b65c58951ede2f93d103a25366bdebca95081265
|
||||
network_info_plus: cf61925ab5205dce05a4f0895989afdb6aade5fc
|
||||
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
|
||||
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
|
||||
photo_manager: 25fd77df14f4f0ba5ef99e2c61814dde77e2bceb
|
||||
share_handler_ios: e2244e990f826b2c8eaa291ac3831569438ba0fb
|
||||
share_handler_ios_models: fc638c9b4330dc7f082586c92aee9dfa0b87b871
|
||||
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
|
||||
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
|
||||
url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b
|
||||
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
|
||||
|
||||
PODFILE CHECKSUM: 938abbae4114b9c2140c550a2a0d8f7c674f5dfe
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
FEE084F82EC172460045228E /* SQLiteData in Frameworks */ = {isa = PBXBuildFile; productRef = FEE084F72EC172460045228E /* SQLiteData */; };
|
||||
FEE084FB2EC1725A0045228E /* RawStructuredFieldValues in Frameworks */ = {isa = PBXBuildFile; productRef = FEE084FA2EC1725A0045228E /* RawStructuredFieldValues */; };
|
||||
FEE084FD2EC1725A0045228E /* StructuredFieldValues in Frameworks */ = {isa = PBXBuildFile; productRef = FEE084FC2EC1725A0045228E /* StructuredFieldValues */; };
|
||||
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -129,6 +130,7 @@
|
||||
FE5499F72F1198DE006016CB /* RemoteImagesImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteImagesImpl.swift; sourceTree = "<group>"; };
|
||||
FE5FE4AD2F30FBC000A71243 /* ImageProcessing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageProcessing.swift; sourceTree = "<group>"; };
|
||||
FEAFA8722E4D42F4001E47FE /* Thumbhash.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Thumbhash.swift; sourceTree = "<group>"; };
|
||||
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||
@@ -193,6 +195,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */,
|
||||
FEE084F82EC172460045228E /* SQLiteData in Frameworks */,
|
||||
FEE084FB2EC1725A0045228E /* RawStructuredFieldValues in Frameworks */,
|
||||
FEE084FD2EC1725A0045228E /* StructuredFieldValues in Frameworks */,
|
||||
@@ -247,6 +250,7 @@
|
||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */,
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */,
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
|
||||
@@ -360,6 +364,9 @@
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
97C146ED1CF9000F007C117D /* Runner */ = {
|
||||
packageProductDependencies = (
|
||||
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */,
|
||||
);
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
@@ -463,6 +470,7 @@
|
||||
);
|
||||
mainGroup = 97C146E51CF9000F007C117D;
|
||||
packageReferences = (
|
||||
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */,
|
||||
FEE084F62EC172460045228E /* XCRemoteSwiftPackageReference "sqlite-data" */,
|
||||
FEE084F92EC1725A0045228E /* XCRemoteSwiftPackageReference "swift-http-structured-headers" */,
|
||||
);
|
||||
@@ -1285,7 +1293,17 @@
|
||||
package = FEE084F92EC1725A0045228E /* XCRemoteSwiftPackageReference "swift-http-structured-headers" */;
|
||||
productName = StructuredFieldValues;
|
||||
};
|
||||
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = FlutterGeneratedPluginSwiftPackage;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
/* Begin XCLocalSwiftPackageReference section */
|
||||
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = {
|
||||
isa = XCLocalSwiftPackageReference;
|
||||
relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage;
|
||||
};
|
||||
/* End XCLocalSwiftPackageReference section */
|
||||
};
|
||||
rootObject = 97C146E61CF9000F007C117D /* Project object */;
|
||||
}
|
||||
|
||||
+19
-2
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"originHash" : "9be33bfaa68721646604aefff3cabbdaf9a193da192aae024c265065671f6c49",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "combine-schedulers",
|
||||
@@ -19,6 +18,24 @@
|
||||
"version" : "7.8.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "keychainaccess",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/kishikawakatsumi/KeychainAccess",
|
||||
"state" : {
|
||||
"revision" : "84e546727d66f1adc5439debad16270d0fdd04e7",
|
||||
"version" : "4.2.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "maplibre-gl-native-distribution",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/maplibre/maplibre-gl-native-distribution.git",
|
||||
"state" : {
|
||||
"revision" : "60d9bb85c94ce6e7fc4406cd32529fd12bdb7809",
|
||||
"version" : "6.14.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "sqlite-data",
|
||||
"kind" : "remoteSourceControl",
|
||||
@@ -146,5 +163,5 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 3
|
||||
"version" : 2
|
||||
}
|
||||
|
||||
@@ -5,6 +5,24 @@
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<PreActions>
|
||||
<ExecutionAction
|
||||
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
|
||||
<ActionContent
|
||||
title = "Run Prepare Flutter Framework Script"
|
||||
scriptText = "/bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" prepare ">
|
||||
<EnvironmentBuildable>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Immich.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</EnvironmentBuildable>
|
||||
</ActionContent>
|
||||
</ExecutionAction>
|
||||
</PreActions>
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"originHash" : "9be33bfaa68721646604aefff3cabbdaf9a193da192aae024c265065671f6c49",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "combine-schedulers",
|
||||
@@ -19,6 +18,24 @@
|
||||
"version" : "7.9.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "keychainaccess",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/kishikawakatsumi/KeychainAccess",
|
||||
"state" : {
|
||||
"revision" : "84e546727d66f1adc5439debad16270d0fdd04e7",
|
||||
"version" : "4.2.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "maplibre-gl-native-distribution",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/maplibre/maplibre-gl-native-distribution.git",
|
||||
"state" : {
|
||||
"revision" : "60d9bb85c94ce6e7fc4406cd32529fd12bdb7809",
|
||||
"version" : "6.14.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "sqlite-data",
|
||||
"kind" : "remoteSourceControl",
|
||||
@@ -146,5 +163,5 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 3
|
||||
"version" : 2
|
||||
}
|
||||
|
||||
@@ -8,11 +8,7 @@ class AssetService {
|
||||
final RemoteAssetRepository _remoteAssetRepository;
|
||||
final DriftLocalAssetRepository _localAssetRepository;
|
||||
|
||||
const AssetService({
|
||||
required RemoteAssetRepository remoteAssetRepository,
|
||||
required DriftLocalAssetRepository localAssetRepository,
|
||||
}) : _remoteAssetRepository = remoteAssetRepository,
|
||||
_localAssetRepository = localAssetRepository;
|
||||
const AssetService({required this._remoteAssetRepository, required this._localAssetRepository});
|
||||
|
||||
Future<BaseAsset?> getAsset(BaseAsset asset) {
|
||||
final id = asset is LocalAsset ? asset.id : (asset as RemoteAsset).id;
|
||||
|
||||
@@ -61,11 +61,9 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi {
|
||||
|
||||
bool _isCleanedUp = false;
|
||||
|
||||
BackgroundWorkerBgService({required Drift drift, required DriftLogger driftLogger})
|
||||
: _drift = drift,
|
||||
_driftLogger = driftLogger,
|
||||
_backgroundHostApi = BackgroundWorkerBgHostApi() {
|
||||
_ref = ProviderContainer(overrides: [driftProvider.overrideWith(driftOverride(drift))]);
|
||||
BackgroundWorkerBgService({required this._drift, required this._driftLogger})
|
||||
: _backgroundHostApi = BackgroundWorkerBgHostApi() {
|
||||
_ref = ProviderContainer(overrides: [driftProvider.overrideWith(driftOverride(_drift))]);
|
||||
BackgroundWorkerFlutterApi.setUp(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,18 +21,13 @@ class HashService {
|
||||
final _log = Logger('HashService');
|
||||
|
||||
HashService({
|
||||
required DriftLocalAlbumRepository localAlbumRepository,
|
||||
required DriftLocalAssetRepository localAssetRepository,
|
||||
required DriftTrashedLocalAssetRepository trashedLocalAssetRepository,
|
||||
required NativeSyncApi nativeSyncApi,
|
||||
bool Function()? cancelChecker,
|
||||
required this._localAlbumRepository,
|
||||
required this._localAssetRepository,
|
||||
required this._trashedLocalAssetRepository,
|
||||
required this._nativeSyncApi,
|
||||
this._cancelChecker,
|
||||
int? batchSize,
|
||||
}) : _localAlbumRepository = localAlbumRepository,
|
||||
_localAssetRepository = localAssetRepository,
|
||||
_trashedLocalAssetRepository = trashedLocalAssetRepository,
|
||||
_cancelChecker = cancelChecker,
|
||||
_nativeSyncApi = nativeSyncApi,
|
||||
_batchSize = batchSize ?? kBatchHashFileLimit;
|
||||
}) : _batchSize = batchSize ?? kBatchHashFileLimit;
|
||||
|
||||
bool get isCancelled => _cancelChecker?.call() ?? false;
|
||||
|
||||
|
||||
@@ -28,18 +28,13 @@ class LocalSyncService {
|
||||
final Logger _log = Logger("DeviceSyncService");
|
||||
|
||||
LocalSyncService({
|
||||
required DriftLocalAlbumRepository localAlbumRepository,
|
||||
required DriftLocalAssetRepository localAssetRepository,
|
||||
required DriftTrashedLocalAssetRepository trashedLocalAssetRepository,
|
||||
required AssetMediaRepository assetMediaRepository,
|
||||
required IPermissionRepository permissionRepository,
|
||||
required NativeSyncApi nativeSyncApi,
|
||||
}) : _localAlbumRepository = localAlbumRepository,
|
||||
_localAssetRepository = localAssetRepository,
|
||||
_trashedLocalAssetRepository = trashedLocalAssetRepository,
|
||||
_assetMediaRepository = assetMediaRepository,
|
||||
_permissionRepository = permissionRepository,
|
||||
_nativeSyncApi = nativeSyncApi;
|
||||
required this._localAlbumRepository,
|
||||
required this._localAssetRepository,
|
||||
required this._nativeSyncApi,
|
||||
required this._trashedLocalAssetRepository,
|
||||
required this._assetMediaRepository,
|
||||
required this._permissionRepository,
|
||||
});
|
||||
|
||||
Future<void> sync({bool full = false}) async {
|
||||
final Stopwatch stopwatch = Stopwatch()..start();
|
||||
|
||||
@@ -10,7 +10,7 @@ typedef MapQuery = ({MapMarkerSource markerSource});
|
||||
class MapFactory {
|
||||
final DriftMapRepository _mapRepository;
|
||||
|
||||
const MapFactory({required DriftMapRepository mapRepository}) : _mapRepository = mapRepository;
|
||||
const MapFactory({required this._mapRepository});
|
||||
|
||||
MapService remote(List<String> ownerIds, TimelineMapOptions options) =>
|
||||
MapService(_mapRepository.remote(ownerIds, options));
|
||||
|
||||
@@ -9,7 +9,7 @@ final AppSetting = SettingsService(storeService: StoreService.I);
|
||||
class SettingsService {
|
||||
final StoreService _storeService;
|
||||
|
||||
const SettingsService({required StoreService storeService}) : _storeService = storeService;
|
||||
const SettingsService({required this._storeService});
|
||||
|
||||
T get<T>(Setting<T> setting) => _storeService.get(setting.storeKey, setting.defaultValue);
|
||||
|
||||
|
||||
@@ -41,24 +41,16 @@ class SyncStreamService {
|
||||
final bool Function()? _cancelChecker;
|
||||
|
||||
SyncStreamService({
|
||||
required SyncApiRepository syncApiRepository,
|
||||
required SyncStreamRepository syncStreamRepository,
|
||||
required DriftLocalAssetRepository localAssetRepository,
|
||||
required DriftTrashedLocalAssetRepository trashedLocalAssetRepository,
|
||||
required AssetMediaRepository assetMediaRepository,
|
||||
required IPermissionRepository permissionRepository,
|
||||
required SyncMigrationRepository syncMigrationRepository,
|
||||
required ApiService api,
|
||||
bool Function()? cancelChecker,
|
||||
}) : _syncApiRepository = syncApiRepository,
|
||||
_syncStreamRepository = syncStreamRepository,
|
||||
_localAssetRepository = localAssetRepository,
|
||||
_trashedLocalAssetRepository = trashedLocalAssetRepository,
|
||||
_assetMediaRepository = assetMediaRepository,
|
||||
_permissionRepository = permissionRepository,
|
||||
_syncMigrationRepository = syncMigrationRepository,
|
||||
_api = api,
|
||||
_cancelChecker = cancelChecker;
|
||||
required this._syncApiRepository,
|
||||
required this._syncStreamRepository,
|
||||
required this._localAssetRepository,
|
||||
required this._trashedLocalAssetRepository,
|
||||
required this._assetMediaRepository,
|
||||
required this._permissionRepository,
|
||||
required this._syncMigrationRepository,
|
||||
required this._api,
|
||||
this._cancelChecker,
|
||||
});
|
||||
|
||||
bool get isCancelled => _cancelChecker?.call() ?? false;
|
||||
|
||||
|
||||
@@ -41,11 +41,7 @@ class TimelineFactory {
|
||||
final DriftTimelineRepository _timelineRepository;
|
||||
final MetadataRepository _metadataRepository;
|
||||
|
||||
const TimelineFactory({
|
||||
required DriftTimelineRepository timelineRepository,
|
||||
required MetadataRepository metadataRepository,
|
||||
}) : _timelineRepository = timelineRepository,
|
||||
_metadataRepository = metadataRepository;
|
||||
const TimelineFactory({required this._timelineRepository, required this._metadataRepository});
|
||||
|
||||
GroupAssetsBy get groupBy {
|
||||
final group = _metadataRepository.appConfig.timeline.groupAssetsBy;
|
||||
@@ -108,12 +104,7 @@ class TimelineService {
|
||||
TimelineService(TimelineQuery query)
|
||||
: this._(assetSource: query.assetSource, bucketSource: query.bucketSource, origin: query.origin);
|
||||
|
||||
TimelineService._({
|
||||
required TimelineAssetSource assetSource,
|
||||
required TimelineBucketSource bucketSource,
|
||||
required this.origin,
|
||||
}) : _assetSource = assetSource,
|
||||
_bucketSource = bucketSource {
|
||||
TimelineService._({required this._assetSource, required this._bucketSource, required this.origin}) {
|
||||
_bucketSubscription = _bucketSource().listen((buckets) {
|
||||
_mutex.run(() async {
|
||||
final totalAssets = buckets.fold<int>(0, (acc, bucket) => acc + bucket.assetCount);
|
||||
|
||||
@@ -12,9 +12,7 @@ class UserService {
|
||||
final UserApiRepository _userApiRepository;
|
||||
final StoreService _storeService;
|
||||
|
||||
UserService({required UserApiRepository userApiRepository, required StoreService storeService})
|
||||
: _userApiRepository = userApiRepository,
|
||||
_storeService = storeService;
|
||||
UserService({required this._userApiRepository, required this._storeService});
|
||||
|
||||
UserDto getMyUser() {
|
||||
return _storeService.get(StoreKey.currentUser);
|
||||
|
||||
@@ -296,16 +296,12 @@ class _ThumbnailRenderBox extends RenderBox {
|
||||
bool isRepaintBoundary = true;
|
||||
|
||||
_ThumbnailRenderBox({
|
||||
required ui.Image? image,
|
||||
required ui.Image? previousImage,
|
||||
required double fadeValue,
|
||||
required BoxFit fit,
|
||||
required Gradient placeholderGradient,
|
||||
}) : _image = image,
|
||||
_previousImage = previousImage,
|
||||
_fadeValue = fadeValue,
|
||||
_fit = fit,
|
||||
_placeholderGradient = placeholderGradient;
|
||||
required this._image,
|
||||
required this._previousImage,
|
||||
required this._fadeValue,
|
||||
required this._fit,
|
||||
required this._placeholderGradient,
|
||||
});
|
||||
|
||||
@override
|
||||
void paint(PaintingContext context, Offset offset) {
|
||||
|
||||
@@ -62,14 +62,11 @@ class RenderFixedRow extends RenderBox
|
||||
RenderBoxContainerDefaultsMixin<RenderBox, _RowParentData> {
|
||||
RenderFixedRow({
|
||||
List<RenderBox>? children,
|
||||
required double height,
|
||||
required List<double> widths,
|
||||
required double spacing,
|
||||
required TextDirection textDirection,
|
||||
}) : _height = height,
|
||||
_widths = widths,
|
||||
_spacing = spacing,
|
||||
_textDirection = textDirection {
|
||||
required this._height,
|
||||
required this._widths,
|
||||
required this._spacing,
|
||||
required this._textDirection,
|
||||
}) {
|
||||
addAll(children);
|
||||
}
|
||||
|
||||
|
||||
@@ -578,9 +578,7 @@ class _SlideFadeTransition extends StatelessWidget {
|
||||
final Animation<double> _animation;
|
||||
final Widget _child;
|
||||
|
||||
const _SlideFadeTransition({required Animation<double> animation, required Widget child})
|
||||
: _animation = animation,
|
||||
_child = child;
|
||||
const _SlideFadeTransition({required this._animation, required this._child});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
@@ -397,7 +397,7 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> {
|
||||
final grid = CustomScrollView(
|
||||
primary: true,
|
||||
physics: _scrollPhysics,
|
||||
cacheExtent: maxHeight * 2,
|
||||
scrollCacheExtent: .pixels(maxHeight * 2),
|
||||
slivers: [
|
||||
if (isSelectionMode) const SelectionSliverAppBar() else if (widget.appBar != null) widget.appBar!,
|
||||
if (widget.topSliverWidget != null) widget.topSliverWidget!,
|
||||
@@ -503,7 +503,7 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> {
|
||||
class _SliverSegmentedList extends SliverMultiBoxAdaptorWidget {
|
||||
final List<Segment> _segments;
|
||||
|
||||
const _SliverSegmentedList({required List<Segment> segments, required super.delegate}) : _segments = segments;
|
||||
const _SliverSegmentedList({required this._segments, required super.delegate});
|
||||
|
||||
@override
|
||||
_RenderSliverTimelineBoxAdaptor createRenderObject(BuildContext context) =>
|
||||
@@ -527,8 +527,7 @@ class _RenderSliverTimelineBoxAdaptor extends RenderSliverMultiBoxAdaptor {
|
||||
markNeedsLayout();
|
||||
}
|
||||
|
||||
_RenderSliverTimelineBoxAdaptor({required super.childManager, required List<Segment> segments})
|
||||
: _segments = segments;
|
||||
_RenderSliverTimelineBoxAdaptor({required super.childManager, required this._segments});
|
||||
|
||||
int getMinChildIndexForScrollOffset(double offset) =>
|
||||
_segments.findByOffset(offset)?.getMinChildIndexForScrollOffset(offset) ?? 0;
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:immich_mobile/constants/locales.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
||||
import 'package:immich_mobile/services/localization.service.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
import 'package:immich_mobile/widgets/common/search_field.dart';
|
||||
|
||||
class LanguageSettings extends HookConsumerWidget {
|
||||
@@ -84,7 +85,7 @@ class LanguageSettings extends HookConsumerWidget {
|
||||
padding: const EdgeInsets.all(8),
|
||||
itemCount: filteredLocaleEntries.value.length,
|
||||
itemExtent: 64.0,
|
||||
cacheExtent: 100,
|
||||
scrollCacheExtent: const .pixels(100),
|
||||
itemBuilder: (context, index) {
|
||||
final countryName = filteredLocaleEntries.value[index].key;
|
||||
final localeValue = filteredLocaleEntries.value[index].value;
|
||||
|
||||
@@ -36,10 +36,6 @@ class ExternalNetworkPreference extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
handleReorder(int oldIndex, int newIndex) {
|
||||
if (oldIndex < newIndex) {
|
||||
newIndex -= 1;
|
||||
}
|
||||
|
||||
final entry = entries.value.removeAt(oldIndex);
|
||||
entries.value.insert(newIndex, entry);
|
||||
entries.value = [...entries.value];
|
||||
@@ -113,7 +109,7 @@ class ExternalNetworkPreference extends HookConsumerWidget {
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: entries.value.length,
|
||||
onReorder: handleReorder,
|
||||
onReorderItem: handleReorder,
|
||||
itemBuilder: (context, index) {
|
||||
return EndpointInput(
|
||||
key: Key(index.toString()),
|
||||
|
||||
+12
-12
@@ -5,18 +5,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: "8d7ff3948166b8ec5da0fbb5962000926b8e02f2ed9b3e51d1738905fbd4c98d"
|
||||
sha256: "3b19a47f6ea7c2632760777c78174f47f6aec1e05f0cd611380d4593b8af1dbc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "93.0.0"
|
||||
version: "96.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: de7148ed2fcec579b19f122c1800933dfa028f6d9fd38a152b04b1516cec120b
|
||||
sha256: "0c516bc4ad36a1a75759e54d5047cb9d15cded4459df01aa35a0b5ec7db2c2a0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.1"
|
||||
version: "10.2.0"
|
||||
ansicolor:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1088,10 +1088,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
||||
sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
version: "1.18.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1719,10 +1719,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
|
||||
sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.10"
|
||||
version: "0.7.11"
|
||||
thumbhash:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -1775,10 +1775,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_android
|
||||
sha256: "3bb000251e55d4a209aa0e2e563309dc9bb2befea2295fd0cec1f51760aac572"
|
||||
sha256: "17bc677f0b301615530dd1d67e0a9828cafa2d0b6b6eae4cd3679b7eac4a273c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.29"
|
||||
version: "6.3.30"
|
||||
url_launcher_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1996,5 +1996,5 @@ packages:
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.11.0 <4.0.0"
|
||||
flutter: "3.41.9"
|
||||
dart: ">=3.12.0 <4.0.0"
|
||||
flutter: "3.44.0"
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@ publish_to: 'none'
|
||||
version: 3.0.0+3047
|
||||
|
||||
environment:
|
||||
sdk: '>=3.11.0 <4.0.0'
|
||||
flutter: 3.41.9
|
||||
sdk: '>=3.12.0 <4.0.0'
|
||||
flutter: 3.44.0
|
||||
|
||||
dependencies:
|
||||
async: ^2.13.1
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { TimelineAsset } from '$lib/managers/timeline-manager/types';
|
||||
import { filterIsInOrNearViewport } from '$lib/managers/timeline-manager/utils.svelte';
|
||||
import type { ViewerAsset } from '$lib/managers/timeline-manager/viewer-asset.svelte';
|
||||
import type { VirtualScrollManager } from '$lib/managers/VirtualScrollManager/VirtualScrollManager.svelte';
|
||||
import { uploadAssetsStore } from '$lib/stores/upload';
|
||||
@@ -12,8 +13,6 @@
|
||||
|
||||
type Props = {
|
||||
viewerAssets: ViewerAsset[];
|
||||
firstInOrNearIndex: number;
|
||||
lastInOrNearIndex: number;
|
||||
width: number;
|
||||
height: number;
|
||||
manager: VirtualScrollManager;
|
||||
@@ -28,27 +27,15 @@
|
||||
customThumbnailLayout?: Snippet<[asset: TimelineAsset]>;
|
||||
};
|
||||
|
||||
const {
|
||||
viewerAssets,
|
||||
firstInOrNearIndex,
|
||||
lastInOrNearIndex,
|
||||
width,
|
||||
height,
|
||||
manager,
|
||||
thumbnail,
|
||||
customThumbnailLayout,
|
||||
}: Props = $props();
|
||||
const { viewerAssets, width, height, manager, thumbnail, customThumbnailLayout }: Props = $props();
|
||||
|
||||
const transitionDuration = $derived(manager.suspendTransitions && !$isUploading ? 0 : 150);
|
||||
const scaleDuration = $derived(transitionDuration === 0 ? 0 : transitionDuration + 100);
|
||||
const visibleViewerAssets = $derived(
|
||||
firstInOrNearIndex === -1 ? [] : viewerAssets.slice(firstInOrNearIndex, lastInOrNearIndex + 1),
|
||||
);
|
||||
</script>
|
||||
|
||||
<!-- Image grid -->
|
||||
<div data-image-grid class="relative overflow-clip" style:height={height + 'px'} style:width={width + 'px'}>
|
||||
{#each visibleViewerAssets as viewerAsset (viewerAsset.id)}
|
||||
{#each filterIsInOrNearViewport(viewerAssets) as viewerAsset (viewerAsset.id)}
|
||||
{@const position = viewerAsset.position!}
|
||||
{@const asset = viewerAsset.asset!}
|
||||
|
||||
|
||||
@@ -101,8 +101,6 @@
|
||||
<AssetLayout
|
||||
{manager}
|
||||
viewerAssets={timelineDay.viewerAssets}
|
||||
firstInOrNearIndex={timelineDay.firstInOrNearIndex}
|
||||
lastInOrNearIndex={timelineDay.lastInOrNearIndex}
|
||||
height={timelineDay.height}
|
||||
width={timelineDay.width}
|
||||
{customThumbnailLayout}
|
||||
|
||||
@@ -54,3 +54,16 @@ export function updateTimelineMonthViewportProximity(timelineManager: TimelineMa
|
||||
}
|
||||
}
|
||||
|
||||
export function calculateViewerAssetViewportProximity(
|
||||
timelineManager: TimelineManager,
|
||||
positionTop: number,
|
||||
positionHeight: number,
|
||||
) {
|
||||
const headerHeight = timelineManager.headerHeight;
|
||||
return calculateViewportProximity(
|
||||
positionTop,
|
||||
positionTop + positionHeight,
|
||||
timelineManager.visibleWindow.top - headerHeight,
|
||||
timelineManager.visibleWindow.bottom + headerHeight,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,15 +3,10 @@ import { SvelteSet } from 'svelte/reactivity';
|
||||
import type { CommonLayoutOptions } from '$lib/utils/layout-utils';
|
||||
import { getJustifiedLayoutFromAssets } from '$lib/utils/layout-utils';
|
||||
import { getOrderingDate, plainDateTimeCompare } from '$lib/utils/timeline-util';
|
||||
import { TUNABLES } from '$lib/utils/tunables';
|
||||
import type { TimelineMonth } from './timeline-month.svelte';
|
||||
import type { Direction, MoveAsset, TimelineAsset } from './types';
|
||||
import { ViewerAsset } from './viewer-asset.svelte';
|
||||
|
||||
const {
|
||||
TIMELINE: { INTERSECTION_EXPAND_TOP, INTERSECTION_EXPAND_BOTTOM },
|
||||
} = TUNABLES;
|
||||
|
||||
export class TimelineDay {
|
||||
readonly timelineMonth: TimelineMonth;
|
||||
readonly index: number;
|
||||
@@ -22,12 +17,7 @@ export class TimelineDay {
|
||||
|
||||
height = $state(0);
|
||||
width = $state(0);
|
||||
|
||||
// Indices into viewerAssets bounding the in-or-near range. -1/-1 means no assets are in-or-near.
|
||||
// Updated imperatively by updateAssetBoundaries() from updateViewportProximities() and layout().
|
||||
firstInOrNearIndex = $state(-1);
|
||||
lastInOrNearIndex = $state(-1);
|
||||
isInOrNearViewport = $derived(this.firstInOrNearIndex !== -1);
|
||||
isInOrNearViewport = $derived.by(() => this.viewerAssets.some((viewAsset) => viewAsset.isInOrNearViewport));
|
||||
|
||||
#top: number = $state(0);
|
||||
#start: number = $state(0);
|
||||
@@ -159,73 +149,6 @@ export class TimelineDay {
|
||||
for (let i = 0; i < this.viewerAssets.length; i++) {
|
||||
this.viewerAssets[i].position = geometry.getPosition(i);
|
||||
}
|
||||
this.updateAssetBoundaries();
|
||||
}
|
||||
|
||||
// Imperatively (re)computes firstInOrNearIndex / lastInOrNearIndex via binary search on
|
||||
// asset positions. Called from layout() (positions changed) and from
|
||||
// updateViewportProximities() (viewport changed). Cost: O(log N) per day instead of the
|
||||
// O(N) per-asset $derived recompute that the reactive equivalent would do.
|
||||
updateAssetBoundaries() {
|
||||
const manager = this.timelineMonth.timelineManager;
|
||||
const visibleWindow = manager.visibleWindow;
|
||||
if (this.viewerAssets.length === 0 || !this.viewerAssets[0].position) {
|
||||
this.firstInOrNearIndex = -1;
|
||||
this.lastInOrNearIndex = -1;
|
||||
return;
|
||||
}
|
||||
// Match the asset-level proximity zone from calculateViewerAssetViewportProximity:
|
||||
// window is expanded by headerHeight on both sides, then by INTERSECTION_EXPAND_*
|
||||
// for the "near" band. Combined: the in-or-near zone reaches headerHeight + EXPAND
|
||||
// beyond the visible window on each side.
|
||||
const headerHeight = manager.headerHeight;
|
||||
const dayOffset = this.absoluteTimelineDayTop;
|
||||
const localExpandedTop = visibleWindow.top - headerHeight - INTERSECTION_EXPAND_TOP - dayOffset;
|
||||
const localExpandedBottom = visibleWindow.bottom + headerHeight + INTERSECTION_EXPAND_BOTTOM - dayOffset;
|
||||
|
||||
// Lower bound: smallest i where asset[i].bottom >= localExpandedTop
|
||||
// (asset's bottom edge is at or below the in-or-near top boundary).
|
||||
let lo = 0;
|
||||
let hi = this.viewerAssets.length;
|
||||
while (lo < hi) {
|
||||
const mid = (lo + hi) >>> 1;
|
||||
const position = this.viewerAssets[mid].position!;
|
||||
if (position.top + position.height < localExpandedTop) {
|
||||
lo = mid + 1;
|
||||
} else {
|
||||
hi = mid;
|
||||
}
|
||||
}
|
||||
const firstIdx = lo;
|
||||
|
||||
if (firstIdx >= this.viewerAssets.length) {
|
||||
// Entire day is above the in-or-near zone.
|
||||
this.firstInOrNearIndex = -1;
|
||||
this.lastInOrNearIndex = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Upper bound: smallest i where asset[i].top >= localExpandedBottom
|
||||
// (asset's top edge crosses past the in-or-near bottom boundary).
|
||||
lo = firstIdx;
|
||||
hi = this.viewerAssets.length;
|
||||
while (lo < hi) {
|
||||
const mid = (lo + hi) >>> 1;
|
||||
if (this.viewerAssets[mid].position!.top >= localExpandedBottom) {
|
||||
hi = mid;
|
||||
} else {
|
||||
lo = mid + 1;
|
||||
}
|
||||
}
|
||||
const lastIdx = lo - 1;
|
||||
|
||||
if (lastIdx < firstIdx) {
|
||||
this.firstInOrNearIndex = -1;
|
||||
this.lastInOrNearIndex = -1;
|
||||
} else {
|
||||
this.firstInOrNearIndex = firstIdx;
|
||||
this.lastInOrNearIndex = lastIdx;
|
||||
}
|
||||
}
|
||||
|
||||
get absoluteTimelineDayTop() {
|
||||
|
||||
@@ -214,11 +214,6 @@ export class TimelineManager extends VirtualScrollManager {
|
||||
|
||||
for (const month of this.months) {
|
||||
updateTimelineMonthViewportProximity(this, month);
|
||||
if (month.isInOrNearViewport && month.isLoaded) {
|
||||
for (const day of month.timelineDays) {
|
||||
day.updateAssetBoundaries();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const month = this.months.find((month) => month.isInViewport);
|
||||
|
||||
@@ -254,7 +254,7 @@ export class TimelineMonth {
|
||||
addContext.newTimelineDays.add(timelineDay);
|
||||
}
|
||||
|
||||
const viewerAsset = new ViewerAsset(timelineAsset);
|
||||
const viewerAsset = new ViewerAsset(timelineDay, timelineAsset);
|
||||
timelineDay.viewerAssets.push(viewerAsset);
|
||||
addContext.changedTimelineDays.add(timelineDay);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,36 @@
|
||||
import type { CommonPosition } from '$lib/utils/layout-utils';
|
||||
import {
|
||||
ViewportProximity,
|
||||
calculateViewerAssetViewportProximity,
|
||||
isInOrNearViewport,
|
||||
} from './internal/intersection-support.svelte';
|
||||
import type { TimelineDay } from './timeline-day.svelte';
|
||||
import type { TimelineAsset } from './types';
|
||||
|
||||
export class ViewerAsset {
|
||||
readonly #group: TimelineDay;
|
||||
|
||||
#viewportProximity = $derived.by(() => {
|
||||
if (!this.position) {
|
||||
return ViewportProximity.FarFromViewport;
|
||||
}
|
||||
|
||||
const store = this.#group.timelineMonth.timelineManager;
|
||||
const positionTop = this.#group.absoluteTimelineDayTop + this.position.top;
|
||||
|
||||
return calculateViewerAssetViewportProximity(store, positionTop, this.position.height);
|
||||
});
|
||||
|
||||
get isInOrNearViewport() {
|
||||
return isInOrNearViewport(this.#viewportProximity);
|
||||
}
|
||||
|
||||
position: CommonPosition | undefined = $state.raw();
|
||||
asset: TimelineAsset = $state() as TimelineAsset;
|
||||
id: string = $derived(this.asset.id);
|
||||
|
||||
constructor(asset: TimelineAsset) {
|
||||
constructor(group: TimelineDay, asset: TimelineAsset) {
|
||||
this.#group = group;
|
||||
this.asset = asset;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user