mirror of
https://github.com/immich-app/immich.git
synced 2025-12-17 01:57:50 -08:00
Compare commits
46 Commits
v1.135.2
...
feat/widge
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97329d488b | ||
|
|
c6cd4dce78 | ||
|
|
0a90f490f2 | ||
|
|
88e008c4c2 | ||
|
|
99a9914da2 | ||
|
|
1923f1a887 | ||
|
|
ce14324c97 | ||
|
|
6a309129b7 | ||
|
|
bcb1bf4692 | ||
|
|
7f89999abe | ||
|
|
813186e618 | ||
|
|
20d9204ada | ||
|
|
3a9e79a452 | ||
|
|
03966146fe | ||
|
|
ecc58a8971 | ||
|
|
c705a7b280 | ||
|
|
ef278b4fb0 | ||
|
|
4cd633dc68 | ||
|
|
a18c6fa910 | ||
|
|
90aa0dc14d | ||
|
|
ce8c80dad0 | ||
|
|
81eb98d4e5 | ||
|
|
2b03802e9c | ||
|
|
484311e9bb | ||
|
|
366539bc4c | ||
|
|
69b1331026 | ||
|
|
af30d97668 | ||
|
|
9b047d30e4 | ||
|
|
6a5597b36b | ||
|
|
c10b795e99 | ||
|
|
b606d4fe73 | ||
|
|
4c2ad44303 | ||
|
|
698d3004b4 | ||
|
|
fe4d6edbdc | ||
|
|
798debfde3 | ||
|
|
6563fa608a | ||
|
|
1a90fc8e58 | ||
|
|
c707f9cef4 | ||
|
|
6fda863c08 | ||
|
|
373b654156 | ||
|
|
a5d84ba552 | ||
|
|
1dc8fa2979 | ||
|
|
0426699f13 | ||
|
|
8154ec29df | ||
|
|
3024cd343b | ||
|
|
0b44d4b6f2 |
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -461,7 +461,7 @@ jobs:
|
|||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Install Playwright Browsers
|
- name: Install Playwright Browsers
|
||||||
run: npx playwright install --with-deps chromium
|
run: npx playwright install chromium --only-shell
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
|
||||||
- name: Docker build
|
- name: Docker build
|
||||||
|
|||||||
6
cli/package-lock.json
generated
6
cli/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@immich/cli",
|
"name": "@immich/cli",
|
||||||
"version": "2.2.71",
|
"version": "2.2.72",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@immich/cli",
|
"name": "@immich/cli",
|
||||||
"version": "2.2.71",
|
"version": "2.2.72",
|
||||||
"license": "GNU Affero General Public License version 3",
|
"license": "GNU Affero General Public License version 3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chokidar": "^4.0.3",
|
"chokidar": "^4.0.3",
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
},
|
},
|
||||||
"../open-api/typescript-sdk": {
|
"../open-api/typescript-sdk": {
|
||||||
"name": "@immich/sdk",
|
"name": "@immich/sdk",
|
||||||
"version": "1.135.2",
|
"version": "1.135.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "GNU Affero General Public License version 3",
|
"license": "GNU Affero General Public License version 3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@immich/cli",
|
"name": "@immich/cli",
|
||||||
"version": "2.2.71",
|
"version": "2.2.72",
|
||||||
"description": "Command Line Interface (CLI) for Immich",
|
"description": "Command Line Interface (CLI) for Immich",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": "./dist/index.js",
|
"exports": "./dist/index.js",
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ alt="Dot Env Example"
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
- Change the default `DB_PASSWORD`, and add custom database connection information if necessary.
|
- Change the default `DB_PASSWORD`, and add custom database connection information if necessary.
|
||||||
- Change `DB_DATA_LOCATION` to a folder where the database will be saved to disk.
|
- Change `DB_DATA_LOCATION` to a folder (absolute path) where the database will be saved to disk.
|
||||||
- Change `UPLOAD_LOCATION` to a folder where media (uploaded and generated) will be stored.
|
- Change `UPLOAD_LOCATION` to a folder (absolute path) where media (uploaded and generated) will be stored.
|
||||||
|
|
||||||
11. Click on "**Deploy the stack**".
|
11. Click on "**Deploy the stack**".
|
||||||
|
|
||||||
|
|||||||
4
docs/static/archived-versions.json
vendored
4
docs/static/archived-versions.json
vendored
@@ -1,4 +1,8 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"label": "v1.135.3",
|
||||||
|
"url": "https://v1.135.3.archive.immich.app"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "v1.135.2",
|
"label": "v1.135.2",
|
||||||
"url": "https://v1.135.2.archive.immich.app"
|
"url": "https://v1.135.2.archive.immich.app"
|
||||||
|
|||||||
8
e2e/package-lock.json
generated
8
e2e/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "immich-e2e",
|
"name": "immich-e2e",
|
||||||
"version": "1.135.2",
|
"version": "1.135.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "immich-e2e",
|
"name": "immich-e2e",
|
||||||
"version": "1.135.2",
|
"version": "1.135.3",
|
||||||
"license": "GNU Affero General Public License version 3",
|
"license": "GNU Affero General Public License version 3",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "^3.1.0",
|
"@eslint/eslintrc": "^3.1.0",
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
},
|
},
|
||||||
"../cli": {
|
"../cli": {
|
||||||
"name": "@immich/cli",
|
"name": "@immich/cli",
|
||||||
"version": "2.2.71",
|
"version": "2.2.72",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "GNU Affero General Public License version 3",
|
"license": "GNU Affero General Public License version 3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -93,7 +93,7 @@
|
|||||||
},
|
},
|
||||||
"../open-api/typescript-sdk": {
|
"../open-api/typescript-sdk": {
|
||||||
"name": "@immich/sdk",
|
"name": "@immich/sdk",
|
||||||
"version": "1.135.2",
|
"version": "1.135.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "GNU Affero General Public License version 3",
|
"license": "GNU Affero General Public License version 3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "immich-e2e",
|
"name": "immich-e2e",
|
||||||
"version": "1.135.2",
|
"version": "1.135.3",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -464,7 +464,6 @@
|
|||||||
"assets": "Assets",
|
"assets": "Assets",
|
||||||
"assets_added_count": "Added {count, plural, one {# asset} other {# assets}}",
|
"assets_added_count": "Added {count, plural, one {# asset} other {# assets}}",
|
||||||
"assets_added_to_album_count": "Added {count, plural, one {# asset} other {# assets}} to the album",
|
"assets_added_to_album_count": "Added {count, plural, one {# asset} other {# assets}} to the album",
|
||||||
"assets_added_to_name_count": "Added {count, plural, one {# asset} other {# assets}} to {hasName, select, true {<b>{name}</b>} other {new album}}",
|
|
||||||
"assets_cannot_be_added_to_album_count": "{count, plural, one {Asset} other {Assets}} cannot be added to the album",
|
"assets_cannot_be_added_to_album_count": "{count, plural, one {Asset} other {Assets}} cannot be added to the album",
|
||||||
"assets_count": "{count, plural, one {# asset} other {# assets}}",
|
"assets_count": "{count, plural, one {# asset} other {# assets}}",
|
||||||
"assets_deleted_permanently": "{count} asset(s) deleted permanently",
|
"assets_deleted_permanently": "{count} asset(s) deleted permanently",
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ platform :android do
|
|||||||
task: 'bundle',
|
task: 'bundle',
|
||||||
build_type: 'Release',
|
build_type: 'Release',
|
||||||
properties: {
|
properties: {
|
||||||
"android.injected.version.code" => 203,
|
"android.injected.version.code" => 204,
|
||||||
"android.injected.version.name" => "1.135.2",
|
"android.injected.version.name" => "1.135.3",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab')
|
upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab')
|
||||||
|
|||||||
@@ -17,6 +17,14 @@ enum AssetType: String, Codable {
|
|||||||
case other = "OTHER"
|
case other = "OTHER"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ServerWellKnown: Codable {
|
||||||
|
struct APIInfo: Codable{
|
||||||
|
let endpoint: String
|
||||||
|
}
|
||||||
|
|
||||||
|
let api: APIInfo
|
||||||
|
}
|
||||||
|
|
||||||
struct SearchResult: Codable {
|
struct SearchResult: Codable {
|
||||||
let id: String
|
let id: String
|
||||||
let type: AssetType
|
let type: AssetType
|
||||||
@@ -57,7 +65,7 @@ class ImmichAPI {
|
|||||||
init() async throws {
|
init() async throws {
|
||||||
// fetch the credentials from the UserDefaults store that dart placed here
|
// fetch the credentials from the UserDefaults store that dart placed here
|
||||||
guard let defaults = UserDefaults(suiteName: "group.app.immich.share"),
|
guard let defaults = UserDefaults(suiteName: "group.app.immich.share"),
|
||||||
let serverURL = defaults.string(forKey: "widget_server_url"),
|
var serverURL = defaults.string(forKey: "widget_server_url"),
|
||||||
let sessionKey = defaults.string(forKey: "widget_auth_token")
|
let sessionKey = defaults.string(forKey: "widget_auth_token")
|
||||||
else {
|
else {
|
||||||
throw WidgetError.noLogin
|
throw WidgetError.noLogin
|
||||||
@@ -66,13 +74,55 @@ class ImmichAPI {
|
|||||||
if serverURL == "" || sessionKey == "" {
|
if serverURL == "" || sessionKey == "" {
|
||||||
throw WidgetError.noLogin
|
throw WidgetError.noLogin
|
||||||
}
|
}
|
||||||
|
|
||||||
serverConfig = ServerConfig(
|
// migrate the server list value to a JSON array if it is not already
|
||||||
serverEndpoint: serverURL,
|
if !serverURL.starts(with: "[") {
|
||||||
sessionKey: sessionKey
|
let newServerList = "[\"\(serverURL)\"]"
|
||||||
)
|
defaults.set(newServerList, forKey: "widget_server_url")
|
||||||
|
serverURL = newServerList
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let urls = try? JSONDecoder().decode([String].self, from: serverURL.data(using: .utf8)!) else {
|
||||||
|
throw WidgetError.noLogin
|
||||||
|
}
|
||||||
|
|
||||||
|
for url in urls {
|
||||||
|
guard let endpointURL = URL(string: url) else { continue }
|
||||||
|
|
||||||
|
if let apiURL = await Self.validateServer(at: endpointURL) {
|
||||||
|
serverConfig = ServerConfig(
|
||||||
|
serverEndpoint: apiURL.absoluteString,
|
||||||
|
sessionKey: sessionKey
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw WidgetError.fetchFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static func validateServer(at endpointURL: URL) async -> URL? {
|
||||||
|
// build a URL that is only scheme, host, and port
|
||||||
|
var components = URLComponents()
|
||||||
|
components.scheme = endpointURL.scheme
|
||||||
|
components.host = endpointURL.host
|
||||||
|
components.port = endpointURL.port
|
||||||
|
|
||||||
|
guard let baseURL = components.url else { return nil }
|
||||||
|
|
||||||
|
var pingURL = baseURL
|
||||||
|
pingURL.appendPathComponent(".well-known")
|
||||||
|
pingURL.appendPathComponent("immich")
|
||||||
|
|
||||||
|
guard let (serverPingJSON, _) = try? await URLSession.shared.data(from: pingURL) else { return nil }
|
||||||
|
guard let apiInfo = try? JSONDecoder().decode(ServerWellKnown.self, from: serverPingJSON) else { return nil }
|
||||||
|
|
||||||
|
var apiURL = baseURL
|
||||||
|
apiURL.appendPathComponent(apiInfo.api.endpoint)
|
||||||
|
|
||||||
|
return apiURL
|
||||||
|
}
|
||||||
|
|
||||||
private func buildRequestURL(
|
private func buildRequestURL(
|
||||||
serverConfig: ServerConfig,
|
serverConfig: ServerConfig,
|
||||||
endpoint: String,
|
endpoint: String,
|
||||||
|
|||||||
@@ -20,8 +20,11 @@ struct ImmichMemoryProvider: TimelineProvider {
|
|||||||
completion: @escaping @Sendable (ImageEntry) -> Void
|
completion: @escaping @Sendable (ImageEntry) -> Void
|
||||||
) {
|
) {
|
||||||
Task {
|
Task {
|
||||||
guard let api = try? await ImmichAPI() else {
|
var api: ImmichAPI
|
||||||
completion(ImageEntry(date: Date(), image: nil, error: .noLogin))
|
do {
|
||||||
|
api = try await ImmichAPI()
|
||||||
|
} catch let error as WidgetError {
|
||||||
|
completion(ImageEntry(date: Date(), image: nil, error: error))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,9 +82,13 @@ struct ImmichMemoryProvider: TimelineProvider {
|
|||||||
Task {
|
Task {
|
||||||
var entries: [ImageEntry] = []
|
var entries: [ImageEntry] = []
|
||||||
let now = Date()
|
let now = Date()
|
||||||
|
|
||||||
guard let api = try? await ImmichAPI() else {
|
|
||||||
entries.append(ImageEntry(date: now, image: nil, error: .noLogin))
|
var api: ImmichAPI
|
||||||
|
do {
|
||||||
|
api = try await ImmichAPI()
|
||||||
|
} catch let error as WidgetError {
|
||||||
|
entries.append(ImageEntry(date: now, image: nil, error: error))
|
||||||
completion(Timeline(entries: entries, policy: .atEnd))
|
completion(Timeline(entries: entries, policy: .atEnd))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,10 +63,15 @@ struct ImmichRandomProvider: AppIntentTimelineProvider {
|
|||||||
) async
|
) async
|
||||||
-> ImageEntry
|
-> ImageEntry
|
||||||
{
|
{
|
||||||
guard let api = try? await ImmichAPI() else {
|
var api: ImmichAPI
|
||||||
return ImageEntry(date: Date(), image: nil, error: .noLogin)
|
do {
|
||||||
|
api = try await ImmichAPI()
|
||||||
|
} catch let error as WidgetError {
|
||||||
|
return ImageEntry(date: Date(), image: nil, error: error)
|
||||||
|
} catch {
|
||||||
|
return ImageEntry(date: Date(), image: nil, error: .fetchFailed)
|
||||||
}
|
}
|
||||||
|
|
||||||
guard
|
guard
|
||||||
let randomImage = try? await api.fetchSearchResults(
|
let randomImage = try? await api.fetchSearchResults(
|
||||||
with: SearchFilters(size: 1)
|
with: SearchFilters(size: 1)
|
||||||
@@ -100,15 +105,21 @@ struct ImmichRandomProvider: AppIntentTimelineProvider {
|
|||||||
let now = Date()
|
let now = Date()
|
||||||
|
|
||||||
// If we don't have a server config, return an entry with an error
|
// If we don't have a server config, return an entry with an error
|
||||||
guard let api = try? await ImmichAPI() else {
|
var api: ImmichAPI
|
||||||
entries.append(ImageEntry(date: now, image: nil, error: .noLogin))
|
do {
|
||||||
|
api = try await ImmichAPI()
|
||||||
|
} catch let error as WidgetError {
|
||||||
|
entries.append(ImageEntry(date: now, image: nil, error: error))
|
||||||
|
return Timeline(entries: entries, policy: .atEnd)
|
||||||
|
} catch {
|
||||||
|
entries.append(ImageEntry(date: now, image: nil, error: .fetchFailed))
|
||||||
return Timeline(entries: entries, policy: .atEnd)
|
return Timeline(entries: entries, policy: .atEnd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nil if album is NONE or nil
|
// nil if album is NONE or nil
|
||||||
let albumId =
|
let albumId =
|
||||||
configuration.album?.id != "NONE" ? configuration.album?.id : nil
|
configuration.album?.id != "NONE" ? configuration.album?.id : nil
|
||||||
var albumName: String? = albumId != nil ? configuration.album?.albumName : nil
|
let albumName: String? = albumId != nil ? configuration.album?.albumName : nil
|
||||||
|
|
||||||
if albumId != nil {
|
if albumId != nil {
|
||||||
// make sure the album exists on server, otherwise show error
|
// make sure the album exists on server, otherwise show error
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ platform :ios do
|
|||||||
path: "./Runner.xcodeproj",
|
path: "./Runner.xcodeproj",
|
||||||
)
|
)
|
||||||
increment_version_number(
|
increment_version_number(
|
||||||
version_number: "1.135.2"
|
version_number: "1.135.3"
|
||||||
)
|
)
|
||||||
increment_build_number(
|
increment_build_number(
|
||||||
build_number: latest_testflight_build_number + 1,
|
build_number: latest_testflight_build_number + 1,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ const Map<String, Locale> locales = {
|
|||||||
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'SIMPLIFIED'),
|
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'SIMPLIFIED'),
|
||||||
'Chinese Traditional (zh_TW)':
|
'Chinese Traditional (zh_TW)':
|
||||||
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant'),
|
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant'),
|
||||||
|
'Croatian (hr)': Locale('hr'),
|
||||||
'Czech (cs)': Locale('cs'),
|
'Czech (cs)': Locale('cs'),
|
||||||
'Danish (da)': Locale('da'),
|
'Danish (da)': Locale('da'),
|
||||||
'Dutch (nl)': Locale('nl'),
|
'Dutch (nl)': Locale('nl'),
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
import 'dart:typed_data';
|
|
||||||
import 'dart:ui';
|
|
||||||
|
|
||||||
abstract interface class IAssetMediaRepository {
|
|
||||||
Future<Uint8List?> getThumbnail(
|
|
||||||
String id, {
|
|
||||||
int quality = 80,
|
|
||||||
Size size = const Size.square(256),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:immich_mobile/domain/interfaces/db.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/device_asset.model.dart';
|
|
||||||
|
|
||||||
abstract interface class IDeviceAssetRepository implements IDatabaseRepository {
|
|
||||||
Future<bool> updateAll(List<DeviceAsset> assetHash);
|
|
||||||
|
|
||||||
Future<List<DeviceAsset>> getByIds(List<String> localIds);
|
|
||||||
|
|
||||||
Future<void> deleteIds(List<String> ids);
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import 'package:immich_mobile/domain/interfaces/db.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/exif.model.dart';
|
|
||||||
|
|
||||||
abstract interface class IExifInfoRepository implements IDatabaseRepository {
|
|
||||||
Future<ExifInfo?> get(int assetId);
|
|
||||||
|
|
||||||
Future<ExifInfo> update(ExifInfo exifInfo);
|
|
||||||
|
|
||||||
Future<List<ExifInfo>> updateAll(List<ExifInfo> exifInfos);
|
|
||||||
|
|
||||||
Future<void> delete(int assetId);
|
|
||||||
|
|
||||||
Future<void> deleteAll();
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
import 'package:immich_mobile/domain/interfaces/db.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/local_album.model.dart';
|
|
||||||
|
|
||||||
abstract interface class ILocalAlbumRepository implements IDatabaseRepository {
|
|
||||||
Future<List<LocalAlbum>> getAll({Set<SortLocalAlbumsBy> sortBy = const {}});
|
|
||||||
|
|
||||||
Future<List<LocalAsset>> getAssets(String albumId);
|
|
||||||
|
|
||||||
Future<List<String>> getAssetIds(String albumId);
|
|
||||||
|
|
||||||
Future<void> upsert(
|
|
||||||
LocalAlbum album, {
|
|
||||||
Iterable<LocalAsset> toUpsert = const [],
|
|
||||||
Iterable<String> toDelete = const [],
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<void> updateAll(Iterable<LocalAlbum> albums);
|
|
||||||
|
|
||||||
Future<void> delete(String albumId);
|
|
||||||
|
|
||||||
Future<void> processDelta({
|
|
||||||
required List<LocalAsset> updates,
|
|
||||||
required List<String> deletes,
|
|
||||||
required Map<String, List<String>> assetAlbums,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<void> syncDeletes(String albumId, Iterable<String> assetIdsToKeep);
|
|
||||||
|
|
||||||
Future<List<LocalAsset>> getAssetsToHash(String albumId);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum SortLocalAlbumsBy { id, backupSelection, isIosSharedAlbum }
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import 'package:immich_mobile/domain/interfaces/db.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
|
||||||
|
|
||||||
abstract interface class ILocalAssetRepository implements IDatabaseRepository {
|
|
||||||
Future<void> updateHashes(Iterable<LocalAsset> hashes);
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:immich_mobile/domain/interfaces/db.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/log.model.dart';
|
|
||||||
|
|
||||||
abstract interface class ILogRepository implements IDatabaseRepository {
|
|
||||||
Future<bool> insert(LogMessage log);
|
|
||||||
|
|
||||||
Future<bool> insertAll(Iterable<LogMessage> logs);
|
|
||||||
|
|
||||||
Future<List<LogMessage>> getAll();
|
|
||||||
|
|
||||||
Future<bool> deleteAll();
|
|
||||||
|
|
||||||
/// Truncates the logs to the most recent [limit]. Defaults to recent 250 logs
|
|
||||||
Future<void> truncate({int limit = 250});
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
|
||||||
|
|
||||||
abstract interface class IStorageRepository {
|
|
||||||
Future<File?> getFileForAsset(LocalAsset asset);
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import 'package:immich_mobile/domain/interfaces/db.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
|
||||||
|
|
||||||
abstract interface class IStoreRepository implements IDatabaseRepository {
|
|
||||||
Future<bool> insert<T>(StoreKey<T> key, T value);
|
|
||||||
|
|
||||||
Future<T?> tryGet<T>(StoreKey<T> key);
|
|
||||||
|
|
||||||
Future<List<StoreDto<Object>>> getAll();
|
|
||||||
|
|
||||||
Stream<T?> watch<T>(StoreKey<T> key);
|
|
||||||
|
|
||||||
Stream<StoreDto<Object>> watchAll();
|
|
||||||
|
|
||||||
Future<bool> update<T>(StoreKey<T> key, T value);
|
|
||||||
|
|
||||||
Future<void> delete<T>(StoreKey<T> key);
|
|
||||||
|
|
||||||
Future<void> deleteAll();
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import 'package:http/http.dart' as http;
|
|
||||||
import 'package:immich_mobile/domain/models/sync_event.model.dart';
|
|
||||||
|
|
||||||
abstract interface class ISyncApiRepository {
|
|
||||||
Future<void> ack(List<String> data);
|
|
||||||
|
|
||||||
Future<void> streamChanges(
|
|
||||||
Function(List<SyncEvent>, Function() abort) onData, {
|
|
||||||
int batchSize,
|
|
||||||
http.Client? httpClient,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
import 'package:immich_mobile/domain/interfaces/db.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/timeline.model.dart';
|
|
||||||
|
|
||||||
abstract interface class ITimelineRepository implements IDatabaseRepository {
|
|
||||||
Stream<List<Bucket>> watchMainBucket(
|
|
||||||
List<String> timelineUsers, {
|
|
||||||
GroupAssetsBy groupBy = GroupAssetsBy.day,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<List<BaseAsset>> getMainBucketAssets(
|
|
||||||
List<String> timelineUsers, {
|
|
||||||
required int offset,
|
|
||||||
required int count,
|
|
||||||
});
|
|
||||||
|
|
||||||
Stream<List<Bucket>> watchLocalBucket(
|
|
||||||
String albumId, {
|
|
||||||
GroupAssetsBy groupBy = GroupAssetsBy.day,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<List<BaseAsset>> getLocalBucketAssets(
|
|
||||||
String albumId, {
|
|
||||||
required int offset,
|
|
||||||
required int count,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,5 @@
|
|||||||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
abstract interface class IPersonApiRepository {
|
|
||||||
Future<List<Person>> getAll();
|
|
||||||
Future<Person> update(String id, {String? name});
|
|
||||||
}
|
|
||||||
|
|
||||||
class Person {
|
class Person {
|
||||||
Person({
|
Person({
|
||||||
required this.id,
|
required this.id,
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:immich_mobile/constants/constants.dart';
|
import 'package:immich_mobile/constants/constants.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/local_album.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/interfaces/local_asset.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/interfaces/storage.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart';
|
||||||
import 'package:immich_mobile/platform/native_sync_api.g.dart';
|
import 'package:immich_mobile/platform/native_sync_api.g.dart';
|
||||||
import 'package:immich_mobile/presentation/pages/dev/dev_logger.dart';
|
import 'package:immich_mobile/presentation/pages/dev/dev_logger.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
@@ -12,16 +12,16 @@ import 'package:logging/logging.dart';
|
|||||||
class HashService {
|
class HashService {
|
||||||
final int batchSizeLimit;
|
final int batchSizeLimit;
|
||||||
final int batchFileLimit;
|
final int batchFileLimit;
|
||||||
final ILocalAlbumRepository _localAlbumRepository;
|
final DriftLocalAlbumRepository _localAlbumRepository;
|
||||||
final ILocalAssetRepository _localAssetRepository;
|
final DriftLocalAssetRepository _localAssetRepository;
|
||||||
final IStorageRepository _storageRepository;
|
final StorageRepository _storageRepository;
|
||||||
final NativeSyncApi _nativeSyncApi;
|
final NativeSyncApi _nativeSyncApi;
|
||||||
final _log = Logger('HashService');
|
final _log = Logger('HashService');
|
||||||
|
|
||||||
HashService({
|
HashService({
|
||||||
required ILocalAlbumRepository localAlbumRepository,
|
required DriftLocalAlbumRepository localAlbumRepository,
|
||||||
required ILocalAssetRepository localAssetRepository,
|
required DriftLocalAssetRepository localAssetRepository,
|
||||||
required IStorageRepository storageRepository,
|
required StorageRepository storageRepository,
|
||||||
required NativeSyncApi nativeSyncApi,
|
required NativeSyncApi nativeSyncApi,
|
||||||
this.batchSizeLimit = kBatchHashSizeLimit,
|
this.batchSizeLimit = kBatchHashSizeLimit,
|
||||||
this.batchFileLimit = kBatchHashFileLimit,
|
this.batchFileLimit = kBatchHashFileLimit,
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/local_album.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/local_album.model.dart';
|
import 'package:immich_mobile/domain/models/local_album.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
import 'package:immich_mobile/domain/services/store.service.dart';
|
import 'package:immich_mobile/domain/services/store.service.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
|
||||||
import 'package:immich_mobile/platform/native_sync_api.g.dart';
|
import 'package:immich_mobile/platform/native_sync_api.g.dart';
|
||||||
import 'package:immich_mobile/presentation/pages/dev/dev_logger.dart';
|
import 'package:immich_mobile/presentation/pages/dev/dev_logger.dart';
|
||||||
import 'package:immich_mobile/utils/diff.dart';
|
import 'package:immich_mobile/utils/diff.dart';
|
||||||
@@ -14,14 +14,14 @@ import 'package:logging/logging.dart';
|
|||||||
import 'package:platform/platform.dart';
|
import 'package:platform/platform.dart';
|
||||||
|
|
||||||
class LocalSyncService {
|
class LocalSyncService {
|
||||||
final ILocalAlbumRepository _localAlbumRepository;
|
final DriftLocalAlbumRepository _localAlbumRepository;
|
||||||
final NativeSyncApi _nativeSyncApi;
|
final NativeSyncApi _nativeSyncApi;
|
||||||
final Platform _platform;
|
final Platform _platform;
|
||||||
final StoreService _storeService;
|
final StoreService _storeService;
|
||||||
final Logger _log = Logger("DeviceSyncService");
|
final Logger _log = Logger("DeviceSyncService");
|
||||||
|
|
||||||
LocalSyncService({
|
LocalSyncService({
|
||||||
required ILocalAlbumRepository localAlbumRepository,
|
required DriftLocalAlbumRepository localAlbumRepository,
|
||||||
required NativeSyncApi nativeSyncApi,
|
required NativeSyncApi nativeSyncApi,
|
||||||
required StoreService storeService,
|
required StoreService storeService,
|
||||||
Platform? platform,
|
Platform? platform,
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:immich_mobile/constants/constants.dart';
|
import 'package:immich_mobile/constants/constants.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/log.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/interfaces/store.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/log.model.dart';
|
import 'package:immich_mobile/domain/models/log.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/log.repository.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
|
|
||||||
/// Service responsible for handling application logging.
|
/// Service responsible for handling application logging.
|
||||||
@@ -14,8 +14,8 @@ import 'package:logging/logging.dart';
|
|||||||
/// writes them to a persistent [ILogRepository], and manages log levels
|
/// writes them to a persistent [ILogRepository], and manages log levels
|
||||||
/// via [IStoreRepository]
|
/// via [IStoreRepository]
|
||||||
class LogService {
|
class LogService {
|
||||||
final ILogRepository _logRepository;
|
final IsarLogRepository _logRepository;
|
||||||
final IStoreRepository _storeRepository;
|
final IsarStoreRepository _storeRepository;
|
||||||
|
|
||||||
final List<LogMessage> _msgBuffer = [];
|
final List<LogMessage> _msgBuffer = [];
|
||||||
|
|
||||||
@@ -37,8 +37,8 @@ class LogService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future<LogService> init({
|
static Future<LogService> init({
|
||||||
required ILogRepository logRepository,
|
required IsarLogRepository logRepository,
|
||||||
required IStoreRepository storeRepository,
|
required IsarStoreRepository storeRepository,
|
||||||
bool shouldBuffer = true,
|
bool shouldBuffer = true,
|
||||||
}) async {
|
}) async {
|
||||||
_instance ??= await create(
|
_instance ??= await create(
|
||||||
@@ -50,8 +50,8 @@ class LogService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future<LogService> create({
|
static Future<LogService> create({
|
||||||
required ILogRepository logRepository,
|
required IsarLogRepository logRepository,
|
||||||
required IStoreRepository storeRepository,
|
required IsarStoreRepository storeRepository,
|
||||||
bool shouldBuffer = true,
|
bool shouldBuffer = true,
|
||||||
}) async {
|
}) async {
|
||||||
final instance = LogService._(logRepository, storeRepository, shouldBuffer);
|
final instance = LogService._(logRepository, storeRepository, shouldBuffer);
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:immich_mobile/domain/interfaces/store.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
|
||||||
|
|
||||||
/// Provides access to a persistent key-value store with an in-memory cache.
|
/// Provides access to a persistent key-value store with an in-memory cache.
|
||||||
/// Listens for repository changes to keep the cache updated.
|
/// Listens for repository changes to keep the cache updated.
|
||||||
class StoreService {
|
class StoreService {
|
||||||
final IStoreRepository _storeRepository;
|
final IsarStoreRepository _storeRepository;
|
||||||
|
|
||||||
/// In-memory cache. Keys are [StoreKey.id]
|
/// In-memory cache. Keys are [StoreKey.id]
|
||||||
final Map<int, Object?> _cache = {};
|
final Map<int, Object?> _cache = {};
|
||||||
late final StreamSubscription<StoreDto> _storeUpdateSubscription;
|
late final StreamSubscription<StoreDto> _storeUpdateSubscription;
|
||||||
|
|
||||||
StoreService._({required IStoreRepository storeRepository})
|
StoreService._({required IsarStoreRepository storeRepository})
|
||||||
: _storeRepository = storeRepository;
|
: _storeRepository = storeRepository;
|
||||||
|
|
||||||
// TODO: Temporary typedef to make minimal changes. Remove this and make the presentation layer access store through a provider
|
// TODO: Temporary typedef to make minimal changes. Remove this and make the presentation layer access store through a provider
|
||||||
@@ -26,14 +26,14 @@ class StoreService {
|
|||||||
|
|
||||||
// TODO: Replace the implementation with the one from create after removing the typedef
|
// TODO: Replace the implementation with the one from create after removing the typedef
|
||||||
static Future<StoreService> init({
|
static Future<StoreService> init({
|
||||||
required IStoreRepository storeRepository,
|
required IsarStoreRepository storeRepository,
|
||||||
}) async {
|
}) async {
|
||||||
_instance ??= await create(storeRepository: storeRepository);
|
_instance ??= await create(storeRepository: storeRepository);
|
||||||
return _instance!;
|
return _instance!;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<StoreService> create({
|
static Future<StoreService> create({
|
||||||
required IStoreRepository storeRepository,
|
required IsarStoreRepository storeRepository,
|
||||||
}) async {
|
}) async {
|
||||||
final instance = StoreService._(storeRepository: storeRepository);
|
final instance = StoreService._(storeRepository: storeRepository);
|
||||||
await instance._populateCache();
|
await instance._populateCache();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:immich_mobile/domain/interfaces/sync_api.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/sync_event.model.dart';
|
import 'package:immich_mobile/domain/models/sync_event.model.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/sync_api.repository.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:openapi/api.dart';
|
import 'package:openapi/api.dart';
|
||||||
@@ -9,12 +9,12 @@ import 'package:openapi/api.dart';
|
|||||||
class SyncStreamService {
|
class SyncStreamService {
|
||||||
final Logger _logger = Logger('SyncStreamService');
|
final Logger _logger = Logger('SyncStreamService');
|
||||||
|
|
||||||
final ISyncApiRepository _syncApiRepository;
|
final SyncApiRepository _syncApiRepository;
|
||||||
final SyncStreamRepository _syncStreamRepository;
|
final SyncStreamRepository _syncStreamRepository;
|
||||||
final bool Function()? _cancelChecker;
|
final bool Function()? _cancelChecker;
|
||||||
|
|
||||||
SyncStreamService({
|
SyncStreamService({
|
||||||
required ISyncApiRepository syncApiRepository,
|
required SyncApiRepository syncApiRepository,
|
||||||
required SyncStreamRepository syncStreamRepository,
|
required SyncStreamRepository syncStreamRepository,
|
||||||
bool Function()? cancelChecker,
|
bool Function()? cancelChecker,
|
||||||
}) : _syncApiRepository = syncApiRepository,
|
}) : _syncApiRepository = syncApiRepository,
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import 'dart:math' as math;
|
|||||||
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:immich_mobile/constants/constants.dart';
|
import 'package:immich_mobile/constants/constants.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/timeline.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/setting.model.dart';
|
import 'package:immich_mobile/domain/models/setting.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/timeline.model.dart';
|
import 'package:immich_mobile/domain/models/timeline.model.dart';
|
||||||
import 'package:immich_mobile/domain/services/setting.service.dart';
|
import 'package:immich_mobile/domain/services/setting.service.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/timeline.repository.dart';
|
||||||
import 'package:immich_mobile/utils/async_mutex.dart';
|
import 'package:immich_mobile/utils/async_mutex.dart';
|
||||||
|
|
||||||
typedef TimelineAssetSource = Future<List<BaseAsset>> Function(
|
typedef TimelineAssetSource = Future<List<BaseAsset>> Function(
|
||||||
@@ -18,11 +18,11 @@ typedef TimelineAssetSource = Future<List<BaseAsset>> Function(
|
|||||||
typedef TimelineBucketSource = Stream<List<Bucket>> Function();
|
typedef TimelineBucketSource = Stream<List<Bucket>> Function();
|
||||||
|
|
||||||
class TimelineFactory {
|
class TimelineFactory {
|
||||||
final ITimelineRepository _timelineRepository;
|
final DriftTimelineRepository _timelineRepository;
|
||||||
final SettingsService _settingsService;
|
final SettingsService _settingsService;
|
||||||
|
|
||||||
const TimelineFactory({
|
const TimelineFactory({
|
||||||
required ITimelineRepository timelineRepository,
|
required DriftTimelineRepository timelineRepository,
|
||||||
required SettingsService settingsService,
|
required SettingsService settingsService,
|
||||||
}) : _timelineRepository = timelineRepository,
|
}) : _timelineRepository = timelineRepository,
|
||||||
_settingsService = settingsService;
|
_settingsService = settingsService;
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:immich_mobile/domain/interfaces/asset_media.interface.dart';
|
|
||||||
import 'package:photo_manager/photo_manager.dart';
|
import 'package:photo_manager/photo_manager.dart';
|
||||||
|
|
||||||
class AssetMediaRepository implements IAssetMediaRepository {
|
class AssetMediaRepository {
|
||||||
const AssetMediaRepository();
|
const AssetMediaRepository();
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Uint8List?> getThumbnail(
|
Future<Uint8List?> getThumbnail(
|
||||||
String id, {
|
String id, {
|
||||||
int quality = 80,
|
int quality = 80,
|
||||||
|
|||||||
@@ -1,23 +1,19 @@
|
|||||||
import 'package:immich_mobile/domain/interfaces/device_asset.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/device_asset.model.dart';
|
import 'package:immich_mobile/domain/models/device_asset.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/device_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/device_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
class IsarDeviceAssetRepository extends IsarDatabaseRepository
|
class IsarDeviceAssetRepository extends IsarDatabaseRepository {
|
||||||
implements IDeviceAssetRepository {
|
|
||||||
final Isar _db;
|
final Isar _db;
|
||||||
|
|
||||||
const IsarDeviceAssetRepository(this._db) : super(_db);
|
const IsarDeviceAssetRepository(this._db) : super(_db);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> deleteIds(List<String> ids) {
|
Future<void> deleteIds(List<String> ids) {
|
||||||
return transaction(() async {
|
return transaction(() async {
|
||||||
await _db.deviceAssetEntitys.deleteAllByAssetId(ids.toList());
|
await _db.deviceAssetEntitys.deleteAllByAssetId(ids.toList());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<DeviceAsset>> getByIds(List<String> localIds) {
|
Future<List<DeviceAsset>> getByIds(List<String> localIds) {
|
||||||
return _db.deviceAssetEntitys
|
return _db.deviceAssetEntitys
|
||||||
.where()
|
.where()
|
||||||
@@ -26,7 +22,6 @@ class IsarDeviceAssetRepository extends IsarDatabaseRepository
|
|||||||
.then((value) => value.map((e) => e.toModel()).toList());
|
.then((value) => value.map((e) => e.toModel()).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> updateAll(List<DeviceAsset> assetHash) {
|
Future<bool> updateAll(List<DeviceAsset> assetHash) {
|
||||||
return transaction(() async {
|
return transaction(() async {
|
||||||
await _db.deviceAssetEntitys
|
await _db.deviceAssetEntitys
|
||||||
|
|||||||
@@ -1,36 +1,30 @@
|
|||||||
import 'package:immich_mobile/domain/interfaces/exif.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/exif.model.dart';
|
import 'package:immich_mobile/domain/models/exif.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/exif.entity.dart'
|
import 'package:immich_mobile/infrastructure/entities/exif.entity.dart'
|
||||||
as entity;
|
as entity;
|
||||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
class IsarExifRepository extends IsarDatabaseRepository
|
class IsarExifRepository extends IsarDatabaseRepository {
|
||||||
implements IExifInfoRepository {
|
|
||||||
final Isar _db;
|
final Isar _db;
|
||||||
|
|
||||||
const IsarExifRepository(this._db) : super(_db);
|
const IsarExifRepository(this._db) : super(_db);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> delete(int assetId) async {
|
Future<void> delete(int assetId) async {
|
||||||
await transaction(() async {
|
await transaction(() async {
|
||||||
await _db.exifInfos.delete(assetId);
|
await _db.exifInfos.delete(assetId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> deleteAll() async {
|
Future<void> deleteAll() async {
|
||||||
await transaction(() async {
|
await transaction(() async {
|
||||||
await _db.exifInfos.clear();
|
await _db.exifInfos.clear();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<ExifInfo?> get(int assetId) async {
|
Future<ExifInfo?> get(int assetId) async {
|
||||||
return (await _db.exifInfos.get(assetId))?.toDto();
|
return (await _db.exifInfos.get(assetId))?.toDto();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<ExifInfo> update(ExifInfo exifInfo) {
|
Future<ExifInfo> update(ExifInfo exifInfo) {
|
||||||
return transaction(() async {
|
return transaction(() async {
|
||||||
await _db.exifInfos.put(entity.ExifInfo.fromDto(exifInfo));
|
await _db.exifInfos.put(entity.ExifInfo.fromDto(exifInfo));
|
||||||
@@ -38,7 +32,6 @@ class IsarExifRepository extends IsarDatabaseRepository
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<ExifInfo>> updateAll(List<ExifInfo> exifInfos) {
|
Future<List<ExifInfo>> updateAll(List<ExifInfo> exifInfos) {
|
||||||
return transaction(() async {
|
return transaction(() async {
|
||||||
await _db.exifInfos.putAll(
|
await _db.exifInfos.putAll(
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/local_album.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/local_album.model.dart';
|
import 'package:immich_mobile/domain/models/local_album.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/local_album.entity.drift.dart';
|
import 'package:immich_mobile/infrastructure/entities/local_album.entity.drift.dart';
|
||||||
@@ -8,15 +7,15 @@ import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.d
|
|||||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||||
import 'package:platform/platform.dart';
|
import 'package:platform/platform.dart';
|
||||||
|
|
||||||
class DriftLocalAlbumRepository extends DriftDatabaseRepository
|
enum SortLocalAlbumsBy { id, backupSelection, isIosSharedAlbum }
|
||||||
implements ILocalAlbumRepository {
|
|
||||||
|
class DriftLocalAlbumRepository extends DriftDatabaseRepository {
|
||||||
final Drift _db;
|
final Drift _db;
|
||||||
final Platform _platform;
|
final Platform _platform;
|
||||||
const DriftLocalAlbumRepository(this._db, {Platform? platform})
|
const DriftLocalAlbumRepository(this._db, {Platform? platform})
|
||||||
: _platform = platform ?? const LocalPlatform(),
|
: _platform = platform ?? const LocalPlatform(),
|
||||||
super(_db);
|
super(_db);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<LocalAlbum>> getAll({Set<SortLocalAlbumsBy> sortBy = const {}}) {
|
Future<List<LocalAlbum>> getAll({Set<SortLocalAlbumsBy> sortBy = const {}}) {
|
||||||
final assetCount = _db.localAlbumAssetEntity.assetId.count();
|
final assetCount = _db.localAlbumAssetEntity.assetId.count();
|
||||||
|
|
||||||
@@ -56,7 +55,6 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository
|
|||||||
.get();
|
.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> delete(String albumId) => transaction(() async {
|
Future<void> delete(String albumId) => transaction(() async {
|
||||||
// Remove all assets that are only in this particular album
|
// Remove all assets that are only in this particular album
|
||||||
// We cannot remove all assets in the album because they might be in other albums in iOS
|
// We cannot remove all assets in the album because they might be in other albums in iOS
|
||||||
@@ -72,7 +70,6 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository
|
|||||||
.delete();
|
.delete();
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> syncDeletes(
|
Future<void> syncDeletes(
|
||||||
String albumId,
|
String albumId,
|
||||||
Iterable<String> assetIdsToKeep,
|
Iterable<String> assetIdsToKeep,
|
||||||
@@ -101,7 +98,6 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository
|
|||||||
await deleteSmt.go();
|
await deleteSmt.go();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> upsert(
|
Future<void> upsert(
|
||||||
LocalAlbum localAlbum, {
|
LocalAlbum localAlbum, {
|
||||||
Iterable<LocalAsset> toUpsert = const [],
|
Iterable<LocalAsset> toUpsert = const [],
|
||||||
@@ -134,7 +130,6 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> updateAll(Iterable<LocalAlbum> albums) {
|
Future<void> updateAll(Iterable<LocalAlbum> albums) {
|
||||||
return _db.transaction(() async {
|
return _db.transaction(() async {
|
||||||
await _db.localAlbumEntity
|
await _db.localAlbumEntity
|
||||||
@@ -185,7 +180,6 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<LocalAsset>> getAssets(String albumId) {
|
Future<List<LocalAsset>> getAssets(String albumId) {
|
||||||
final query = _db.localAlbumAssetEntity.select().join(
|
final query = _db.localAlbumAssetEntity.select().join(
|
||||||
[
|
[
|
||||||
@@ -202,7 +196,6 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository
|
|||||||
.get();
|
.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<String>> getAssetIds(String albumId) {
|
Future<List<String>> getAssetIds(String albumId) {
|
||||||
final query = _db.localAlbumAssetEntity.selectOnly()
|
final query = _db.localAlbumAssetEntity.selectOnly()
|
||||||
..addColumns([_db.localAlbumAssetEntity.assetId])
|
..addColumns([_db.localAlbumAssetEntity.assetId])
|
||||||
@@ -212,7 +205,6 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository
|
|||||||
.get();
|
.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> processDelta({
|
Future<void> processDelta({
|
||||||
required List<LocalAsset> updates,
|
required List<LocalAsset> updates,
|
||||||
required List<String> deletes,
|
required List<String> deletes,
|
||||||
@@ -253,7 +245,6 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<LocalAsset>> getAssetsToHash(String albumId) {
|
Future<List<LocalAsset>> getAssetsToHash(String albumId) {
|
||||||
final query = _db.localAlbumAssetEntity.select().join(
|
final query = _db.localAlbumAssetEntity.select().join(
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/local_asset.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart';
|
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||||
|
|
||||||
class DriftLocalAssetRepository extends DriftDatabaseRepository
|
class DriftLocalAssetRepository extends DriftDatabaseRepository {
|
||||||
implements ILocalAssetRepository {
|
|
||||||
final Drift _db;
|
final Drift _db;
|
||||||
const DriftLocalAssetRepository(this._db) : super(_db);
|
const DriftLocalAssetRepository(this._db) : super(_db);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> updateHashes(Iterable<LocalAsset> hashes) {
|
Future<void> updateHashes(Iterable<LocalAsset> hashes) {
|
||||||
if (hashes.isEmpty) {
|
if (hashes.isEmpty) {
|
||||||
return Future.value();
|
return Future.value();
|
||||||
|
|||||||
@@ -1,28 +1,23 @@
|
|||||||
import 'package:immich_mobile/domain/interfaces/log.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/log.model.dart';
|
import 'package:immich_mobile/domain/models/log.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/log.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/log.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
class IsarLogRepository extends IsarDatabaseRepository
|
class IsarLogRepository extends IsarDatabaseRepository {
|
||||||
implements ILogRepository {
|
|
||||||
final Isar _db;
|
final Isar _db;
|
||||||
const IsarLogRepository(super.db) : _db = db;
|
const IsarLogRepository(super.db) : _db = db;
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> deleteAll() async {
|
Future<bool> deleteAll() async {
|
||||||
await transaction(() async => await _db.loggerMessages.clear());
|
await transaction(() async => await _db.loggerMessages.clear());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<LogMessage>> getAll() async {
|
Future<List<LogMessage>> getAll() async {
|
||||||
final logs =
|
final logs =
|
||||||
await _db.loggerMessages.where().sortByCreatedAtDesc().findAll();
|
await _db.loggerMessages.where().sortByCreatedAtDesc().findAll();
|
||||||
return logs.map((l) => l.toDto()).toList();
|
return logs.map((l) => l.toDto()).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> insert(LogMessage log) async {
|
Future<bool> insert(LogMessage log) async {
|
||||||
final logEntity = LoggerMessage.fromDto(log);
|
final logEntity = LoggerMessage.fromDto(log);
|
||||||
await transaction(() async {
|
await transaction(() async {
|
||||||
@@ -31,7 +26,6 @@ class IsarLogRepository extends IsarDatabaseRepository
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> insertAll(Iterable<LogMessage> logs) async {
|
Future<bool> insertAll(Iterable<LogMessage> logs) async {
|
||||||
await transaction(() async {
|
await transaction(() async {
|
||||||
final logEntities =
|
final logEntities =
|
||||||
@@ -41,7 +35,6 @@ class IsarLogRepository extends IsarDatabaseRepository
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> truncate({int limit = 250}) async {
|
Future<void> truncate({int limit = 250}) async {
|
||||||
await transaction(() async {
|
await transaction(() async {
|
||||||
final count = await _db.loggerMessages.count();
|
final count = await _db.loggerMessages.count();
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:immich_mobile/domain/interfaces/storage.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:photo_manager/photo_manager.dart';
|
import 'package:photo_manager/photo_manager.dart';
|
||||||
|
|
||||||
class StorageRepository implements IStorageRepository {
|
class StorageRepository {
|
||||||
final _log = Logger('StorageRepository');
|
final _log = Logger('StorageRepository');
|
||||||
|
|
||||||
@override
|
|
||||||
Future<File?> getFileForAsset(LocalAsset asset) async {
|
Future<File?> getFileForAsset(LocalAsset asset) async {
|
||||||
File? file;
|
File? file;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import 'package:immich_mobile/domain/interfaces/store.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/store.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/store.entity.dart';
|
||||||
@@ -6,14 +5,12 @@ import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
|||||||
import 'package:immich_mobile/infrastructure/repositories/user.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/user.repository.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
class IsarStoreRepository extends IsarDatabaseRepository
|
class IsarStoreRepository extends IsarDatabaseRepository {
|
||||||
implements IStoreRepository {
|
|
||||||
final Isar _db;
|
final Isar _db;
|
||||||
final validStoreKeys = StoreKey.values.map((e) => e.id).toSet();
|
final validStoreKeys = StoreKey.values.map((e) => e.id).toSet();
|
||||||
|
|
||||||
IsarStoreRepository(super.db) : _db = db;
|
IsarStoreRepository(super.db) : _db = db;
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> deleteAll() async {
|
Future<bool> deleteAll() async {
|
||||||
return await transaction(() async {
|
return await transaction(() async {
|
||||||
await _db.storeValues.clear();
|
await _db.storeValues.clear();
|
||||||
@@ -21,7 +18,6 @@ class IsarStoreRepository extends IsarDatabaseRepository
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<StoreDto<Object>> watchAll() {
|
Stream<StoreDto<Object>> watchAll() {
|
||||||
return _db.storeValues
|
return _db.storeValues
|
||||||
.filter()
|
.filter()
|
||||||
@@ -34,12 +30,10 @@ class IsarStoreRepository extends IsarDatabaseRepository
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> delete<T>(StoreKey<T> key) async {
|
Future<void> delete<T>(StoreKey<T> key) async {
|
||||||
return await transaction(() async => await _db.storeValues.delete(key.id));
|
return await transaction(() async => await _db.storeValues.delete(key.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> insert<T>(StoreKey<T> key, T value) async {
|
Future<bool> insert<T>(StoreKey<T> key, T value) async {
|
||||||
return await transaction(() async {
|
return await transaction(() async {
|
||||||
await _db.storeValues.put(await _fromValue(key, value));
|
await _db.storeValues.put(await _fromValue(key, value));
|
||||||
@@ -47,7 +41,6 @@ class IsarStoreRepository extends IsarDatabaseRepository
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<T?> tryGet<T>(StoreKey<T> key) async {
|
Future<T?> tryGet<T>(StoreKey<T> key) async {
|
||||||
final entity = (await _db.storeValues.get(key.id));
|
final entity = (await _db.storeValues.get(key.id));
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
@@ -56,7 +49,6 @@ class IsarStoreRepository extends IsarDatabaseRepository
|
|||||||
return await _toValue(key, entity);
|
return await _toValue(key, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> update<T>(StoreKey<T> key, T value) async {
|
Future<bool> update<T>(StoreKey<T> key, T value) async {
|
||||||
return await transaction(() async {
|
return await transaction(() async {
|
||||||
await _db.storeValues.put(await _fromValue(key, value));
|
await _db.storeValues.put(await _fromValue(key, value));
|
||||||
@@ -64,7 +56,6 @@ class IsarStoreRepository extends IsarDatabaseRepository
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<T?> watch<T>(StoreKey<T> key) async* {
|
Stream<T?> watch<T>(StoreKey<T> key) async* {
|
||||||
yield* _db.storeValues
|
yield* _db.storeValues
|
||||||
.watchObject(key.id, fireImmediately: true)
|
.watchObject(key.id, fireImmediately: true)
|
||||||
@@ -109,7 +100,6 @@ class IsarStoreRepository extends IsarDatabaseRepository
|
|||||||
return StoreValue(key.id, intValue: intValue, strValue: strValue);
|
return StoreValue(key.id, intValue: intValue, strValue: strValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<StoreDto<Object>>> getAll() async {
|
Future<List<StoreDto<Object>>> getAll() async {
|
||||||
final entities = await _db.storeValues
|
final entities = await _db.storeValues
|
||||||
.filter()
|
.filter()
|
||||||
|
|||||||
@@ -3,24 +3,21 @@ import 'dart:convert';
|
|||||||
|
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:immich_mobile/constants/constants.dart';
|
import 'package:immich_mobile/constants/constants.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/sync_api.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/sync_event.model.dart';
|
import 'package:immich_mobile/domain/models/sync_event.model.dart';
|
||||||
import 'package:immich_mobile/presentation/pages/dev/dev_logger.dart';
|
import 'package:immich_mobile/presentation/pages/dev/dev_logger.dart';
|
||||||
import 'package:immich_mobile/services/api.service.dart';
|
import 'package:immich_mobile/services/api.service.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:openapi/api.dart';
|
import 'package:openapi/api.dart';
|
||||||
|
|
||||||
class SyncApiRepository implements ISyncApiRepository {
|
class SyncApiRepository {
|
||||||
final Logger _logger = Logger('SyncApiRepository');
|
final Logger _logger = Logger('SyncApiRepository');
|
||||||
final ApiService _api;
|
final ApiService _api;
|
||||||
SyncApiRepository(this._api);
|
SyncApiRepository(this._api);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> ack(List<String> data) {
|
Future<void> ack(List<String> data) {
|
||||||
return _api.syncApi.sendSyncAck(SyncAckSetDto(acks: data));
|
return _api.syncApi.sendSyncAck(SyncAckSetDto(acks: data));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> streamChanges(
|
Future<void> streamChanges(
|
||||||
Function(List<SyncEvent>, Function() abort) onData, {
|
Function(List<SyncEvent>, Function() abort) onData, {
|
||||||
int batchSize = kSyncEventBatchSize,
|
int batchSize = kSyncEventBatchSize,
|
||||||
|
|||||||
@@ -3,15 +3,13 @@ import 'dart:async';
|
|||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:immich_mobile/constants/constants.dart';
|
import 'package:immich_mobile/constants/constants.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/timeline.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/timeline.model.dart';
|
import 'package:immich_mobile/domain/models/timeline.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||||
import 'package:stream_transform/stream_transform.dart';
|
import 'package:stream_transform/stream_transform.dart';
|
||||||
|
|
||||||
class DriftTimelineRepository extends DriftDatabaseRepository
|
class DriftTimelineRepository extends DriftDatabaseRepository {
|
||||||
implements ITimelineRepository {
|
|
||||||
final Drift _db;
|
final Drift _db;
|
||||||
|
|
||||||
const DriftTimelineRepository(super._db) : _db = _db;
|
const DriftTimelineRepository(super._db) : _db = _db;
|
||||||
@@ -28,7 +26,6 @@ class DriftTimelineRepository extends DriftDatabaseRepository
|
|||||||
return buckets;
|
return buckets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<List<Bucket>> watchMainBucket(
|
Stream<List<Bucket>> watchMainBucket(
|
||||||
List<String> userIds, {
|
List<String> userIds, {
|
||||||
GroupAssetsBy groupBy = GroupAssetsBy.day,
|
GroupAssetsBy groupBy = GroupAssetsBy.day,
|
||||||
@@ -49,7 +46,6 @@ class DriftTimelineRepository extends DriftDatabaseRepository
|
|||||||
.throttle(const Duration(seconds: 3), trailing: true);
|
.throttle(const Duration(seconds: 3), trailing: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<BaseAsset>> getMainBucketAssets(
|
Future<List<BaseAsset>> getMainBucketAssets(
|
||||||
List<String> userIds, {
|
List<String> userIds, {
|
||||||
required int offset,
|
required int offset,
|
||||||
@@ -90,7 +86,6 @@ class DriftTimelineRepository extends DriftDatabaseRepository
|
|||||||
.get();
|
.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<List<Bucket>> watchLocalBucket(
|
Stream<List<Bucket>> watchLocalBucket(
|
||||||
String albumId, {
|
String albumId, {
|
||||||
GroupAssetsBy groupBy = GroupAssetsBy.day,
|
GroupAssetsBy groupBy = GroupAssetsBy.day,
|
||||||
@@ -124,7 +119,6 @@ class DriftTimelineRepository extends DriftDatabaseRepository
|
|||||||
}).watch();
|
}).watch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<BaseAsset>> getLocalBucketAssets(
|
Future<List<BaseAsset>> getLocalBucketAssets(
|
||||||
String albumId, {
|
String albumId, {
|
||||||
required int offset,
|
required int offset,
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
|
||||||
import 'package:immich_mobile/entities/album.entity.dart';
|
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
|
||||||
import 'package:immich_mobile/interfaces/database.interface.dart';
|
|
||||||
import 'package:immich_mobile/models/albums/album_search.model.dart';
|
|
||||||
|
|
||||||
abstract interface class IAlbumRepository implements IDatabaseRepository {
|
|
||||||
Future<Album> create(Album album);
|
|
||||||
|
|
||||||
Future<Album?> get(int id);
|
|
||||||
|
|
||||||
Future<Album?> getByName(
|
|
||||||
String name, {
|
|
||||||
bool? shared,
|
|
||||||
bool? remote,
|
|
||||||
bool? owner,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<List<Album>> getAll({
|
|
||||||
bool? shared,
|
|
||||||
bool? remote,
|
|
||||||
int? ownerId,
|
|
||||||
AlbumSort? sortBy,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<Album> update(Album album);
|
|
||||||
|
|
||||||
Future<void> delete(int albumId);
|
|
||||||
|
|
||||||
Future<void> deleteAllLocal();
|
|
||||||
|
|
||||||
Future<int> count({bool? local});
|
|
||||||
|
|
||||||
Future<void> addUsers(Album album, List<UserDto> users);
|
|
||||||
|
|
||||||
Future<void> removeUsers(Album album, List<UserDto> users);
|
|
||||||
|
|
||||||
Future<void> addAssets(Album album, List<Asset> assets);
|
|
||||||
|
|
||||||
Future<void> removeAssets(Album album, List<Asset> assets);
|
|
||||||
|
|
||||||
Future<Album> recalculateMetadata(Album album);
|
|
||||||
|
|
||||||
Future<List<Album>> search(String searchTerm, QuickFilterMode filterMode);
|
|
||||||
|
|
||||||
Stream<List<Album>> watchRemoteAlbums();
|
|
||||||
|
|
||||||
Stream<List<Album>> watchLocalAlbums();
|
|
||||||
|
|
||||||
Stream<Album?> watchAlbum(int id);
|
|
||||||
|
|
||||||
Future<void> clearTable();
|
|
||||||
}
|
|
||||||
|
|
||||||
enum AlbumSort { remoteId, localId }
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
import 'package:immich_mobile/entities/album.entity.dart';
|
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
|
||||||
import 'package:immich_mobile/interfaces/database.interface.dart';
|
|
||||||
|
|
||||||
abstract interface class IAssetRepository implements IDatabaseRepository {
|
|
||||||
Future<Asset?> getByRemoteId(String id);
|
|
||||||
|
|
||||||
Future<Asset?> getByOwnerIdChecksum(int ownerId, String checksum);
|
|
||||||
|
|
||||||
Future<List<Asset>> getAllByRemoteId(
|
|
||||||
Iterable<String> ids, {
|
|
||||||
AssetState? state,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<List<Asset?>> getAllByOwnerIdChecksum(
|
|
||||||
List<int> ids,
|
|
||||||
List<String> checksums,
|
|
||||||
);
|
|
||||||
|
|
||||||
Future<List<Asset>> getAll({
|
|
||||||
required String ownerId,
|
|
||||||
AssetState? state,
|
|
||||||
AssetSort? sortBy,
|
|
||||||
int? limit,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<List<Asset>> getAllLocal();
|
|
||||||
|
|
||||||
Future<List<Asset>> getByAlbum(
|
|
||||||
Album album, {
|
|
||||||
Iterable<String> notOwnedBy = const [],
|
|
||||||
String? ownerId,
|
|
||||||
AssetState? state,
|
|
||||||
AssetSort? sortBy,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<Asset> update(Asset asset);
|
|
||||||
|
|
||||||
Future<List<Asset>> updateAll(List<Asset> assets);
|
|
||||||
|
|
||||||
Future<void> deleteAllByRemoteId(List<String> ids, {AssetState? state});
|
|
||||||
|
|
||||||
Future<void> deleteByIds(List<int> ids);
|
|
||||||
|
|
||||||
Future<List<Asset>> getMatches({
|
|
||||||
required List<Asset> assets,
|
|
||||||
required String ownerId,
|
|
||||||
AssetState? state,
|
|
||||||
int limit = 100,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<void> upsertDuplicatedAssets(Iterable<String> duplicatedAssets);
|
|
||||||
|
|
||||||
Future<List<String>> getAllDuplicatedAssetIds();
|
|
||||||
|
|
||||||
Future<List<Asset>> getStackAssets(String stackId);
|
|
||||||
|
|
||||||
Future<void> clearTable();
|
|
||||||
|
|
||||||
Stream<Asset?> watchAsset(int id, {bool fireImmediately = false});
|
|
||||||
|
|
||||||
Future<List<Asset>> getTrashAssets(String userId);
|
|
||||||
|
|
||||||
Future<List<Asset>> getRecentlyTakenAssets(String userId);
|
|
||||||
Future<List<Asset>> getMotionAssets(String userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum AssetSort { checksum, ownerIdChecksum }
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import 'package:immich_mobile/constants/enums.dart';
|
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
|
||||||
|
|
||||||
abstract interface class IAssetApiRepository {
|
|
||||||
// Future<Asset> get(String id);
|
|
||||||
|
|
||||||
// Future<List<Asset>> getAll();
|
|
||||||
|
|
||||||
// Future<Asset> create(Asset asset);
|
|
||||||
|
|
||||||
Future<Asset> update(
|
|
||||||
String id, {
|
|
||||||
String? description,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Future<void> delete(String id);
|
|
||||||
|
|
||||||
Future<List<Asset>> search({List<String> personIds = const []});
|
|
||||||
|
|
||||||
Future<void> updateVisibility(
|
|
||||||
List<String> list,
|
|
||||||
AssetVisibilityEnum visibility,
|
|
||||||
);
|
|
||||||
|
|
||||||
Future<String?> getAssetMIMEType(String id);
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
|
||||||
|
|
||||||
abstract interface class IAssetMediaRepository {
|
|
||||||
Future<List<String>> deleteAll(List<String> ids);
|
|
||||||
|
|
||||||
Future<Asset?> get(String id);
|
|
||||||
|
|
||||||
/// Obtaining the correct original filename of the asset
|
|
||||||
Future<String?> getOriginalFilename(String id);
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import 'package:immich_mobile/interfaces/database.interface.dart';
|
|
||||||
import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart';
|
|
||||||
|
|
||||||
abstract interface class IAuthRepository implements IDatabaseRepository {
|
|
||||||
Future<void> clearLocalData();
|
|
||||||
String getAccessToken();
|
|
||||||
bool getEndpointSwitchingFeature();
|
|
||||||
String? getPreferredWifiName();
|
|
||||||
String? getLocalEndpoint();
|
|
||||||
List<AuxilaryEndpoint> getExternalEndpointList();
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import 'package:immich_mobile/models/auth/login_response.model.dart';
|
|
||||||
|
|
||||||
abstract interface class IAuthApiRepository {
|
|
||||||
Future<LoginResponse> login(String email, String password);
|
|
||||||
|
|
||||||
Future<void> logout();
|
|
||||||
|
|
||||||
Future<void> changePassword(String newPassword);
|
|
||||||
|
|
||||||
Future<bool> unlockPinCode(String pinCode);
|
|
||||||
Future<void> lockPinCode();
|
|
||||||
|
|
||||||
Future<void> setupPinCode(String pinCode);
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
|
||||||
import 'package:immich_mobile/interfaces/database.interface.dart';
|
|
||||||
|
|
||||||
abstract interface class IBackupAlbumRepository implements IDatabaseRepository {
|
|
||||||
Future<List<BackupAlbum>> getAll({BackupAlbumSort? sort});
|
|
||||||
|
|
||||||
Future<List<String>> getIdsBySelection(BackupSelection backup);
|
|
||||||
|
|
||||||
Future<List<BackupAlbum>> getAllBySelection(BackupSelection backup);
|
|
||||||
|
|
||||||
Future<void> updateAll(List<BackupAlbum> backupAlbums);
|
|
||||||
|
|
||||||
Future<void> deleteAll(List<int> ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum BackupAlbumSort { id }
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
|
||||||
import 'package:immich_mobile/models/cast/cast_manager_state.dart';
|
|
||||||
|
|
||||||
abstract interface class ICastDestinationService {
|
|
||||||
Future<bool> initialize();
|
|
||||||
CastDestinationType getType();
|
|
||||||
|
|
||||||
void Function(bool)? onConnectionState;
|
|
||||||
|
|
||||||
void Function(Duration)? onCurrentTime;
|
|
||||||
void Function(Duration)? onDuration;
|
|
||||||
|
|
||||||
void Function(String)? onReceiverName;
|
|
||||||
void Function(CastState)? onCastState;
|
|
||||||
|
|
||||||
Future<void> connect(dynamic device);
|
|
||||||
|
|
||||||
void loadMedia(Asset asset, bool reload);
|
|
||||||
|
|
||||||
void play();
|
|
||||||
void pause();
|
|
||||||
void seekTo(Duration position);
|
|
||||||
void stop();
|
|
||||||
Future<void> disconnect();
|
|
||||||
|
|
||||||
Future<List<(String, CastDestinationType, dynamic)>> getDevices();
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import 'package:immich_mobile/entities/etag.entity.dart';
|
|
||||||
import 'package:immich_mobile/interfaces/database.interface.dart';
|
|
||||||
|
|
||||||
abstract interface class IETagRepository implements IDatabaseRepository {
|
|
||||||
Future<ETag?> get(String id);
|
|
||||||
|
|
||||||
Future<ETag?> getById(String id);
|
|
||||||
|
|
||||||
Future<List<String>> getAllIds();
|
|
||||||
|
|
||||||
Future<void> upsertAll(List<ETag> etags);
|
|
||||||
|
|
||||||
Future<void> deleteByIds(List<String> ids);
|
|
||||||
|
|
||||||
Future<void> clearTable();
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
import 'dart:io';
|
|
||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
|
||||||
|
|
||||||
abstract interface class IFileMediaRepository {
|
|
||||||
Future<Asset?> saveImage(
|
|
||||||
Uint8List data, {
|
|
||||||
required String title,
|
|
||||||
String? relativePath,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<Asset?> saveImageWithFile(
|
|
||||||
String filePath, {
|
|
||||||
String? title,
|
|
||||||
String? relativePath,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<Asset?> saveVideo(
|
|
||||||
File file, {
|
|
||||||
required String title,
|
|
||||||
String? relativePath,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<Asset?> saveLivePhoto({
|
|
||||||
required File image,
|
|
||||||
required File video,
|
|
||||||
required String title,
|
|
||||||
});
|
|
||||||
|
|
||||||
Future<void> clearFileCache();
|
|
||||||
|
|
||||||
Future<void> enableBackgroundAccess();
|
|
||||||
|
|
||||||
Future<void> requestExtendedPermissions();
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
|
||||||
|
|
||||||
abstract interface class IFolderApiRepository {
|
|
||||||
Future<List<String>> getAllUniquePaths();
|
|
||||||
Future<List<Asset>> getAssetsForPath(String? path);
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
abstract interface class ILocalFilesManager {
|
|
||||||
Future<bool> moveToTrash(List<String> mediaUrls);
|
|
||||||
Future<bool> restoreFromTrash(String fileName, int type);
|
|
||||||
Future<bool> requestManageMediaPermission();
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
|
||||||
|
|
||||||
abstract class IPartnerRepository {
|
|
||||||
Future<List<UserDto>> getSharedWith();
|
|
||||||
Future<List<UserDto>> getSharedBy();
|
|
||||||
Stream<List<UserDto>> watchSharedWith();
|
|
||||||
Stream<List<UserDto>> watchSharedBy();
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
|
||||||
|
|
||||||
abstract interface class IPartnerApiRepository {
|
|
||||||
Future<List<UserDto>> getAll(Direction direction);
|
|
||||||
Future<UserDto> create(String id);
|
|
||||||
Future<UserDto> update(String id, {required bool inTimeline});
|
|
||||||
Future<void> delete(String id);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Direction {
|
|
||||||
sharedWithMe,
|
|
||||||
sharedByMe,
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
import 'package:immich_mobile/entities/album.entity.dart';
|
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
|
||||||
import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
|
|
||||||
|
|
||||||
abstract class ITimelineRepository {
|
|
||||||
Future<List<String>> getTimelineUserIds(String id);
|
|
||||||
|
|
||||||
Stream<List<String>> watchTimelineUsers(String id);
|
|
||||||
|
|
||||||
Stream<RenderList> watchArchiveTimeline(String userId);
|
|
||||||
Stream<RenderList> watchFavoriteTimeline(String userId);
|
|
||||||
Stream<RenderList> watchTrashTimeline(String userId);
|
|
||||||
Stream<RenderList> watchAlbumTimeline(
|
|
||||||
Album album,
|
|
||||||
GroupAssetsBy groupAssetsBy,
|
|
||||||
);
|
|
||||||
Stream<RenderList> watchAllVideosTimeline(String userId);
|
|
||||||
|
|
||||||
Stream<RenderList> watchHomeTimeline(
|
|
||||||
String userId,
|
|
||||||
GroupAssetsBy groupAssetsBy,
|
|
||||||
);
|
|
||||||
Stream<RenderList> watchMultiUsersTimeline(
|
|
||||||
List<String> userIds,
|
|
||||||
GroupAssetsBy groupAssetsBy,
|
|
||||||
);
|
|
||||||
|
|
||||||
Future<RenderList> getTimelineFromAssets(
|
|
||||||
List<Asset> assets,
|
|
||||||
GroupAssetsBy getGroupByOption,
|
|
||||||
);
|
|
||||||
|
|
||||||
Stream<RenderList> watchAssetSelectionTimeline(String userId);
|
|
||||||
|
|
||||||
Stream<RenderList> watchLockedTimeline(
|
|
||||||
String userId,
|
|
||||||
GroupAssetsBy groupAssetsBy,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import 'package:background_downloader/background_downloader.dart';
|
|
||||||
|
|
||||||
abstract interface class IUploadRepository {
|
|
||||||
void Function(TaskStatusUpdate)? onUploadStatus;
|
|
||||||
void Function(TaskProgressUpdate)? onTaskProgress;
|
|
||||||
|
|
||||||
Future<bool> upload(UploadTask task);
|
|
||||||
Future<bool> cancel(String id);
|
|
||||||
Future<void> deleteAllTrackingRecords();
|
|
||||||
Future<void> deleteRecordsWithIds(List<String> id);
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
abstract interface class IWidgetRepository {
|
|
||||||
Future<void> saveData(String key, String value);
|
|
||||||
Future<void> refresh(String name);
|
|
||||||
Future<void> setAppGroupId(String appGroupId);
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:immich_mobile/domain/models/person.model.dart';
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
import 'package:immich_mobile/interfaces/person_api.interface.dart';
|
|
||||||
|
|
||||||
class SearchLocationFilter {
|
class SearchLocationFilter {
|
||||||
String? country;
|
String? country;
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/constants/enums.dart';
|
import 'package:immich_mobile/constants/enums.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/person.model.dart';
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/interfaces/person_api.interface.dart';
|
|
||||||
import 'package:immich_mobile/models/search/search_filter.model.dart';
|
import 'package:immich_mobile/models/search/search_filter.model.dart';
|
||||||
import 'package:immich_mobile/providers/search/paginated_search.provider.dart';
|
import 'package:immich_mobile/providers/search/paginated_search.provider.dart';
|
||||||
import 'package:immich_mobile/providers/search/search_input_focus.provider.dart';
|
import 'package:immich_mobile/providers/search/search_input_focus.provider.dart';
|
||||||
|
|||||||
@@ -4,14 +4,13 @@ import 'dart:ui';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/asset_media.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/asset_media.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/asset_media.repository.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/timeline/constants.dart';
|
import 'package:immich_mobile/presentation/widgets/timeline/constants.dart';
|
||||||
import 'package:immich_mobile/providers/image/cache/thumbnail_image_cache_manager.dart';
|
import 'package:immich_mobile/providers/image/cache/thumbnail_image_cache_manager.dart';
|
||||||
|
|
||||||
class LocalThumbProvider extends ImageProvider<LocalThumbProvider> {
|
class LocalThumbProvider extends ImageProvider<LocalThumbProvider> {
|
||||||
final IAssetMediaRepository _assetMediaRepository =
|
final AssetMediaRepository _assetMediaRepository =
|
||||||
const AssetMediaRepository();
|
const AssetMediaRepository();
|
||||||
final CacheManager? cacheManager;
|
final CacheManager? cacheManager;
|
||||||
|
|
||||||
|
|||||||
@@ -118,10 +118,8 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||||||
}) async {
|
}) async {
|
||||||
await _apiService.setAccessToken(accessToken);
|
await _apiService.setAccessToken(accessToken);
|
||||||
|
|
||||||
await _widgetService.writeCredentials(
|
await _widgetService.writeSessionKey(accessToken);
|
||||||
Store.get(StoreKey.serverEndpoint),
|
await _widgetService.writeServerList();
|
||||||
accessToken,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Get the deviceid from the store if it exists, otherwise generate a new one
|
// Get the deviceid from the store if it exists, otherwise generate a new one
|
||||||
String deviceId =
|
String deviceId =
|
||||||
@@ -190,6 +188,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
|
|||||||
|
|
||||||
Future<void> saveLocalEndpoint(String url) async {
|
Future<void> saveLocalEndpoint(String url) async {
|
||||||
await Store.put(StoreKey.localEndpoint, url);
|
await Store.put(StoreKey.localEndpoint, url);
|
||||||
|
await _widgetService.writeServerList();
|
||||||
}
|
}
|
||||||
|
|
||||||
String? getSavedWifiName() {
|
String? getSavedWifiName() {
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ import 'package:immich_mobile/domain/models/store.model.dart';
|
|||||||
import 'package:immich_mobile/entities/album.entity.dart';
|
import 'package:immich_mobile/entities/album.entity.dart';
|
||||||
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
||||||
import 'package:immich_mobile/entities/store.entity.dart';
|
import 'package:immich_mobile/entities/store.entity.dart';
|
||||||
import 'package:immich_mobile/interfaces/backup_album.interface.dart';
|
|
||||||
import 'package:immich_mobile/interfaces/file_media.interface.dart';
|
|
||||||
import 'package:immich_mobile/models/auth/auth_state.model.dart';
|
import 'package:immich_mobile/models/auth/auth_state.model.dart';
|
||||||
import 'package:immich_mobile/models/backup/available_album.model.dart';
|
import 'package:immich_mobile/models/backup/available_album.model.dart';
|
||||||
import 'package:immich_mobile/models/backup/backup_candidate.model.dart';
|
import 'package:immich_mobile/models/backup/backup_candidate.model.dart';
|
||||||
@@ -24,6 +22,7 @@ import 'package:immich_mobile/providers/auth.provider.dart';
|
|||||||
import 'package:immich_mobile/providers/backup/error_backup_list.provider.dart';
|
import 'package:immich_mobile/providers/backup/error_backup_list.provider.dart';
|
||||||
import 'package:immich_mobile/providers/gallery_permission.provider.dart';
|
import 'package:immich_mobile/providers/gallery_permission.provider.dart';
|
||||||
import 'package:immich_mobile/repositories/album_media.repository.dart';
|
import 'package:immich_mobile/repositories/album_media.repository.dart';
|
||||||
|
import 'package:immich_mobile/repositories/backup.repository.dart';
|
||||||
import 'package:immich_mobile/repositories/file_media.repository.dart';
|
import 'package:immich_mobile/repositories/file_media.repository.dart';
|
||||||
import 'package:immich_mobile/services/background.service.dart';
|
import 'package:immich_mobile/services/background.service.dart';
|
||||||
import 'package:immich_mobile/services/backup.service.dart';
|
import 'package:immich_mobile/services/backup.service.dart';
|
||||||
@@ -108,7 +107,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|||||||
final BackgroundService _backgroundService;
|
final BackgroundService _backgroundService;
|
||||||
final GalleryPermissionNotifier _galleryPermissionNotifier;
|
final GalleryPermissionNotifier _galleryPermissionNotifier;
|
||||||
final AlbumMediaRepository _albumMediaRepository;
|
final AlbumMediaRepository _albumMediaRepository;
|
||||||
final IFileMediaRepository _fileMediaRepository;
|
final FileMediaRepository _fileMediaRepository;
|
||||||
final BackupAlbumService _backupAlbumService;
|
final BackupAlbumService _backupAlbumService;
|
||||||
final Ref ref;
|
final Ref ref;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
import 'package:immich_mobile/interfaces/cast_destination_service.interface.dart';
|
|
||||||
import 'package:immich_mobile/models/cast/cast_manager_state.dart';
|
import 'package:immich_mobile/models/cast/cast_manager_state.dart';
|
||||||
import 'package:immich_mobile/services/gcast.service.dart';
|
import 'package:immich_mobile/services/gcast.service.dart';
|
||||||
|
|
||||||
@@ -10,7 +9,7 @@ final castProvider = StateNotifierProvider<CastNotifier, CastManagerState>(
|
|||||||
|
|
||||||
class CastNotifier extends StateNotifier<CastManagerState> {
|
class CastNotifier extends StateNotifier<CastManagerState> {
|
||||||
// more cast providers can be added here (ie Fcast)
|
// more cast providers can be added here (ie Fcast)
|
||||||
final ICastDestinationService _gCastService;
|
final GCastService _gCastService;
|
||||||
|
|
||||||
List<(String, CastDestinationType, dynamic)> discovered = List.empty();
|
List<(String, CastDestinationType, dynamic)> discovered = List.empty();
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/local_album.interface.dart';
|
|
||||||
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||||
|
|
||||||
final localAlbumRepository = Provider<ILocalAlbumRepository>(
|
final localAlbumRepository = Provider<DriftLocalAlbumRepository>(
|
||||||
(ref) => DriftLocalAlbumRepository(ref.watch(driftProvider)),
|
(ref) => DriftLocalAlbumRepository(ref.watch(driftProvider)),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/local_asset.interface.dart';
|
|
||||||
import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||||
|
|
||||||
final localAssetRepository = Provider<ILocalAssetRepository>(
|
final localAssetRepository = Provider<DriftLocalAssetRepository>(
|
||||||
(ref) => DriftLocalAssetRepository(ref.watch(driftProvider)),
|
(ref) => DriftLocalAssetRepository(ref.watch(driftProvider)),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/device_asset.interface.dart';
|
|
||||||
import 'package:immich_mobile/infrastructure/repositories/device_asset.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/device_asset.repository.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||||
|
|
||||||
final deviceAssetRepositoryProvider = Provider<IDeviceAssetRepository>(
|
final deviceAssetRepositoryProvider = Provider<IsarDeviceAssetRepository>(
|
||||||
(ref) => IsarDeviceAssetRepository(ref.watch(isarProvider)),
|
(ref) => IsarDeviceAssetRepository(ref.watch(isarProvider)),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/exif.interface.dart';
|
|
||||||
import 'package:immich_mobile/infrastructure/repositories/exif.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/exif.repository.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
@@ -7,5 +6,5 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|||||||
part 'exif.provider.g.dart';
|
part 'exif.provider.g.dart';
|
||||||
|
|
||||||
@Riverpod(keepAlive: true)
|
@Riverpod(keepAlive: true)
|
||||||
IExifInfoRepository exifRepository(Ref ref) =>
|
IsarExifRepository exifRepository(Ref ref) =>
|
||||||
IsarExifRepository(ref.watch(isarProvider));
|
IsarExifRepository(ref.watch(isarProvider));
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ part of 'exif.provider.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$exifRepositoryHash() => r'f0abe778ed61fbb257001fdf2ac6e17814011fee';
|
String _$exifRepositoryHash() => r'bf4a3f6a50d954a23d317659b4f3e2f381066463';
|
||||||
|
|
||||||
/// See also [exifRepository].
|
/// See also [exifRepository].
|
||||||
@ProviderFor(exifRepository)
|
@ProviderFor(exifRepository)
|
||||||
final exifRepositoryProvider = Provider<IExifInfoRepository>.internal(
|
final exifRepositoryProvider = Provider<IsarExifRepository>.internal(
|
||||||
exifRepository,
|
exifRepository,
|
||||||
name: r'exifRepositoryProvider',
|
name: r'exifRepositoryProvider',
|
||||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||||
@@ -22,6 +22,6 @@ final exifRepositoryProvider = Provider<IExifInfoRepository>.internal(
|
|||||||
|
|
||||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
typedef ExifRepositoryRef = ProviderRef<IExifInfoRepository>;
|
typedef ExifRepositoryRef = ProviderRef<IsarExifRepository>;
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/storage.interface.dart';
|
|
||||||
import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart';
|
||||||
|
|
||||||
final storageRepositoryProvider = Provider<IStorageRepository>(
|
final storageRepositoryProvider = Provider<StorageRepository>(
|
||||||
(ref) => StorageRepository(),
|
(ref) => StorageRepository(),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/store.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/services/store.service.dart';
|
import 'package:immich_mobile/domain/services/store.service.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||||
@@ -8,7 +7,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|||||||
part 'store.provider.g.dart';
|
part 'store.provider.g.dart';
|
||||||
|
|
||||||
@Riverpod(keepAlive: true)
|
@Riverpod(keepAlive: true)
|
||||||
IStoreRepository storeRepository(Ref ref) =>
|
IsarStoreRepository storeRepository(Ref ref) =>
|
||||||
IsarStoreRepository(ref.watch(isarProvider));
|
IsarStoreRepository(ref.watch(isarProvider));
|
||||||
|
|
||||||
@Riverpod(keepAlive: true)
|
@Riverpod(keepAlive: true)
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ part of 'store.provider.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$storeRepositoryHash() => r'99d24875d30c5e86b1c6caa352a0026167114e62';
|
String _$storeRepositoryHash() => r'659cb134466e4b0d5f04e2fc93e426350d99545f';
|
||||||
|
|
||||||
/// See also [storeRepository].
|
/// See also [storeRepository].
|
||||||
@ProviderFor(storeRepository)
|
@ProviderFor(storeRepository)
|
||||||
final storeRepositoryProvider = Provider<IStoreRepository>.internal(
|
final storeRepositoryProvider = Provider<IsarStoreRepository>.internal(
|
||||||
storeRepository,
|
storeRepository,
|
||||||
name: r'storeRepositoryProvider',
|
name: r'storeRepositoryProvider',
|
||||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||||
@@ -22,7 +22,7 @@ final storeRepositoryProvider = Provider<IStoreRepository>.internal(
|
|||||||
|
|
||||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
typedef StoreRepositoryRef = ProviderRef<IStoreRepository>;
|
typedef StoreRepositoryRef = ProviderRef<IsarStoreRepository>;
|
||||||
String _$storeServiceHash() => r'250e10497c42df360e9e1f9a618d0b19c1b5b0a0';
|
String _$storeServiceHash() => r'250e10497c42df360e9e1f9a618d0b19c1b5b0a0';
|
||||||
|
|
||||||
/// See also [storeService].
|
/// See also [storeService].
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/timeline.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/services/timeline.service.dart';
|
import 'package:immich_mobile/domain/services/timeline.service.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/timeline.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/timeline.repository.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/timeline/timeline.state.dart';
|
import 'package:immich_mobile/presentation/widgets/timeline/timeline.state.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/setting.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/setting.provider.dart';
|
||||||
|
|
||||||
final timelineRepositoryProvider = Provider<ITimelineRepository>(
|
final timelineRepositoryProvider = Provider<DriftTimelineRepository>(
|
||||||
(ref) => DriftTimelineRepository(ref.watch(driftProvider)),
|
(ref) => DriftTimelineRepository(ref.watch(driftProvider)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/interfaces/person_api.interface.dart';
|
import 'package:immich_mobile/domain/models/person.model.dart';
|
||||||
import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
|
import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
|
||||||
import 'package:immich_mobile/services/person.service.dart';
|
import 'package:immich_mobile/services/person.service.dart';
|
||||||
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
||||||
|
|||||||
@@ -6,20 +6,20 @@ import 'package:immich_mobile/entities/asset.entity.dart';
|
|||||||
import 'package:immich_mobile/entities/store.entity.dart';
|
import 'package:immich_mobile/entities/store.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/user.entity.dart'
|
import 'package:immich_mobile/infrastructure/entities/user.entity.dart'
|
||||||
as entity;
|
as entity;
|
||||||
import 'package:immich_mobile/interfaces/album.interface.dart';
|
|
||||||
import 'package:immich_mobile/models/albums/album_search.model.dart';
|
import 'package:immich_mobile/models/albums/album_search.model.dart';
|
||||||
import 'package:immich_mobile/providers/db.provider.dart';
|
import 'package:immich_mobile/providers/db.provider.dart';
|
||||||
import 'package:immich_mobile/repositories/database.repository.dart';
|
import 'package:immich_mobile/repositories/database.repository.dart';
|
||||||
import 'package:immich_mobile/utils/hash.dart';
|
import 'package:immich_mobile/utils/hash.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
|
enum AlbumSort { remoteId, localId }
|
||||||
|
|
||||||
final albumRepositoryProvider =
|
final albumRepositoryProvider =
|
||||||
Provider((ref) => AlbumRepository(ref.watch(dbProvider)));
|
Provider((ref) => AlbumRepository(ref.watch(dbProvider)));
|
||||||
|
|
||||||
class AlbumRepository extends DatabaseRepository implements IAlbumRepository {
|
class AlbumRepository extends DatabaseRepository {
|
||||||
AlbumRepository(super.db);
|
AlbumRepository(super.db);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<int> count({bool? local}) {
|
Future<int> count({bool? local}) {
|
||||||
final baseQuery = db.albums.where();
|
final baseQuery = db.albums.where();
|
||||||
final QueryBuilder<Album, Album, QAfterWhereClause> query = switch (local) {
|
final QueryBuilder<Album, Album, QAfterWhereClause> query = switch (local) {
|
||||||
@@ -30,10 +30,8 @@ class AlbumRepository extends DatabaseRepository implements IAlbumRepository {
|
|||||||
return query.count();
|
return query.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Album> create(Album album) => txn(() => db.albums.store(album));
|
Future<Album> create(Album album) => txn(() => db.albums.store(album));
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Album?> getByName(
|
Future<Album?> getByName(
|
||||||
String name, {
|
String name, {
|
||||||
bool? shared,
|
bool? shared,
|
||||||
@@ -58,13 +56,10 @@ class AlbumRepository extends DatabaseRepository implements IAlbumRepository {
|
|||||||
return query.findFirst();
|
return query.findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Album> update(Album album) => txn(() => db.albums.store(album));
|
Future<Album> update(Album album) => txn(() => db.albums.store(album));
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> delete(int albumId) => txn(() => db.albums.delete(albumId));
|
Future<void> delete(int albumId) => txn(() => db.albums.delete(albumId));
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Album>> getAll({
|
Future<List<Album>> getAll({
|
||||||
bool? shared,
|
bool? shared,
|
||||||
bool? remote,
|
bool? remote,
|
||||||
@@ -96,23 +91,18 @@ class AlbumRepository extends DatabaseRepository implements IAlbumRepository {
|
|||||||
return query.findAll();
|
return query.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Album?> get(int id) => db.albums.get(id);
|
Future<Album?> get(int id) => db.albums.get(id);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> removeUsers(Album album, List<UserDto> users) => txn(
|
Future<void> removeUsers(Album album, List<UserDto> users) => txn(
|
||||||
() => album.sharedUsers.update(unlink: users.map(entity.User.fromDto)),
|
() => album.sharedUsers.update(unlink: users.map(entity.User.fromDto)),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> addAssets(Album album, List<Asset> assets) =>
|
Future<void> addAssets(Album album, List<Asset> assets) =>
|
||||||
txn(() => album.assets.update(link: assets));
|
txn(() => album.assets.update(link: assets));
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> removeAssets(Album album, List<Asset> assets) =>
|
Future<void> removeAssets(Album album, List<Asset> assets) =>
|
||||||
txn(() => album.assets.update(unlink: assets));
|
txn(() => album.assets.update(unlink: assets));
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Album> recalculateMetadata(Album album) async {
|
Future<Album> recalculateMetadata(Album album) async {
|
||||||
album.startDate = await album.assets.filter().fileCreatedAtProperty().min();
|
album.startDate = await album.assets.filter().fileCreatedAtProperty().min();
|
||||||
album.endDate = await album.assets.filter().fileCreatedAtProperty().max();
|
album.endDate = await album.assets.filter().fileCreatedAtProperty().max();
|
||||||
@@ -121,15 +111,12 @@ class AlbumRepository extends DatabaseRepository implements IAlbumRepository {
|
|||||||
return album;
|
return album;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> addUsers(Album album, List<UserDto> users) =>
|
Future<void> addUsers(Album album, List<UserDto> users) =>
|
||||||
txn(() => album.sharedUsers.update(link: users.map(entity.User.fromDto)));
|
txn(() => album.sharedUsers.update(link: users.map(entity.User.fromDto)));
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> deleteAllLocal() =>
|
Future<void> deleteAllLocal() =>
|
||||||
txn(() => db.albums.where().localIdIsNotNull().deleteAll());
|
txn(() => db.albums.where().localIdIsNotNull().deleteAll());
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Album>> search(
|
Future<List<Album>> search(
|
||||||
String searchTerm,
|
String searchTerm,
|
||||||
QuickFilterMode filterMode,
|
QuickFilterMode filterMode,
|
||||||
@@ -152,24 +139,20 @@ class AlbumRepository extends DatabaseRepository implements IAlbumRepository {
|
|||||||
return await query.findAll();
|
return await query.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> clearTable() async {
|
Future<void> clearTable() async {
|
||||||
await txn(() async {
|
await txn(() async {
|
||||||
await db.albums.clear();
|
await db.albums.clear();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<List<Album>> watchRemoteAlbums() {
|
Stream<List<Album>> watchRemoteAlbums() {
|
||||||
return db.albums.where().remoteIdIsNotNull().watch();
|
return db.albums.where().remoteIdIsNotNull().watch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<List<Album>> watchLocalAlbums() {
|
Stream<List<Album>> watchLocalAlbums() {
|
||||||
return db.albums.where().localIdIsNotNull().watch();
|
return db.albums.where().localIdIsNotNull().watch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<Album?> watchAlbum(int id) {
|
Stream<Album?> watchAlbum(int id) {
|
||||||
return db.albums.watchObject(id, fireImmediately: true);
|
return db.albums.watchObject(id, fireImmediately: true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,19 +4,19 @@ import 'package:immich_mobile/entities/album.entity.dart';
|
|||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
import 'package:immich_mobile/entities/duplicated_asset.entity.dart';
|
import 'package:immich_mobile/entities/duplicated_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/exif.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/exif.entity.dart';
|
||||||
import 'package:immich_mobile/interfaces/asset.interface.dart';
|
|
||||||
import 'package:immich_mobile/providers/db.provider.dart';
|
import 'package:immich_mobile/providers/db.provider.dart';
|
||||||
import 'package:immich_mobile/repositories/database.repository.dart';
|
import 'package:immich_mobile/repositories/database.repository.dart';
|
||||||
import 'package:immich_mobile/utils/hash.dart';
|
import 'package:immich_mobile/utils/hash.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
|
enum AssetSort { checksum, ownerIdChecksum }
|
||||||
|
|
||||||
final assetRepositoryProvider =
|
final assetRepositoryProvider =
|
||||||
Provider((ref) => AssetRepository(ref.watch(dbProvider)));
|
Provider((ref) => AssetRepository(ref.watch(dbProvider)));
|
||||||
|
|
||||||
class AssetRepository extends DatabaseRepository implements IAssetRepository {
|
class AssetRepository extends DatabaseRepository {
|
||||||
AssetRepository(super.db);
|
AssetRepository(super.db);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Asset>> getByAlbum(
|
Future<List<Asset>> getByAlbum(
|
||||||
Album album, {
|
Album album, {
|
||||||
Iterable<String> notOwnedBy = const [],
|
Iterable<String> notOwnedBy = const [],
|
||||||
@@ -54,16 +54,13 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository {
|
|||||||
return sortedQuery.findAll();
|
return sortedQuery.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> deleteByIds(List<int> ids) => txn(() async {
|
Future<void> deleteByIds(List<int> ids) => txn(() async {
|
||||||
await db.assets.deleteAll(ids);
|
await db.assets.deleteAll(ids);
|
||||||
await db.exifInfos.deleteAll(ids);
|
await db.exifInfos.deleteAll(ids);
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Asset?> getByRemoteId(String id) => db.assets.getByRemoteId(id);
|
Future<Asset?> getByRemoteId(String id) => db.assets.getByRemoteId(id);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Asset>> getAllByRemoteId(
|
Future<List<Asset>> getAllByRemoteId(
|
||||||
Iterable<String> ids, {
|
Iterable<String> ids, {
|
||||||
AssetState? state,
|
AssetState? state,
|
||||||
@@ -88,7 +85,6 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Asset>> getAll({
|
Future<List<Asset>> getAll({
|
||||||
required String ownerId,
|
required String ownerId,
|
||||||
AssetState? state,
|
AssetState? state,
|
||||||
@@ -127,13 +123,11 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository {
|
|||||||
return limit == null ? query.findAll() : query.limit(limit).findAll();
|
return limit == null ? query.findAll() : query.limit(limit).findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Asset>> updateAll(List<Asset> assets) async {
|
Future<List<Asset>> updateAll(List<Asset> assets) async {
|
||||||
await txn(() => db.assets.putAll(assets));
|
await txn(() => db.assets.putAll(assets));
|
||||||
return assets;
|
return assets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Asset>> getMatches({
|
Future<List<Asset>> getMatches({
|
||||||
required List<Asset> assets,
|
required List<Asset> assets,
|
||||||
required String ownerId,
|
required String ownerId,
|
||||||
@@ -154,42 +148,34 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository {
|
|||||||
return _getMatchesImpl(query, fastHash(ownerId), assets, limit);
|
return _getMatchesImpl(query, fastHash(ownerId), assets, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Asset> update(Asset asset) async {
|
Future<Asset> update(Asset asset) async {
|
||||||
await txn(() => asset.put(db));
|
await txn(() => asset.put(db));
|
||||||
return asset;
|
return asset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> upsertDuplicatedAssets(Iterable<String> duplicatedAssets) => txn(
|
Future<void> upsertDuplicatedAssets(Iterable<String> duplicatedAssets) => txn(
|
||||||
() => db.duplicatedAssets
|
() => db.duplicatedAssets
|
||||||
.putAll(duplicatedAssets.map(DuplicatedAsset.new).toList()),
|
.putAll(duplicatedAssets.map(DuplicatedAsset.new).toList()),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<String>> getAllDuplicatedAssetIds() =>
|
Future<List<String>> getAllDuplicatedAssetIds() =>
|
||||||
db.duplicatedAssets.where().idProperty().findAll();
|
db.duplicatedAssets.where().idProperty().findAll();
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Asset?> getByOwnerIdChecksum(int ownerId, String checksum) =>
|
Future<Asset?> getByOwnerIdChecksum(int ownerId, String checksum) =>
|
||||||
db.assets.getByOwnerIdChecksum(ownerId, checksum);
|
db.assets.getByOwnerIdChecksum(ownerId, checksum);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Asset?>> getAllByOwnerIdChecksum(
|
Future<List<Asset?>> getAllByOwnerIdChecksum(
|
||||||
List<int> ownerIds,
|
List<int> ownerIds,
|
||||||
List<String> checksums,
|
List<String> checksums,
|
||||||
) =>
|
) =>
|
||||||
db.assets.getAllByOwnerIdChecksum(ownerIds, checksums);
|
db.assets.getAllByOwnerIdChecksum(ownerIds, checksums);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Asset>> getAllLocal() =>
|
Future<List<Asset>> getAllLocal() =>
|
||||||
db.assets.where().localIdIsNotNull().findAll();
|
db.assets.where().localIdIsNotNull().findAll();
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> deleteAllByRemoteId(List<String> ids, {AssetState? state}) =>
|
Future<void> deleteAllByRemoteId(List<String> ids, {AssetState? state}) =>
|
||||||
txn(() => _getAllByRemoteIdImpl(ids, state).deleteAll());
|
txn(() => _getAllByRemoteIdImpl(ids, state).deleteAll());
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Asset>> getStackAssets(String stackId) {
|
Future<List<Asset>> getStackAssets(String stackId) {
|
||||||
return db.assets
|
return db.assets
|
||||||
.filter()
|
.filter()
|
||||||
@@ -202,19 +188,16 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository {
|
|||||||
.findAll();
|
.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> clearTable() async {
|
Future<void> clearTable() async {
|
||||||
await txn(() async {
|
await txn(() async {
|
||||||
await db.assets.clear();
|
await db.assets.clear();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<Asset?> watchAsset(int id, {bool fireImmediately = false}) {
|
Stream<Asset?> watchAsset(int id, {bool fireImmediately = false}) {
|
||||||
return db.assets.watchObject(id, fireImmediately: fireImmediately);
|
return db.assets.watchObject(id, fireImmediately: fireImmediately);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Asset>> getTrashAssets(String userId) {
|
Future<List<Asset>> getTrashAssets(String userId) {
|
||||||
return db.assets
|
return db.assets
|
||||||
.where()
|
.where()
|
||||||
@@ -225,7 +208,6 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository {
|
|||||||
.findAll();
|
.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Asset>> getRecentlyTakenAssets(String userId) {
|
Future<List<Asset>> getRecentlyTakenAssets(String userId) {
|
||||||
return db.assets
|
return db.assets
|
||||||
.where()
|
.where()
|
||||||
@@ -236,7 +218,6 @@ class AssetRepository extends DatabaseRepository implements IAssetRepository {
|
|||||||
.findAll();
|
.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Asset>> getMotionAssets(String userId) {
|
Future<List<Asset>> getMotionAssets(String userId) {
|
||||||
return db.assets
|
return db.assets
|
||||||
.where()
|
.where()
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/constants/enums.dart';
|
import 'package:immich_mobile/constants/enums.dart';
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
import 'package:immich_mobile/interfaces/asset_api.interface.dart';
|
|
||||||
import 'package:immich_mobile/providers/api.provider.dart';
|
import 'package:immich_mobile/providers/api.provider.dart';
|
||||||
import 'package:immich_mobile/repositories/api.repository.dart';
|
import 'package:immich_mobile/repositories/api.repository.dart';
|
||||||
import 'package:openapi/api.dart';
|
import 'package:openapi/api.dart';
|
||||||
@@ -13,13 +12,12 @@ final assetApiRepositoryProvider = Provider(
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
class AssetApiRepository extends ApiRepository implements IAssetApiRepository {
|
class AssetApiRepository extends ApiRepository {
|
||||||
final AssetsApi _api;
|
final AssetsApi _api;
|
||||||
final SearchApi _searchApi;
|
final SearchApi _searchApi;
|
||||||
|
|
||||||
AssetApiRepository(this._api, this._searchApi);
|
AssetApiRepository(this._api, this._searchApi);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Asset> update(String id, {String? description}) async {
|
Future<Asset> update(String id, {String? description}) async {
|
||||||
final response = await checkNull(
|
final response = await checkNull(
|
||||||
_api.updateAsset(id, UpdateAssetDto(description: description)),
|
_api.updateAsset(id, UpdateAssetDto(description: description)),
|
||||||
@@ -27,7 +25,6 @@ class AssetApiRepository extends ApiRepository implements IAssetApiRepository {
|
|||||||
return Asset.remote(response);
|
return Asset.remote(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Asset>> search({List<String> personIds = const []}) async {
|
Future<List<Asset>> search({List<String> personIds = const []}) async {
|
||||||
// TODO this always fetches all assets, change API and usage to actually do pagination
|
// TODO this always fetches all assets, change API and usage to actually do pagination
|
||||||
final List<Asset> result = [];
|
final List<Asset> result = [];
|
||||||
@@ -50,7 +47,6 @@ class AssetApiRepository extends ApiRepository implements IAssetApiRepository {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> updateVisibility(
|
Future<void> updateVisibility(
|
||||||
List<String> ids,
|
List<String> ids,
|
||||||
AssetVisibilityEnum visibility,
|
AssetVisibilityEnum visibility,
|
||||||
@@ -73,7 +69,6 @@ class AssetApiRepository extends ApiRepository implements IAssetApiRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<String?> getAssetMIMEType(String assetId) async {
|
Future<String?> getAssetMIMEType(String assetId) async {
|
||||||
final response = await checkNull(_api.getAssetInfo(assetId));
|
final response = await checkNull(_api.getAssetInfo(assetId));
|
||||||
|
|
||||||
|
|||||||
@@ -3,18 +3,15 @@ import 'package:immich_mobile/domain/models/exif.model.dart';
|
|||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
import 'package:immich_mobile/entities/store.entity.dart';
|
import 'package:immich_mobile/entities/store.entity.dart';
|
||||||
import 'package:immich_mobile/interfaces/asset_media.interface.dart';
|
|
||||||
import 'package:immich_mobile/utils/hash.dart';
|
import 'package:immich_mobile/utils/hash.dart';
|
||||||
import 'package:photo_manager/photo_manager.dart' hide AssetType;
|
import 'package:photo_manager/photo_manager.dart' hide AssetType;
|
||||||
|
|
||||||
final assetMediaRepositoryProvider = Provider((ref) => AssetMediaRepository());
|
final assetMediaRepositoryProvider = Provider((ref) => AssetMediaRepository());
|
||||||
|
|
||||||
class AssetMediaRepository implements IAssetMediaRepository {
|
class AssetMediaRepository {
|
||||||
@override
|
|
||||||
Future<List<String>> deleteAll(List<String> ids) =>
|
Future<List<String>> deleteAll(List<String> ids) =>
|
||||||
PhotoManager.editor.deleteWithIds(ids);
|
PhotoManager.editor.deleteWithIds(ids);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Asset?> get(String id) async {
|
Future<Asset?> get(String id) async {
|
||||||
final entity = await AssetEntity.fromId(id);
|
final entity = await AssetEntity.fromId(id);
|
||||||
return toAsset(entity);
|
return toAsset(entity);
|
||||||
@@ -47,7 +44,6 @@ class AssetMediaRepository implements IAssetMediaRepository {
|
|||||||
return asset;
|
return asset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<String?> getOriginalFilename(String id) async {
|
Future<String?> getOriginalFilename(String id) async {
|
||||||
final entity = await AssetEntity.fromId(id);
|
final entity = await AssetEntity.fromId(id);
|
||||||
|
|
||||||
|
|||||||
@@ -10,23 +10,20 @@ import 'package:immich_mobile/entities/store.entity.dart';
|
|||||||
import 'package:immich_mobile/infrastructure/entities/exif.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/exif.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||||
import 'package:immich_mobile/interfaces/auth.interface.dart';
|
|
||||||
import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart';
|
import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart';
|
||||||
import 'package:immich_mobile/providers/db.provider.dart';
|
import 'package:immich_mobile/providers/db.provider.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||||
import 'package:immich_mobile/repositories/database.repository.dart';
|
import 'package:immich_mobile/repositories/database.repository.dart';
|
||||||
|
|
||||||
final authRepositoryProvider = Provider<IAuthRepository>(
|
final authRepositoryProvider = Provider<AuthRepository>(
|
||||||
(ref) =>
|
(ref) => AuthRepository(ref.watch(dbProvider), ref.watch(driftProvider)),
|
||||||
AuthRepository(ref.watch(dbProvider), drift: ref.watch(driftProvider)),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
class AuthRepository extends DatabaseRepository implements IAuthRepository {
|
class AuthRepository extends DatabaseRepository {
|
||||||
final Drift _drift;
|
final Drift _drift;
|
||||||
|
|
||||||
AuthRepository(super.db, {required Drift drift}) : _drift = drift;
|
AuthRepository(super.db, this._drift);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> clearLocalData() {
|
Future<void> clearLocalData() {
|
||||||
return db.writeTxn(() {
|
return db.writeTxn(() {
|
||||||
return Future.wait([
|
return Future.wait([
|
||||||
@@ -41,27 +38,22 @@ class AuthRepository extends DatabaseRepository implements IAuthRepository {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
String getAccessToken() {
|
String getAccessToken() {
|
||||||
return Store.get(StoreKey.accessToken);
|
return Store.get(StoreKey.accessToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
bool getEndpointSwitchingFeature() {
|
bool getEndpointSwitchingFeature() {
|
||||||
return Store.tryGet(StoreKey.autoEndpointSwitching) ?? false;
|
return Store.tryGet(StoreKey.autoEndpointSwitching) ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
String? getPreferredWifiName() {
|
String? getPreferredWifiName() {
|
||||||
return Store.tryGet(StoreKey.preferredWifiName);
|
return Store.tryGet(StoreKey.preferredWifiName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
String? getLocalEndpoint() {
|
String? getLocalEndpoint() {
|
||||||
return Store.tryGet(StoreKey.localEndpoint);
|
return Store.tryGet(StoreKey.localEndpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
List<AuxilaryEndpoint> getExternalEndpointList() {
|
List<AuxilaryEndpoint> getExternalEndpointList() {
|
||||||
final jsonString = Store.tryGet(StoreKey.externalEndpointList);
|
final jsonString = Store.tryGet(StoreKey.externalEndpointList);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/interfaces/auth_api.interface.dart';
|
|
||||||
import 'package:immich_mobile/models/auth/login_response.model.dart';
|
import 'package:immich_mobile/models/auth/login_response.model.dart';
|
||||||
import 'package:immich_mobile/providers/api.provider.dart';
|
import 'package:immich_mobile/providers/api.provider.dart';
|
||||||
import 'package:immich_mobile/repositories/api.repository.dart';
|
import 'package:immich_mobile/repositories/api.repository.dart';
|
||||||
@@ -9,12 +8,11 @@ import 'package:openapi/api.dart';
|
|||||||
final authApiRepositoryProvider =
|
final authApiRepositoryProvider =
|
||||||
Provider((ref) => AuthApiRepository(ref.watch(apiServiceProvider)));
|
Provider((ref) => AuthApiRepository(ref.watch(apiServiceProvider)));
|
||||||
|
|
||||||
class AuthApiRepository extends ApiRepository implements IAuthApiRepository {
|
class AuthApiRepository extends ApiRepository {
|
||||||
final ApiService _apiService;
|
final ApiService _apiService;
|
||||||
|
|
||||||
AuthApiRepository(this._apiService);
|
AuthApiRepository(this._apiService);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> changePassword(String newPassword) async {
|
Future<void> changePassword(String newPassword) async {
|
||||||
await _apiService.usersApi.updateMyUser(
|
await _apiService.usersApi.updateMyUser(
|
||||||
UserUpdateMeDto(
|
UserUpdateMeDto(
|
||||||
@@ -23,7 +21,6 @@ class AuthApiRepository extends ApiRepository implements IAuthApiRepository {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<LoginResponse> login(String email, String password) async {
|
Future<LoginResponse> login(String email, String password) async {
|
||||||
final loginResponseDto = await checkNull(
|
final loginResponseDto = await checkNull(
|
||||||
_apiService.authenticationApi.login(
|
_apiService.authenticationApi.login(
|
||||||
@@ -37,7 +34,6 @@ class AuthApiRepository extends ApiRepository implements IAuthApiRepository {
|
|||||||
return _mapLoginReponse(loginResponseDto);
|
return _mapLoginReponse(loginResponseDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> logout() async {
|
Future<void> logout() async {
|
||||||
await _apiService.authenticationApi
|
await _apiService.authenticationApi
|
||||||
.logout()
|
.logout()
|
||||||
@@ -56,7 +52,6 @@ class AuthApiRepository extends ApiRepository implements IAuthApiRepository {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> unlockPinCode(String pinCode) async {
|
Future<bool> unlockPinCode(String pinCode) async {
|
||||||
try {
|
try {
|
||||||
await _apiService.authenticationApi
|
await _apiService.authenticationApi
|
||||||
@@ -67,13 +62,11 @@ class AuthApiRepository extends ApiRepository implements IAuthApiRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> setupPinCode(String pinCode) {
|
Future<void> setupPinCode(String pinCode) {
|
||||||
return _apiService.authenticationApi
|
return _apiService.authenticationApi
|
||||||
.setupPinCode(PinCodeSetupDto(pinCode: pinCode));
|
.setupPinCode(PinCodeSetupDto(pinCode: pinCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> lockPinCode() {
|
Future<void> lockPinCode() {
|
||||||
return _apiService.authenticationApi.lockAuthSession();
|
return _apiService.authenticationApi.lockAuthSession();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
||||||
import 'package:immich_mobile/interfaces/backup_album.interface.dart';
|
|
||||||
import 'package:immich_mobile/providers/db.provider.dart';
|
import 'package:immich_mobile/providers/db.provider.dart';
|
||||||
import 'package:immich_mobile/repositories/database.repository.dart';
|
import 'package:immich_mobile/repositories/database.repository.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
|
||||||
|
enum BackupAlbumSort { id }
|
||||||
|
|
||||||
final backupAlbumRepositoryProvider =
|
final backupAlbumRepositoryProvider =
|
||||||
Provider((ref) => BackupAlbumRepository(ref.watch(dbProvider)));
|
Provider((ref) => BackupAlbumRepository(ref.watch(dbProvider)));
|
||||||
|
|
||||||
class BackupAlbumRepository extends DatabaseRepository
|
class BackupAlbumRepository extends DatabaseRepository {
|
||||||
implements IBackupAlbumRepository {
|
|
||||||
BackupAlbumRepository(super.db);
|
BackupAlbumRepository(super.db);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<BackupAlbum>> getAll({BackupAlbumSort? sort}) {
|
Future<List<BackupAlbum>> getAll({BackupAlbumSort? sort}) {
|
||||||
final baseQuery = db.backupAlbums.where();
|
final baseQuery = db.backupAlbums.where();
|
||||||
final QueryBuilder<BackupAlbum, BackupAlbum, QAfterSortBy> query =
|
final QueryBuilder<BackupAlbum, BackupAlbum, QAfterSortBy> query =
|
||||||
@@ -23,19 +22,15 @@ class BackupAlbumRepository extends DatabaseRepository
|
|||||||
return query.findAll();
|
return query.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<String>> getIdsBySelection(BackupSelection backup) =>
|
Future<List<String>> getIdsBySelection(BackupSelection backup) =>
|
||||||
db.backupAlbums.filter().selectionEqualTo(backup).idProperty().findAll();
|
db.backupAlbums.filter().selectionEqualTo(backup).idProperty().findAll();
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<BackupAlbum>> getAllBySelection(BackupSelection backup) =>
|
Future<List<BackupAlbum>> getAllBySelection(BackupSelection backup) =>
|
||||||
db.backupAlbums.filter().selectionEqualTo(backup).findAll();
|
db.backupAlbums.filter().selectionEqualTo(backup).findAll();
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> deleteAll(List<int> ids) =>
|
Future<void> deleteAll(List<int> ids) =>
|
||||||
txn(() => db.backupAlbums.deleteAll(ids));
|
txn(() => db.backupAlbums.deleteAll(ids));
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> updateAll(List<BackupAlbum> backupAlbums) =>
|
Future<void> updateAll(List<BackupAlbum> backupAlbums) =>
|
||||||
txn(() => db.backupAlbums.putAll(backupAlbums));
|
txn(() => db.backupAlbums.putAll(backupAlbums));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/entities/etag.entity.dart';
|
import 'package:immich_mobile/entities/etag.entity.dart';
|
||||||
import 'package:immich_mobile/interfaces/etag.interface.dart';
|
|
||||||
import 'package:immich_mobile/providers/db.provider.dart';
|
import 'package:immich_mobile/providers/db.provider.dart';
|
||||||
import 'package:immich_mobile/repositories/database.repository.dart';
|
import 'package:immich_mobile/repositories/database.repository.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
@@ -8,26 +7,20 @@ import 'package:isar/isar.dart';
|
|||||||
final etagRepositoryProvider =
|
final etagRepositoryProvider =
|
||||||
Provider((ref) => ETagRepository(ref.watch(dbProvider)));
|
Provider((ref) => ETagRepository(ref.watch(dbProvider)));
|
||||||
|
|
||||||
class ETagRepository extends DatabaseRepository implements IETagRepository {
|
class ETagRepository extends DatabaseRepository {
|
||||||
ETagRepository(super.db);
|
ETagRepository(super.db);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<String>> getAllIds() => db.eTags.where().idProperty().findAll();
|
Future<List<String>> getAllIds() => db.eTags.where().idProperty().findAll();
|
||||||
|
|
||||||
@override
|
|
||||||
Future<ETag?> get(String id) => db.eTags.getById(id);
|
Future<ETag?> get(String id) => db.eTags.getById(id);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> upsertAll(List<ETag> etags) => txn(() => db.eTags.putAll(etags));
|
Future<void> upsertAll(List<ETag> etags) => txn(() => db.eTags.putAll(etags));
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> deleteByIds(List<String> ids) =>
|
Future<void> deleteByIds(List<String> ids) =>
|
||||||
txn(() => db.eTags.deleteAllById(ids));
|
txn(() => db.eTags.deleteAllById(ids));
|
||||||
|
|
||||||
@override
|
|
||||||
Future<ETag?> getById(String id) => db.eTags.getById(id);
|
Future<ETag?> getById(String id) => db.eTags.getById(id);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> clearTable() async {
|
Future<void> clearTable() async {
|
||||||
await txn(() async {
|
await txn(() async {
|
||||||
await db.eTags.clear();
|
await db.eTags.clear();
|
||||||
|
|||||||
@@ -3,14 +3,12 @@ import 'dart:io';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
import 'package:immich_mobile/interfaces/file_media.interface.dart';
|
|
||||||
import 'package:immich_mobile/repositories/asset_media.repository.dart';
|
import 'package:immich_mobile/repositories/asset_media.repository.dart';
|
||||||
import 'package:photo_manager/photo_manager.dart' hide AssetType;
|
import 'package:photo_manager/photo_manager.dart' hide AssetType;
|
||||||
|
|
||||||
final fileMediaRepositoryProvider = Provider((ref) => FileMediaRepository());
|
final fileMediaRepositoryProvider = Provider((ref) => FileMediaRepository());
|
||||||
|
|
||||||
class FileMediaRepository implements IFileMediaRepository {
|
class FileMediaRepository {
|
||||||
@override
|
|
||||||
Future<Asset?> saveImage(
|
Future<Asset?> saveImage(
|
||||||
Uint8List data, {
|
Uint8List data, {
|
||||||
required String title,
|
required String title,
|
||||||
@@ -25,7 +23,6 @@ class FileMediaRepository implements IFileMediaRepository {
|
|||||||
return AssetMediaRepository.toAsset(entity);
|
return AssetMediaRepository.toAsset(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Asset?> saveImageWithFile(
|
Future<Asset?> saveImageWithFile(
|
||||||
String filePath, {
|
String filePath, {
|
||||||
String? title,
|
String? title,
|
||||||
@@ -39,7 +36,6 @@ class FileMediaRepository implements IFileMediaRepository {
|
|||||||
return AssetMediaRepository.toAsset(entity);
|
return AssetMediaRepository.toAsset(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Asset?> saveLivePhoto({
|
Future<Asset?> saveLivePhoto({
|
||||||
required File image,
|
required File image,
|
||||||
required File video,
|
required File video,
|
||||||
@@ -53,7 +49,6 @@ class FileMediaRepository implements IFileMediaRepository {
|
|||||||
return AssetMediaRepository.toAsset(entity);
|
return AssetMediaRepository.toAsset(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Asset?> saveVideo(
|
Future<Asset?> saveVideo(
|
||||||
File file, {
|
File file, {
|
||||||
required String title,
|
required String title,
|
||||||
@@ -67,14 +62,11 @@ class FileMediaRepository implements IFileMediaRepository {
|
|||||||
return AssetMediaRepository.toAsset(entity);
|
return AssetMediaRepository.toAsset(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> clearFileCache() => PhotoManager.clearFileCache();
|
Future<void> clearFileCache() => PhotoManager.clearFileCache();
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> enableBackgroundAccess() =>
|
Future<void> enableBackgroundAccess() =>
|
||||||
PhotoManager.setIgnorePermissionCheck(true);
|
PhotoManager.setIgnorePermissionCheck(true);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> requestExtendedPermissions() =>
|
Future<void> requestExtendedPermissions() =>
|
||||||
PhotoManager.requestPermissionExtend();
|
PhotoManager.requestPermissionExtend();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
import 'package:immich_mobile/interfaces/folder_api.interface.dart';
|
|
||||||
import 'package:immich_mobile/providers/api.provider.dart';
|
import 'package:immich_mobile/providers/api.provider.dart';
|
||||||
import 'package:immich_mobile/repositories/api.repository.dart';
|
import 'package:immich_mobile/repositories/api.repository.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
@@ -12,14 +11,12 @@ final folderApiRepositoryProvider = Provider(
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
class FolderApiRepository extends ApiRepository
|
class FolderApiRepository extends ApiRepository {
|
||||||
implements IFolderApiRepository {
|
|
||||||
final ViewApi _api;
|
final ViewApi _api;
|
||||||
final Logger _log = Logger("FolderApiRepository");
|
final Logger _log = Logger("FolderApiRepository");
|
||||||
|
|
||||||
FolderApiRepository(this._api);
|
FolderApiRepository(this._api);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<String>> getAllUniquePaths() async {
|
Future<List<String>> getAllUniquePaths() async {
|
||||||
try {
|
try {
|
||||||
final list = await _api.getUniqueOriginalPaths();
|
final list = await _api.getUniqueOriginalPaths();
|
||||||
@@ -30,7 +27,6 @@ class FolderApiRepository extends ApiRepository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Asset>> getAssetsForPath(String? path) async {
|
Future<List<Asset>> getAssetsForPath(String? path) async {
|
||||||
try {
|
try {
|
||||||
final list = await _api.getAssetsByOriginalPath(path ?? '/');
|
final list = await _api.getAssetsByOriginalPath(path ?? '/');
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/interfaces/local_files_manager.interface.dart';
|
import 'package:immich_mobile/services/local_files_manager.service.dart';
|
||||||
import 'package:immich_mobile/utils/local_files_manager.dart';
|
|
||||||
|
|
||||||
final localFilesManagerRepositoryProvider =
|
final localFilesManagerRepositoryProvider = Provider(
|
||||||
Provider((ref) => const LocalFilesManagerRepository());
|
(ref) =>
|
||||||
|
LocalFilesManagerRepository(ref.watch(localFileManagerServiceProvider)),
|
||||||
|
);
|
||||||
|
|
||||||
class LocalFilesManagerRepository implements ILocalFilesManager {
|
class LocalFilesManagerRepository {
|
||||||
const LocalFilesManagerRepository();
|
LocalFilesManagerRepository(this._service);
|
||||||
|
|
||||||
|
final LocalFilesManagerService _service;
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> moveToTrash(List<String> mediaUrls) async {
|
Future<bool> moveToTrash(List<String> mediaUrls) async {
|
||||||
return await LocalFilesManager.moveToTrash(mediaUrls);
|
return await _service.moveToTrash(mediaUrls);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> restoreFromTrash(String fileName, int type) async {
|
Future<bool> restoreFromTrash(String fileName, int type) async {
|
||||||
return await LocalFilesManager.restoreFromTrash(fileName, type);
|
return await _service.restoreFromTrash(fileName, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> requestManageMediaPermission() async {
|
Future<bool> requestManageMediaPermission() async {
|
||||||
return await LocalFilesManager.requestManageMediaPermission();
|
return await _service.requestManageMediaPermission();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/user.entity.dart'
|
import 'package:immich_mobile/infrastructure/entities/user.entity.dart'
|
||||||
as entity;
|
as entity;
|
||||||
import 'package:immich_mobile/interfaces/partner.interface.dart';
|
|
||||||
import 'package:immich_mobile/providers/db.provider.dart';
|
import 'package:immich_mobile/providers/db.provider.dart';
|
||||||
import 'package:immich_mobile/repositories/database.repository.dart';
|
import 'package:immich_mobile/repositories/database.repository.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
@@ -11,11 +10,9 @@ final partnerRepositoryProvider = Provider(
|
|||||||
(ref) => PartnerRepository(ref.watch(dbProvider)),
|
(ref) => PartnerRepository(ref.watch(dbProvider)),
|
||||||
);
|
);
|
||||||
|
|
||||||
class PartnerRepository extends DatabaseRepository
|
class PartnerRepository extends DatabaseRepository {
|
||||||
implements IPartnerRepository {
|
|
||||||
PartnerRepository(super.db);
|
PartnerRepository(super.db);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<UserDto>> getSharedBy() async {
|
Future<List<UserDto>> getSharedBy() async {
|
||||||
return (await db.users
|
return (await db.users
|
||||||
.filter()
|
.filter()
|
||||||
@@ -26,7 +23,6 @@ class PartnerRepository extends DatabaseRepository
|
|||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<UserDto>> getSharedWith() async {
|
Future<List<UserDto>> getSharedWith() async {
|
||||||
return (await db.users
|
return (await db.users
|
||||||
.filter()
|
.filter()
|
||||||
@@ -37,13 +33,11 @@ class PartnerRepository extends DatabaseRepository
|
|||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<List<UserDto>> watchSharedBy() {
|
Stream<List<UserDto>> watchSharedBy() {
|
||||||
return (db.users.filter().isPartnerSharedByEqualTo(true).sortById().watch())
|
return (db.users.filter().isPartnerSharedByEqualTo(true).sortById().watch())
|
||||||
.map((users) => users.map((u) => u.toDto()).toList());
|
.map((users) => users.map((u) => u.toDto()).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<List<UserDto>> watchSharedWith() {
|
Stream<List<UserDto>> watchSharedWith() {
|
||||||
return (db.users
|
return (db.users
|
||||||
.filter()
|
.filter()
|
||||||
|
|||||||
@@ -1,24 +1,26 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/utils/user.converter.dart';
|
import 'package:immich_mobile/infrastructure/utils/user.converter.dart';
|
||||||
import 'package:immich_mobile/interfaces/partner_api.interface.dart';
|
|
||||||
import 'package:immich_mobile/providers/api.provider.dart';
|
import 'package:immich_mobile/providers/api.provider.dart';
|
||||||
import 'package:immich_mobile/repositories/api.repository.dart';
|
import 'package:immich_mobile/repositories/api.repository.dart';
|
||||||
import 'package:openapi/api.dart';
|
import 'package:openapi/api.dart';
|
||||||
|
|
||||||
|
enum Direction {
|
||||||
|
sharedWithMe,
|
||||||
|
sharedByMe,
|
||||||
|
}
|
||||||
|
|
||||||
final partnerApiRepositoryProvider = Provider(
|
final partnerApiRepositoryProvider = Provider(
|
||||||
(ref) => PartnerApiRepository(
|
(ref) => PartnerApiRepository(
|
||||||
ref.watch(apiServiceProvider).partnersApi,
|
ref.watch(apiServiceProvider).partnersApi,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
class PartnerApiRepository extends ApiRepository
|
class PartnerApiRepository extends ApiRepository {
|
||||||
implements IPartnerApiRepository {
|
|
||||||
final PartnersApi _api;
|
final PartnersApi _api;
|
||||||
|
|
||||||
PartnerApiRepository(this._api);
|
PartnerApiRepository(this._api);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<UserDto>> getAll(Direction direction) async {
|
Future<List<UserDto>> getAll(Direction direction) async {
|
||||||
final response = await checkNull(
|
final response = await checkNull(
|
||||||
_api.getPartners(
|
_api.getPartners(
|
||||||
@@ -30,16 +32,13 @@ class PartnerApiRepository extends ApiRepository
|
|||||||
return response.map(UserConverter.fromPartnerDto).toList();
|
return response.map(UserConverter.fromPartnerDto).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<UserDto> create(String id) async {
|
Future<UserDto> create(String id) async {
|
||||||
final dto = await checkNull(_api.createPartner(id));
|
final dto = await checkNull(_api.createPartner(id));
|
||||||
return UserConverter.fromPartnerDto(dto);
|
return UserConverter.fromPartnerDto(dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> delete(String id) => _api.removePartner(id);
|
Future<void> delete(String id) => _api.removePartner(id);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<UserDto> update(String id, {required bool inTimeline}) async {
|
Future<UserDto> update(String id, {required bool inTimeline}) async {
|
||||||
final dto = await checkNull(
|
final dto = await checkNull(
|
||||||
_api.updatePartner(
|
_api.updatePartner(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/interfaces/person_api.interface.dart';
|
import 'package:immich_mobile/domain/models/person.model.dart';
|
||||||
import 'package:immich_mobile/providers/api.provider.dart';
|
import 'package:immich_mobile/providers/api.provider.dart';
|
||||||
import 'package:immich_mobile/repositories/api.repository.dart';
|
import 'package:immich_mobile/repositories/api.repository.dart';
|
||||||
import 'package:openapi/api.dart';
|
import 'package:openapi/api.dart';
|
||||||
@@ -8,19 +8,16 @@ final personApiRepositoryProvider = Provider(
|
|||||||
(ref) => PersonApiRepository(ref.watch(apiServiceProvider).peopleApi),
|
(ref) => PersonApiRepository(ref.watch(apiServiceProvider).peopleApi),
|
||||||
);
|
);
|
||||||
|
|
||||||
class PersonApiRepository extends ApiRepository
|
class PersonApiRepository extends ApiRepository {
|
||||||
implements IPersonApiRepository {
|
|
||||||
final PeopleApi _api;
|
final PeopleApi _api;
|
||||||
|
|
||||||
PersonApiRepository(this._api);
|
PersonApiRepository(this._api);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<Person>> getAll() async {
|
Future<List<Person>> getAll() async {
|
||||||
final dto = await checkNull(_api.getAllPeople());
|
final dto = await checkNull(_api.getAllPeople());
|
||||||
return dto.people.map(_toPerson).toList();
|
return dto.people.map(_toPerson).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Person> update(String id, {String? name}) async {
|
Future<Person> update(String id, {String? name}) async {
|
||||||
final dto = await checkNull(
|
final dto = await checkNull(
|
||||||
_api.updatePerson(id, PersonUpdateDto(name: name)),
|
_api.updatePerson(id, PersonUpdateDto(name: name)),
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import 'package:immich_mobile/constants/enums.dart';
|
|||||||
import 'package:immich_mobile/entities/album.entity.dart';
|
import 'package:immich_mobile/entities/album.entity.dart';
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
||||||
import 'package:immich_mobile/interfaces/timeline.interface.dart';
|
|
||||||
import 'package:immich_mobile/providers/db.provider.dart';
|
import 'package:immich_mobile/providers/db.provider.dart';
|
||||||
import 'package:immich_mobile/repositories/database.repository.dart';
|
import 'package:immich_mobile/repositories/database.repository.dart';
|
||||||
import 'package:immich_mobile/utils/hash.dart';
|
import 'package:immich_mobile/utils/hash.dart';
|
||||||
@@ -13,11 +12,9 @@ import 'package:isar/isar.dart';
|
|||||||
final timelineRepositoryProvider =
|
final timelineRepositoryProvider =
|
||||||
Provider((ref) => TimelineRepository(ref.watch(dbProvider)));
|
Provider((ref) => TimelineRepository(ref.watch(dbProvider)));
|
||||||
|
|
||||||
class TimelineRepository extends DatabaseRepository
|
class TimelineRepository extends DatabaseRepository {
|
||||||
implements ITimelineRepository {
|
|
||||||
TimelineRepository(super.db);
|
TimelineRepository(super.db);
|
||||||
|
|
||||||
@override
|
|
||||||
Future<List<String>> getTimelineUserIds(String id) {
|
Future<List<String>> getTimelineUserIds(String id) {
|
||||||
return db.users
|
return db.users
|
||||||
.filter()
|
.filter()
|
||||||
@@ -28,7 +25,6 @@ class TimelineRepository extends DatabaseRepository
|
|||||||
.findAll();
|
.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<List<String>> watchTimelineUsers(String id) {
|
Stream<List<String>> watchTimelineUsers(String id) {
|
||||||
return db.users
|
return db.users
|
||||||
.filter()
|
.filter()
|
||||||
@@ -39,7 +35,6 @@ class TimelineRepository extends DatabaseRepository
|
|||||||
.watch();
|
.watch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<RenderList> watchArchiveTimeline(String userId) {
|
Stream<RenderList> watchArchiveTimeline(String userId) {
|
||||||
final query = db.assets
|
final query = db.assets
|
||||||
.where()
|
.where()
|
||||||
@@ -52,7 +47,6 @@ class TimelineRepository extends DatabaseRepository
|
|||||||
return _watchRenderList(query, GroupAssetsBy.none);
|
return _watchRenderList(query, GroupAssetsBy.none);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<RenderList> watchFavoriteTimeline(String userId) {
|
Stream<RenderList> watchFavoriteTimeline(String userId) {
|
||||||
final query = db.assets
|
final query = db.assets
|
||||||
.where()
|
.where()
|
||||||
@@ -67,7 +61,6 @@ class TimelineRepository extends DatabaseRepository
|
|||||||
return _watchRenderList(query, GroupAssetsBy.none);
|
return _watchRenderList(query, GroupAssetsBy.none);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<RenderList> watchAlbumTimeline(
|
Stream<RenderList> watchAlbumTimeline(
|
||||||
Album album,
|
Album album,
|
||||||
GroupAssetsBy groupAssetByOption,
|
GroupAssetsBy groupAssetByOption,
|
||||||
@@ -86,7 +79,6 @@ class TimelineRepository extends DatabaseRepository
|
|||||||
return _watchRenderList(withSortedOption, groupAssetByOption);
|
return _watchRenderList(withSortedOption, groupAssetByOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<RenderList> watchTrashTimeline(String userId) {
|
Stream<RenderList> watchTrashTimeline(String userId) {
|
||||||
final query = db.assets
|
final query = db.assets
|
||||||
.filter()
|
.filter()
|
||||||
@@ -97,7 +89,6 @@ class TimelineRepository extends DatabaseRepository
|
|||||||
return _watchRenderList(query, GroupAssetsBy.none);
|
return _watchRenderList(query, GroupAssetsBy.none);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<RenderList> watchAllVideosTimeline(String userId) {
|
Stream<RenderList> watchAllVideosTimeline(String userId) {
|
||||||
final query = db.assets
|
final query = db.assets
|
||||||
.where()
|
.where()
|
||||||
@@ -111,7 +102,6 @@ class TimelineRepository extends DatabaseRepository
|
|||||||
return _watchRenderList(query, GroupAssetsBy.none);
|
return _watchRenderList(query, GroupAssetsBy.none);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<RenderList> watchHomeTimeline(
|
Stream<RenderList> watchHomeTimeline(
|
||||||
String userId,
|
String userId,
|
||||||
GroupAssetsBy groupAssetByOption,
|
GroupAssetsBy groupAssetByOption,
|
||||||
@@ -128,7 +118,6 @@ class TimelineRepository extends DatabaseRepository
|
|||||||
return _watchRenderList(query, groupAssetByOption);
|
return _watchRenderList(query, groupAssetByOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<RenderList> watchMultiUsersTimeline(
|
Stream<RenderList> watchMultiUsersTimeline(
|
||||||
List<String> userIds,
|
List<String> userIds,
|
||||||
GroupAssetsBy groupAssetByOption,
|
GroupAssetsBy groupAssetByOption,
|
||||||
@@ -145,7 +134,6 @@ class TimelineRepository extends DatabaseRepository
|
|||||||
return _watchRenderList(query, groupAssetByOption);
|
return _watchRenderList(query, groupAssetByOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<RenderList> getTimelineFromAssets(
|
Future<RenderList> getTimelineFromAssets(
|
||||||
List<Asset> assets,
|
List<Asset> assets,
|
||||||
GroupAssetsBy getGroupByOption,
|
GroupAssetsBy getGroupByOption,
|
||||||
@@ -153,7 +141,6 @@ class TimelineRepository extends DatabaseRepository
|
|||||||
return RenderList.fromAssets(assets, getGroupByOption);
|
return RenderList.fromAssets(assets, getGroupByOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<RenderList> watchAssetSelectionTimeline(String userId) {
|
Stream<RenderList> watchAssetSelectionTimeline(String userId) {
|
||||||
final query = db.assets
|
final query = db.assets
|
||||||
.where()
|
.where()
|
||||||
@@ -168,7 +155,6 @@ class TimelineRepository extends DatabaseRepository
|
|||||||
return _watchRenderList(query, GroupAssetsBy.none);
|
return _watchRenderList(query, GroupAssetsBy.none);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Stream<RenderList> watchLockedTimeline(
|
Stream<RenderList> watchLockedTimeline(
|
||||||
String userId,
|
String userId,
|
||||||
GroupAssetsBy getGroupByOption,
|
GroupAssetsBy getGroupByOption,
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
import 'package:background_downloader/background_downloader.dart';
|
import 'package:background_downloader/background_downloader.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/interfaces/upload.interface.dart';
|
|
||||||
import 'package:immich_mobile/utils/upload.dart';
|
import 'package:immich_mobile/utils/upload.dart';
|
||||||
|
|
||||||
final uploadRepositoryProvider = Provider((ref) => UploadRepository());
|
final uploadRepositoryProvider = Provider((ref) => UploadRepository());
|
||||||
|
|
||||||
class UploadRepository implements IUploadRepository {
|
class UploadRepository {
|
||||||
@override
|
|
||||||
void Function(TaskStatusUpdate)? onUploadStatus;
|
void Function(TaskStatusUpdate)? onUploadStatus;
|
||||||
|
|
||||||
@override
|
|
||||||
void Function(TaskProgressUpdate)? onTaskProgress;
|
void Function(TaskProgressUpdate)? onTaskProgress;
|
||||||
|
|
||||||
UploadRepository() {
|
UploadRepository() {
|
||||||
@@ -20,22 +17,18 @@ class UploadRepository implements IUploadRepository {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> upload(UploadTask task) {
|
Future<bool> upload(UploadTask task) {
|
||||||
return FileDownloader().enqueue(task);
|
return FileDownloader().enqueue(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> deleteAllTrackingRecords() {
|
Future<void> deleteAllTrackingRecords() {
|
||||||
return FileDownloader().database.deleteAllRecords();
|
return FileDownloader().database.deleteAllRecords();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> cancel(String id) {
|
Future<bool> cancel(String id) {
|
||||||
return FileDownloader().cancelTaskWithId(id);
|
return FileDownloader().cancelTaskWithId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> deleteRecordsWithIds(List<String> ids) {
|
Future<void> deleteRecordsWithIds(List<String> ids) {
|
||||||
return FileDownloader().database.deleteRecordsWithIds(ids);
|
return FileDownloader().database.deleteRecordsWithIds(ids);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,19 @@
|
|||||||
import 'package:home_widget/home_widget.dart';
|
import 'package:home_widget/home_widget.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/interfaces/widget.interface.dart';
|
|
||||||
|
|
||||||
final widgetRepositoryProvider = Provider((_) => WidgetRepository());
|
final widgetRepositoryProvider = Provider((_) => WidgetRepository());
|
||||||
|
|
||||||
class WidgetRepository implements IWidgetRepository {
|
class WidgetRepository {
|
||||||
WidgetRepository();
|
WidgetRepository();
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> saveData(String key, String value) async {
|
Future<void> saveData(String key, String value) async {
|
||||||
await HomeWidget.saveWidgetData<String>(key, value);
|
await HomeWidget.saveWidgetData<String>(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> refresh(String name) async {
|
Future<void> refresh(String name) async {
|
||||||
await HomeWidget.updateWidget(name: name, iOSName: name);
|
await HomeWidget.updateWidget(name: name, iOSName: name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> setAppGroupId(String appGroupId) async {
|
Future<void> setAppGroupId(String appGroupId) async {
|
||||||
await HomeWidget.setAppGroupId(appGroupId);
|
await HomeWidget.setAppGroupId(appGroupId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,6 @@ import 'package:immich_mobile/entities/asset.entity.dart';
|
|||||||
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/user.entity.dart'
|
import 'package:immich_mobile/infrastructure/entities/user.entity.dart'
|
||||||
as entity;
|
as entity;
|
||||||
import 'package:immich_mobile/interfaces/album.interface.dart';
|
|
||||||
import 'package:immich_mobile/interfaces/asset.interface.dart';
|
|
||||||
import 'package:immich_mobile/interfaces/backup_album.interface.dart';
|
|
||||||
import 'package:immich_mobile/models/albums/album_add_asset_response.model.dart';
|
import 'package:immich_mobile/models/albums/album_add_asset_response.model.dart';
|
||||||
import 'package:immich_mobile/models/albums/album_search.model.dart';
|
import 'package:immich_mobile/models/albums/album_search.model.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
|
||||||
@@ -46,9 +43,9 @@ class AlbumService {
|
|||||||
final SyncService _syncService;
|
final SyncService _syncService;
|
||||||
final UserService _userService;
|
final UserService _userService;
|
||||||
final EntityService _entityService;
|
final EntityService _entityService;
|
||||||
final IAlbumRepository _albumRepository;
|
final AlbumRepository _albumRepository;
|
||||||
final IAssetRepository _assetRepository;
|
final AssetRepository _assetRepository;
|
||||||
final IBackupAlbumRepository _backupAlbumRepository;
|
final BackupAlbumRepository _backupAlbumRepository;
|
||||||
final AlbumMediaRepository _albumMediaRepository;
|
final AlbumMediaRepository _albumMediaRepository;
|
||||||
final AlbumApiRepository _albumApiRepository;
|
final AlbumApiRepository _albumApiRepository;
|
||||||
final Logger _log = Logger('AlbumService');
|
final Logger _log = Logger('AlbumService');
|
||||||
|
|||||||
@@ -4,17 +4,12 @@ import 'package:collection/collection.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/constants/enums.dart';
|
import 'package:immich_mobile/constants/enums.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/exif.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||||
import 'package:immich_mobile/domain/services/user.service.dart';
|
import 'package:immich_mobile/domain/services/user.service.dart';
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/exif.repository.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/user.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/user.repository.dart';
|
||||||
import 'package:immich_mobile/interfaces/asset.interface.dart';
|
|
||||||
import 'package:immich_mobile/interfaces/asset_api.interface.dart';
|
|
||||||
import 'package:immich_mobile/interfaces/asset_media.interface.dart';
|
|
||||||
import 'package:immich_mobile/interfaces/backup_album.interface.dart';
|
|
||||||
import 'package:immich_mobile/interfaces/etag.interface.dart';
|
|
||||||
import 'package:immich_mobile/models/backup/backup_candidate.model.dart';
|
import 'package:immich_mobile/models/backup/backup_candidate.model.dart';
|
||||||
import 'package:immich_mobile/providers/api.provider.dart';
|
import 'package:immich_mobile/providers/api.provider.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/exif.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/exif.provider.dart';
|
||||||
@@ -50,18 +45,18 @@ final assetServiceProvider = Provider(
|
|||||||
);
|
);
|
||||||
|
|
||||||
class AssetService {
|
class AssetService {
|
||||||
final IAssetApiRepository _assetApiRepository;
|
final AssetApiRepository _assetApiRepository;
|
||||||
final IAssetRepository _assetRepository;
|
final AssetRepository _assetRepository;
|
||||||
final IExifInfoRepository _exifInfoRepository;
|
final IsarExifRepository _exifInfoRepository;
|
||||||
final IsarUserRepository _isarUserRepository;
|
final IsarUserRepository _isarUserRepository;
|
||||||
final IETagRepository _etagRepository;
|
final ETagRepository _etagRepository;
|
||||||
final IBackupAlbumRepository _backupRepository;
|
final BackupAlbumRepository _backupRepository;
|
||||||
final ApiService _apiService;
|
final ApiService _apiService;
|
||||||
final SyncService _syncService;
|
final SyncService _syncService;
|
||||||
final BackupService _backupService;
|
final BackupService _backupService;
|
||||||
final AlbumService _albumService;
|
final AlbumService _albumService;
|
||||||
final UserService _userService;
|
final UserService _userService;
|
||||||
final IAssetMediaRepository _assetMediaRepository;
|
final AssetMediaRepository _assetMediaRepository;
|
||||||
final log = Logger('AssetService');
|
final log = Logger('AssetService');
|
||||||
|
|
||||||
AssetService(
|
AssetService(
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
import 'package:immich_mobile/domain/utils/background_sync.dart';
|
import 'package:immich_mobile/domain/utils/background_sync.dart';
|
||||||
import 'package:immich_mobile/entities/store.entity.dart';
|
import 'package:immich_mobile/entities/store.entity.dart';
|
||||||
import 'package:immich_mobile/interfaces/auth.interface.dart';
|
|
||||||
import 'package:immich_mobile/interfaces/auth_api.interface.dart';
|
|
||||||
import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart';
|
import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart';
|
||||||
import 'package:immich_mobile/models/auth/login_response.model.dart';
|
import 'package:immich_mobile/models/auth/login_response.model.dart';
|
||||||
import 'package:immich_mobile/providers/api.provider.dart';
|
import 'package:immich_mobile/providers/api.provider.dart';
|
||||||
@@ -29,8 +27,8 @@ final authServiceProvider = Provider(
|
|||||||
);
|
);
|
||||||
|
|
||||||
class AuthService {
|
class AuthService {
|
||||||
final IAuthApiRepository _authApiRepository;
|
final AuthApiRepository _authApiRepository;
|
||||||
final IAuthRepository _authRepository;
|
final AuthRepository _authRepository;
|
||||||
final ApiService _apiService;
|
final ApiService _apiService;
|
||||||
final NetworkService _networkService;
|
final NetworkService _networkService;
|
||||||
final BackgroundSyncManager _backgroundSyncManager;
|
final BackgroundSyncManager _backgroundSyncManager;
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
||||||
import 'package:immich_mobile/entities/store.entity.dart';
|
import 'package:immich_mobile/entities/store.entity.dart';
|
||||||
import 'package:immich_mobile/interfaces/backup_album.interface.dart';
|
|
||||||
import 'package:immich_mobile/models/backup/backup_candidate.model.dart';
|
import 'package:immich_mobile/models/backup/backup_candidate.model.dart';
|
||||||
import 'package:immich_mobile/models/backup/current_upload_asset.model.dart';
|
import 'package:immich_mobile/models/backup/current_upload_asset.model.dart';
|
||||||
import 'package:immich_mobile/models/backup/error_upload_asset.model.dart';
|
import 'package:immich_mobile/models/backup/error_upload_asset.model.dart';
|
||||||
|
|||||||
@@ -11,9 +11,6 @@ import 'package:immich_mobile/entities/album.entity.dart';
|
|||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
||||||
import 'package:immich_mobile/entities/store.entity.dart';
|
import 'package:immich_mobile/entities/store.entity.dart';
|
||||||
import 'package:immich_mobile/interfaces/asset.interface.dart';
|
|
||||||
import 'package:immich_mobile/interfaces/asset_media.interface.dart';
|
|
||||||
import 'package:immich_mobile/interfaces/file_media.interface.dart';
|
|
||||||
import 'package:immich_mobile/models/backup/backup_candidate.model.dart';
|
import 'package:immich_mobile/models/backup/backup_candidate.model.dart';
|
||||||
import 'package:immich_mobile/models/backup/current_upload_asset.model.dart';
|
import 'package:immich_mobile/models/backup/current_upload_asset.model.dart';
|
||||||
import 'package:immich_mobile/models/backup/error_upload_asset.model.dart';
|
import 'package:immich_mobile/models/backup/error_upload_asset.model.dart';
|
||||||
@@ -52,9 +49,9 @@ class BackupService {
|
|||||||
final AppSettingsService _appSetting;
|
final AppSettingsService _appSetting;
|
||||||
final AlbumService _albumService;
|
final AlbumService _albumService;
|
||||||
final AlbumMediaRepository _albumMediaRepository;
|
final AlbumMediaRepository _albumMediaRepository;
|
||||||
final IFileMediaRepository _fileMediaRepository;
|
final FileMediaRepository _fileMediaRepository;
|
||||||
final IAssetRepository _assetRepository;
|
final AssetRepository _assetRepository;
|
||||||
final IAssetMediaRepository _assetMediaRepository;
|
final AssetMediaRepository _assetMediaRepository;
|
||||||
|
|
||||||
BackupService(
|
BackupService(
|
||||||
this._apiService,
|
this._apiService,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
import 'package:immich_mobile/entities/backup_album.entity.dart';
|
||||||
import 'package:immich_mobile/interfaces/backup_album.interface.dart';
|
|
||||||
import 'package:immich_mobile/repositories/backup.repository.dart';
|
import 'package:immich_mobile/repositories/backup.repository.dart';
|
||||||
|
|
||||||
final backupAlbumServiceProvider = Provider<BackupAlbumService>((ref) {
|
final backupAlbumServiceProvider = Provider<BackupAlbumService>((ref) {
|
||||||
@@ -8,7 +7,7 @@ final backupAlbumServiceProvider = Provider<BackupAlbumService>((ref) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
class BackupAlbumService {
|
class BackupAlbumService {
|
||||||
final IBackupAlbumRepository _backupAlbumRepository;
|
final BackupAlbumRepository _backupAlbumRepository;
|
||||||
|
|
||||||
BackupAlbumService(this._backupAlbumRepository);
|
BackupAlbumService(this._backupAlbumRepository);
|
||||||
|
|
||||||
|
|||||||
@@ -5,15 +5,13 @@ import 'package:collection/collection.dart';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/exif.interface.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/exif.model.dart';
|
import 'package:immich_mobile/domain/models/exif.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
import 'package:immich_mobile/domain/services/user.service.dart';
|
import 'package:immich_mobile/domain/services/user.service.dart';
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
import 'package:immich_mobile/entities/store.entity.dart';
|
import 'package:immich_mobile/entities/store.entity.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/exif.repository.dart';
|
||||||
import 'package:immich_mobile/infrastructure/utils/exif.converter.dart';
|
import 'package:immich_mobile/infrastructure/utils/exif.converter.dart';
|
||||||
import 'package:immich_mobile/interfaces/asset.interface.dart';
|
|
||||||
import 'package:immich_mobile/interfaces/file_media.interface.dart';
|
|
||||||
import 'package:immich_mobile/providers/infrastructure/exif.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/exif.provider.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
|
||||||
import 'package:immich_mobile/repositories/asset.repository.dart';
|
import 'package:immich_mobile/repositories/asset.repository.dart';
|
||||||
@@ -25,9 +23,9 @@ import 'package:immich_mobile/utils/diff.dart';
|
|||||||
/// Finds duplicates originating from missing EXIF information
|
/// Finds duplicates originating from missing EXIF information
|
||||||
class BackupVerificationService {
|
class BackupVerificationService {
|
||||||
final UserService _userService;
|
final UserService _userService;
|
||||||
final IFileMediaRepository _fileMediaRepository;
|
final FileMediaRepository _fileMediaRepository;
|
||||||
final IAssetRepository _assetRepository;
|
final AssetRepository _assetRepository;
|
||||||
final IExifInfoRepository _exifInfoRepository;
|
final IsarExifRepository _exifInfoRepository;
|
||||||
|
|
||||||
const BackupVerificationService(
|
const BackupVerificationService(
|
||||||
this._userService,
|
this._userService,
|
||||||
@@ -123,7 +121,7 @@ class BackupVerificationService {
|
|||||||
String auth,
|
String auth,
|
||||||
String endpoint,
|
String endpoint,
|
||||||
RootIsolateToken rootIsolateToken,
|
RootIsolateToken rootIsolateToken,
|
||||||
IFileMediaRepository fileMediaRepository,
|
FileMediaRepository fileMediaRepository,
|
||||||
}) tuple,
|
}) tuple,
|
||||||
) async {
|
) async {
|
||||||
assert(tuple.deleteCandidates.length == tuple.originals.length);
|
assert(tuple.deleteCandidates.length == tuple.originals.length);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||||
import 'package:immich_mobile/entities/store.entity.dart';
|
import 'package:immich_mobile/entities/store.entity.dart';
|
||||||
import 'package:immich_mobile/interfaces/file_media.interface.dart';
|
|
||||||
import 'package:immich_mobile/models/download/livephotos_medatada.model.dart';
|
import 'package:immich_mobile/models/download/livephotos_medatada.model.dart';
|
||||||
import 'package:immich_mobile/repositories/download.repository.dart';
|
import 'package:immich_mobile/repositories/download.repository.dart';
|
||||||
import 'package:immich_mobile/repositories/file_media.repository.dart';
|
import 'package:immich_mobile/repositories/file_media.repository.dart';
|
||||||
@@ -23,7 +22,7 @@ final downloadServiceProvider = Provider(
|
|||||||
|
|
||||||
class DownloadService {
|
class DownloadService {
|
||||||
final DownloadRepository _downloadRepository;
|
final DownloadRepository _downloadRepository;
|
||||||
final IFileMediaRepository _fileMediaRepository;
|
final FileMediaRepository _fileMediaRepository;
|
||||||
final Logger _log = Logger("DownloadService");
|
final Logger _log = Logger("DownloadService");
|
||||||
void Function(TaskStatusUpdate)? onImageDownloadStatus;
|
void Function(TaskStatusUpdate)? onImageDownloadStatus;
|
||||||
void Function(TaskStatusUpdate)? onVideoDownloadStatus;
|
void Function(TaskStatusUpdate)? onVideoDownloadStatus;
|
||||||
|
|||||||
@@ -2,12 +2,11 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:immich_mobile/entities/album.entity.dart';
|
import 'package:immich_mobile/entities/album.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/user.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/user.repository.dart';
|
||||||
import 'package:immich_mobile/interfaces/asset.interface.dart';
|
|
||||||
import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
|
||||||
import 'package:immich_mobile/repositories/asset.repository.dart';
|
import 'package:immich_mobile/repositories/asset.repository.dart';
|
||||||
|
|
||||||
class EntityService {
|
class EntityService {
|
||||||
final IAssetRepository _assetRepository;
|
final AssetRepository _assetRepository;
|
||||||
final IsarUserRepository _isarUserRepository;
|
final IsarUserRepository _isarUserRepository;
|
||||||
EntityService(
|
EntityService(
|
||||||
this._assetRepository,
|
this._assetRepository,
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user