mirror of
https://github.com/immich-app/immich.git
synced 2026-05-22 15:42:32 -04:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 476e73b0c5 | |||
| 7b9dab872b | |||
| 6413495fb8 | |||
| b414b3d32b |
@@ -288,7 +288,6 @@ jobs:
|
|||||||
APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
|
APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
|
||||||
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
|
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
|
||||||
ENVIRONMENT: ${{ inputs.environment || 'development' }}
|
ENVIRONMENT: ${{ inputs.environment || 'development' }}
|
||||||
BUNDLE_ID_SUFFIX: ${{ inputs.environment == 'production' && '' || 'development' }}
|
|
||||||
GITHUB_REF: ${{ github.ref }}
|
GITHUB_REF: ${{ github.ref }}
|
||||||
FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT: 120
|
FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT: 120
|
||||||
FASTLANE_XCODEBUILD_SETTINGS_RETRIES: 6
|
FASTLANE_XCODEBUILD_SETTINGS_RETRIES: 6
|
||||||
|
|||||||
@@ -4,28 +4,6 @@
|
|||||||
version = "3.41.9"
|
version = "3.41.9"
|
||||||
backend = "aqua:flutter/flutter"
|
backend = "aqua:flutter/flutter"
|
||||||
|
|
||||||
[tools."aqua:flutter/flutter"."platforms.linux-arm64"]
|
|
||||||
url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.41.9-stable.tar.xz"
|
|
||||||
|
|
||||||
[tools."aqua:flutter/flutter"."platforms.linux-arm64-musl"]
|
|
||||||
url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.41.9-stable.tar.xz"
|
|
||||||
|
|
||||||
[tools."aqua:flutter/flutter"."platforms.linux-x64"]
|
|
||||||
url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.41.9-stable.tar.xz"
|
|
||||||
|
|
||||||
[tools."aqua:flutter/flutter"."platforms.linux-x64-musl"]
|
|
||||||
url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.41.9-stable.tar.xz"
|
|
||||||
|
|
||||||
[tools."aqua:flutter/flutter"."platforms.macos-arm64"]
|
|
||||||
checksum = "blake3:aa1a8a9794fcbcb38cba1d2fd8a7afd012ca78ee8c367a4063d4131f1f0fea83"
|
|
||||||
url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/macos/flutter_macos_arm64_3.41.9-stable.zip"
|
|
||||||
|
|
||||||
[tools."aqua:flutter/flutter"."platforms.macos-x64"]
|
|
||||||
url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/macos/flutter_macos_3.41.9-stable.zip"
|
|
||||||
|
|
||||||
[tools."aqua:flutter/flutter"."platforms.windows-x64"]
|
|
||||||
url = "https://storage.googleapis.com/flutter_infra_release/releases/stable/windows/flutter_windows_3.41.9-stable.zip"
|
|
||||||
|
|
||||||
[[tools.flutter]]
|
[[tools.flutter]]
|
||||||
version = "3.41.9-stable"
|
version = "3.41.9-stable"
|
||||||
backend = "asdf:flutter"
|
backend = "asdf:flutter"
|
||||||
|
|||||||
@@ -315,6 +315,7 @@ interface NetworkApi {
|
|||||||
fun hasCertificate(): Boolean
|
fun hasCertificate(): Boolean
|
||||||
fun getClientPointer(): Long
|
fun getClientPointer(): Long
|
||||||
fun setRequestHeaders(headers: Map<String, String>, serverUrls: List<String>, token: String?)
|
fun setRequestHeaders(headers: Map<String, String>, serverUrls: List<String>, token: String?)
|
||||||
|
fun getAppGroupId(): String
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/** The codec used by NetworkApi. */
|
/** The codec used by NetworkApi. */
|
||||||
@@ -430,6 +431,21 @@ interface NetworkApi {
|
|||||||
channel.setMessageHandler(null)
|
channel.setMessageHandler(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
run {
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.immich_mobile.NetworkApi.getAppGroupId$separatedMessageChannelSuffix", codec)
|
||||||
|
if (api != null) {
|
||||||
|
channel.setMessageHandler { _, reply ->
|
||||||
|
val wrapped: List<Any?> = try {
|
||||||
|
listOf(api.getAppGroupId())
|
||||||
|
} catch (exception: Throwable) {
|
||||||
|
NetworkPigeonUtils.wrapError(exception)
|
||||||
|
}
|
||||||
|
reply.reply(wrapped)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
channel.setMessageHandler(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class NetworkApiPlugin : FlutterPlugin, ActivityAware {
|
|||||||
private var networkApi: NetworkApiImpl? = null
|
private var networkApi: NetworkApiImpl? = null
|
||||||
|
|
||||||
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||||
networkApi = NetworkApiImpl()
|
networkApi = NetworkApiImpl(binding.applicationContext)
|
||||||
NetworkApi.setUp(binding.binaryMessenger, networkApi)
|
NetworkApi.setUp(binding.binaryMessenger, networkApi)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,9 +39,11 @@ class NetworkApiPlugin : FlutterPlugin, ActivityAware {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NetworkApiImpl : NetworkApi {
|
private class NetworkApiImpl(private val context: Context) : NetworkApi {
|
||||||
var activity: Activity? = null
|
var activity: Activity? = null
|
||||||
|
|
||||||
|
override fun getAppGroupId(): String = context.packageName
|
||||||
|
|
||||||
override fun addCertificate(clientData: ClientCertData, callback: (Result<Unit>) -> Unit) {
|
override fun addCertificate(clientData: ClientCertData, callback: (Result<Unit>) -> Unit) {
|
||||||
try {
|
try {
|
||||||
HttpClientManager.setKeyEntry(clientData.data, clientData.password.toCharArray())
|
HttpClientManager.setKeyEntry(clientData.data, clientData.password.toCharArray())
|
||||||
|
|||||||
@@ -718,6 +718,7 @@
|
|||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
|
CUSTOM_GROUP_ID = group.app.immich.share.profile;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
@@ -750,7 +751,6 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 240;
|
CURRENT_PROJECT_VERSION = 240;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
|
||||||
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -801,6 +801,7 @@
|
|||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
|
CUSTOM_GROUP_ID = group.app.immich.share.debug;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
@@ -860,6 +861,7 @@
|
|||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
|
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
@@ -894,7 +896,6 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 240;
|
CURRENT_PROJECT_VERSION = 240;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
|
||||||
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -924,7 +925,6 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 240;
|
CURRENT_PROJECT_VERSION = 240;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
|
||||||
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@@ -1080,7 +1080,6 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 240;
|
CURRENT_PROJECT_VERSION = 240;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
|
||||||
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
@@ -1124,7 +1123,6 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 240;
|
CURRENT_PROJECT_VERSION = 240;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
|
||||||
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
@@ -1165,7 +1163,6 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 240;
|
CURRENT_PROJECT_VERSION = 240;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
|
||||||
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
DEVELOPMENT_TEAM = 2W7AC6T8T5;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
|||||||
Generated
+14
@@ -288,6 +288,7 @@ protocol NetworkApi {
|
|||||||
func hasCertificate() throws -> Bool
|
func hasCertificate() throws -> Bool
|
||||||
func getClientPointer() throws -> Int64
|
func getClientPointer() throws -> Int64
|
||||||
func setRequestHeaders(headers: [String: String], serverUrls: [String], token: String?) throws
|
func setRequestHeaders(headers: [String: String], serverUrls: [String], token: String?) throws
|
||||||
|
func getAppGroupId() throws -> String
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
|
/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
|
||||||
@@ -388,5 +389,18 @@ class NetworkApiSetup {
|
|||||||
} else {
|
} else {
|
||||||
setRequestHeadersChannel.setMessageHandler(nil)
|
setRequestHeadersChannel.setMessageHandler(nil)
|
||||||
}
|
}
|
||||||
|
let getAppGroupIdChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.NetworkApi.getAppGroupId\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
|
||||||
|
if let api = api {
|
||||||
|
getAppGroupIdChannel.setMessageHandler { _, reply in
|
||||||
|
do {
|
||||||
|
let result = try api.getAppGroupId()
|
||||||
|
reply(wrapResult(result))
|
||||||
|
} catch {
|
||||||
|
reply(wrapError(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
getAppGroupIdChannel.setMessageHandler(nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ class NetworkApiImpl: NetworkApi {
|
|||||||
return Int64(Int(bitPattern: pointer))
|
return Int64(Int(bitPattern: pointer))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getAppGroupId() throws -> String {
|
||||||
|
return Bundle.main.object(forInfoDictionaryKey: "AppGroupId") as! String
|
||||||
|
}
|
||||||
|
|
||||||
func setRequestHeaders(headers: [String : String], serverUrls: [String], token: String?) throws {
|
func setRequestHeaders(headers: [String : String], serverUrls: [String], token: String?) throws {
|
||||||
URLSessionManager.setServerUrls(serverUrls)
|
URLSessionManager.setServerUrls(serverUrls)
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import native_video_player
|
|||||||
let CLIENT_CERT_LABEL = "app.alextran.immich.client_identity"
|
let CLIENT_CERT_LABEL = "app.alextran.immich.client_identity"
|
||||||
let HEADERS_KEY = "immich.request_headers"
|
let HEADERS_KEY = "immich.request_headers"
|
||||||
let SERVER_URLS_KEY = "immich.server_urls"
|
let SERVER_URLS_KEY = "immich.server_urls"
|
||||||
let APP_GROUP = "group.app.immich.share"
|
let APP_GROUP = Bundle.main.object(forInfoDictionaryKey: "AppGroupId") as! String
|
||||||
let COOKIE_EXPIRY_DAYS: TimeInterval = 400
|
let COOKIE_EXPIRY_DAYS: TimeInterval = 400
|
||||||
|
|
||||||
enum AuthCookie: CaseIterable {
|
enum AuthCookie: CaseIterable {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.application-groups</key>
|
<key>com.apple.security.application-groups</key>
|
||||||
<array>
|
<array>
|
||||||
<string>group.app.immich.share</string>
|
<string>$(CUSTOM_GROUP_ID)</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.application-groups</key>
|
<key>com.apple.security.application-groups</key>
|
||||||
<array>
|
<array>
|
||||||
<string>group.app.immich.share</string>
|
<string>$(CUSTOM_GROUP_ID)</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>com.apple.security.application-groups</key>
|
<key>com.apple.security.application-groups</key>
|
||||||
<array>
|
<array>
|
||||||
<string>group.app.immich.share</string>
|
<string>$(CUSTOM_GROUP_ID)</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
@@ -2,7 +2,7 @@ import Foundation
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import WidgetKit
|
import WidgetKit
|
||||||
|
|
||||||
let IMMICH_SHARE_GROUP = "group.app.immich.share"
|
let IMMICH_SHARE_GROUP = Bundle.main.object(forInfoDictionaryKey: "AppGroupId") as! String
|
||||||
|
|
||||||
enum WidgetError: Error, Codable {
|
enum WidgetError: Error, Codable {
|
||||||
case noLogin
|
case noLogin
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>AppGroupId</key>
|
||||||
|
<string>$(CUSTOM_GROUP_ID)</string>
|
||||||
<key>NSAppTransportSecurity</key>
|
<key>NSAppTransportSecurity</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSAllowsArbitraryLoads</key>
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>com.apple.security.application-groups</key>
|
<key>com.apple.security.application-groups</key>
|
||||||
<array>
|
<array>
|
||||||
<string>group.app.immich.share</string>
|
<string>$(CUSTOM_GROUP_ID)</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
@@ -21,6 +21,7 @@ platform :ios do
|
|||||||
CODE_SIGN_IDENTITY = "Apple Distribution: FUTO Holdings, Inc. (#{TEAM_ID})"
|
CODE_SIGN_IDENTITY = "Apple Distribution: FUTO Holdings, Inc. (#{TEAM_ID})"
|
||||||
BASE_BUNDLE_ID = "app.alextran.immich"
|
BASE_BUNDLE_ID = "app.alextran.immich"
|
||||||
DEV_BUNDLE_ID = "tech.futo.immich.testflight"
|
DEV_BUNDLE_ID = "tech.futo.immich.testflight"
|
||||||
|
DEV_GROUP_ID = "group.app.immich.share.testflight"
|
||||||
|
|
||||||
# Helper method to get App Store Connect API key
|
# Helper method to get App Store Connect API key
|
||||||
def get_api_key
|
def get_api_key
|
||||||
@@ -33,6 +34,13 @@ platform :ios do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Helper method to assemble xcargs with optional CUSTOM_GROUP_ID override
|
||||||
|
def build_xcargs(group_id: nil)
|
||||||
|
args = "-skipMacroValidation CODE_SIGN_IDENTITY='#{CODE_SIGN_IDENTITY}' CODE_SIGN_STYLE=Manual"
|
||||||
|
args += " CUSTOM_GROUP_ID='#{group_id}'" if group_id
|
||||||
|
args
|
||||||
|
end
|
||||||
|
|
||||||
# Helper method to get version from pubspec.yaml
|
# Helper method to get version from pubspec.yaml
|
||||||
def get_version_from_pubspec
|
def get_version_from_pubspec
|
||||||
require 'yaml'
|
require 'yaml'
|
||||||
@@ -89,7 +97,8 @@ end
|
|||||||
version_number: nil,
|
version_number: nil,
|
||||||
profile_name_main:,
|
profile_name_main:,
|
||||||
profile_name_share:,
|
profile_name_share:,
|
||||||
profile_name_widget:
|
profile_name_widget:,
|
||||||
|
group_id: nil
|
||||||
)
|
)
|
||||||
app_identifier = base_bundle_id
|
app_identifier = base_bundle_id
|
||||||
|
|
||||||
@@ -113,7 +122,7 @@ end
|
|||||||
workspace: "Runner.xcworkspace",
|
workspace: "Runner.xcworkspace",
|
||||||
configuration: configuration,
|
configuration: configuration,
|
||||||
export_method: "app-store",
|
export_method: "app-store",
|
||||||
xcargs: "-skipMacroValidation CODE_SIGN_IDENTITY='#{CODE_SIGN_IDENTITY}' CODE_SIGN_STYLE=Manual",
|
xcargs: build_xcargs(group_id: group_id),
|
||||||
export_options: {
|
export_options: {
|
||||||
provisioningProfiles: {
|
provisioningProfiles: {
|
||||||
"#{app_identifier}" => profile_name_main,
|
"#{app_identifier}" => profile_name_main,
|
||||||
@@ -165,7 +174,8 @@ end
|
|||||||
distribute_external: false,
|
distribute_external: false,
|
||||||
profile_name_main: main_profile_name,
|
profile_name_main: main_profile_name,
|
||||||
profile_name_share: share_profile_name,
|
profile_name_share: share_profile_name,
|
||||||
profile_name_widget: widget_profile_name
|
profile_name_widget: widget_profile_name,
|
||||||
|
group_id: DEV_GROUP_ID
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -274,7 +284,7 @@ end
|
|||||||
configuration: "Release",
|
configuration: "Release",
|
||||||
export_method: "app-store",
|
export_method: "app-store",
|
||||||
skip_package_ipa: true,
|
skip_package_ipa: true,
|
||||||
xcargs: "-skipMacroValidation CODE_SIGN_IDENTITY='#{CODE_SIGN_IDENTITY}' CODE_SIGN_STYLE=Manual",
|
xcargs: build_xcargs(group_id: DEV_GROUP_ID),
|
||||||
export_options: {
|
export_options: {
|
||||||
provisioningProfiles: {
|
provisioningProfiles: {
|
||||||
DEV_BUNDLE_ID => main_profile_name,
|
DEV_BUNDLE_ID => main_profile_name,
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ const int kTimelineAssetLoadBatchSize = 1024;
|
|||||||
const int kTimelineAssetLoadOppositeSize = 64;
|
const int kTimelineAssetLoadOppositeSize = 64;
|
||||||
|
|
||||||
// Widget keys
|
// Widget keys
|
||||||
const String appShareGroupId = "group.app.immich.share";
|
|
||||||
const String kWidgetAuthToken = "widget_auth_token";
|
const String kWidgetAuthToken = "widget_auth_token";
|
||||||
const String kWidgetServerEndpoint = "widget_server_url";
|
const String kWidgetServerEndpoint = "widget_server_url";
|
||||||
const String kWidgetCustomHeaders = "widget_custom_headers";
|
const String kWidgetCustomHeaders = "widget_custom_headers";
|
||||||
|
|||||||
Generated
+19
@@ -309,4 +309,23 @@ class NetworkApi {
|
|||||||
|
|
||||||
_extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true);
|
_extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<String> getAppGroupId() async {
|
||||||
|
final pigeonVar_channelName =
|
||||||
|
'dev.flutter.pigeon.immich_mobile.NetworkApi.getAppGroupId$pigeonVar_messageChannelSuffix';
|
||||||
|
final pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
|
pigeonVar_channelName,
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: pigeonVar_binaryMessenger,
|
||||||
|
);
|
||||||
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
|
||||||
|
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
||||||
|
|
||||||
|
final Object? pigeonVar_replyValue = _extractReplyValueOrThrow(
|
||||||
|
pigeonVar_replyList,
|
||||||
|
pigeonVar_channelName,
|
||||||
|
isNullValid: false,
|
||||||
|
);
|
||||||
|
return pigeonVar_replyValue! as String;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
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/providers/infrastructure/platform.provider.dart';
|
||||||
|
|
||||||
final widgetRepositoryProvider = Provider((_) => const WidgetRepository());
|
final widgetRepositoryProvider = Provider((_) => const WidgetRepository());
|
||||||
|
|
||||||
@@ -14,7 +15,7 @@ class WidgetRepository {
|
|||||||
await HomeWidget.updateWidget(iOSName: iosName, qualifiedAndroidName: androidName);
|
await HomeWidget.updateWidget(iOSName: iosName, qualifiedAndroidName: androidName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> setAppGroupId(String appGroupId) async {
|
Future<void> setAppGroupId() async {
|
||||||
await HomeWidget.setAppGroupId(appGroupId);
|
await HomeWidget.setAppGroupId(await networkApi.getAppGroupId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class WidgetService {
|
|||||||
const WidgetService(this._repository);
|
const WidgetService(this._repository);
|
||||||
|
|
||||||
Future<void> writeCredentials(String serverURL, String sessionKey, String? customHeaders) async {
|
Future<void> writeCredentials(String serverURL, String sessionKey, String? customHeaders) async {
|
||||||
await _repository.setAppGroupId(appShareGroupId);
|
await _repository.setAppGroupId();
|
||||||
await _repository.saveData(kWidgetServerEndpoint, serverURL);
|
await _repository.saveData(kWidgetServerEndpoint, serverURL);
|
||||||
await _repository.saveData(kWidgetAuthToken, sessionKey);
|
await _repository.saveData(kWidgetAuthToken, sessionKey);
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ class WidgetService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> clearCredentials() async {
|
Future<void> clearCredentials() async {
|
||||||
await _repository.setAppGroupId(appShareGroupId);
|
await _repository.setAppGroupId();
|
||||||
await _repository.saveData(kWidgetServerEndpoint, "");
|
await _repository.saveData(kWidgetServerEndpoint, "");
|
||||||
await _repository.saveData(kWidgetAuthToken, "");
|
await _repository.saveData(kWidgetAuthToken, "");
|
||||||
await _repository.saveData(kWidgetCustomHeaders, "");
|
await _repository.saveData(kWidgetCustomHeaders, "");
|
||||||
|
|||||||
@@ -44,4 +44,6 @@ abstract class NetworkApi {
|
|||||||
int getClientPointer();
|
int getClientPointer();
|
||||||
|
|
||||||
void setRequestHeaders(Map<String, String> headers, List<String> serverUrls, String? token);
|
void setRequestHeaders(Map<String, String> headers, List<String> serverUrls, String? token);
|
||||||
|
|
||||||
|
String getAppGroupId();
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@utility immich-form-input {
|
@utility immich-form-input {
|
||||||
@apply bg-gray-100 ring-1 ring-gray-200 transition outline-none focus-within:ring-1 disabled:cursor-not-allowed dark:bg-gray-800 dark:ring-neutral-900 flex w-full items-center rounded-lg disabled:bg-gray-300 disabled:text-dark dark:disabled:bg-gray-900 dark:disabled:text-gray-200 flex-1 py-2.5 text-base pl-4 pr-4;
|
@apply bg-gray-100 ring-1 ring-gray-200 transition outline-none focus-within:ring-primary focus-within:ring-1 disabled:cursor-not-allowed dark:bg-gray-800 dark:ring-neutral-900 dark:focus-within:ring-primary flex w-full items-center rounded-lg disabled:bg-gray-300 disabled:text-dark dark:disabled:bg-gray-900 dark:disabled:text-gray-200 flex-1 py-2.5 text-base pl-4 pr-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@utility immich-form-label {
|
@utility immich-form-label {
|
||||||
|
|||||||
+145
-1
@@ -1,17 +1,35 @@
|
|||||||
import { defaultProvider, screencastManager, themeManager, ThemePreference, type ActionItem } from '@immich/ui';
|
import { defaultProvider, screencastManager, themeManager, ThemePreference, type ActionItem } from '@immich/ui';
|
||||||
import {
|
import {
|
||||||
mdiAccountMultipleOutline,
|
mdiAccountMultipleOutline,
|
||||||
|
mdiAccountOutline,
|
||||||
|
mdiArchiveArrowDownOutline,
|
||||||
mdiBookshelf,
|
mdiBookshelf,
|
||||||
mdiCog,
|
mdiCog,
|
||||||
|
mdiContentDuplicate,
|
||||||
|
mdiCrosshairsGps,
|
||||||
|
mdiFolderOutline,
|
||||||
|
mdiHeartOutline,
|
||||||
|
mdiImageAlbum,
|
||||||
|
mdiImageMultipleOutline,
|
||||||
|
mdiImageSizeSelectLarge,
|
||||||
mdiKeyboard,
|
mdiKeyboard,
|
||||||
|
mdiLink,
|
||||||
|
mdiLockOutline,
|
||||||
|
mdiMagnify,
|
||||||
|
mdiMapOutline,
|
||||||
mdiServer,
|
mdiServer,
|
||||||
|
mdiStateMachine,
|
||||||
mdiSync,
|
mdiSync,
|
||||||
|
mdiTagMultipleOutline,
|
||||||
mdiThemeLightDark,
|
mdiThemeLightDark,
|
||||||
|
mdiToolboxOutline,
|
||||||
|
mdiTrashCanOutline,
|
||||||
} from '@mdi/js';
|
} from '@mdi/js';
|
||||||
import type { MessageFormatter } from 'svelte-i18n';
|
import type { MessageFormatter } from 'svelte-i18n';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { page } from '$app/state';
|
import { page } from '$app/state';
|
||||||
import { authManager } from '$lib/managers/auth-manager.svelte';
|
import { authManager } from '$lib/managers/auth-manager.svelte';
|
||||||
|
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
|
||||||
import { Route } from '$lib/route';
|
import { Route } from '$lib/route';
|
||||||
import { copyToClipboard } from '$lib/utils';
|
import { copyToClipboard } from '$lib/utils';
|
||||||
|
|
||||||
@@ -49,7 +67,133 @@ export const getPagesProvider = ($t: MessageFormatter) => {
|
|||||||
},
|
},
|
||||||
].map((route) => ({ ...route, $if: () => authManager.authenticated && authManager.user.isAdmin }));
|
].map((route) => ({ ...route, $if: () => authManager.authenticated && authManager.user.isAdmin }));
|
||||||
|
|
||||||
return defaultProvider({ name: $t('page'), actions: adminPages });
|
const userPages: ActionItem[] = [
|
||||||
|
{
|
||||||
|
title: $t('photos'),
|
||||||
|
icon: mdiImageMultipleOutline,
|
||||||
|
onAction: () => goto(Route.photos()),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('explore'),
|
||||||
|
icon: mdiMagnify,
|
||||||
|
onAction: () => goto(Route.explore()),
|
||||||
|
$if: () => authManager.authenticated && featureFlagsManager.value.search,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: $t('map'),
|
||||||
|
icon: mdiMapOutline,
|
||||||
|
onAction: () => goto(Route.map()),
|
||||||
|
$if: () => authManager.authenticated && featureFlagsManager.value.map,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('people'),
|
||||||
|
description: $t('people_feature_description'),
|
||||||
|
icon: mdiAccountOutline,
|
||||||
|
onAction: () => goto(Route.people()),
|
||||||
|
$if: () => authManager.authenticated && authManager.preferences.people.enabled,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('shared_links'),
|
||||||
|
icon: mdiLink,
|
||||||
|
onAction: () => goto(Route.sharedLinks()),
|
||||||
|
$if: () => authManager.authenticated && authManager.preferences.sharedLinks.enabled,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('recently_added'),
|
||||||
|
icon: mdiMagnify,
|
||||||
|
onAction: () => goto(Route.recentlyAdded()),
|
||||||
|
$if: () => authManager.authenticated,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('sharing'),
|
||||||
|
icon: mdiAccountMultipleOutline,
|
||||||
|
onAction: () => goto(Route.sharing()),
|
||||||
|
$if: () => authManager.authenticated,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('favorites'),
|
||||||
|
icon: mdiHeartOutline,
|
||||||
|
onAction: () => goto(Route.favorites()),
|
||||||
|
$if: () => authManager.authenticated,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('albums'),
|
||||||
|
description: $t('albums_feature_description'),
|
||||||
|
icon: mdiImageAlbum,
|
||||||
|
onAction: () => goto(Route.albums()),
|
||||||
|
$if: () => authManager.authenticated,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('tags'),
|
||||||
|
description: $t('tag_feature_description'),
|
||||||
|
icon: mdiTagMultipleOutline,
|
||||||
|
onAction: () => goto(Route.tags()),
|
||||||
|
$if: () => authManager.authenticated && authManager.preferences.tags.enabled,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('folders'),
|
||||||
|
description: $t('folders_feature_description'),
|
||||||
|
icon: mdiFolderOutline,
|
||||||
|
onAction: () => goto(Route.folders()),
|
||||||
|
$if: () => authManager.authenticated && authManager.preferences.folders.enabled,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('utilities'),
|
||||||
|
icon: mdiToolboxOutline,
|
||||||
|
onAction: () => goto(Route.utilities()),
|
||||||
|
$if: () => authManager.authenticated,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('archive'),
|
||||||
|
icon: mdiArchiveArrowDownOutline,
|
||||||
|
onAction: () => goto(Route.archive()),
|
||||||
|
$if: () => authManager.authenticated,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('locked_folder'),
|
||||||
|
icon: mdiLockOutline,
|
||||||
|
onAction: () => goto(Route.locked()),
|
||||||
|
$if: () => authManager.authenticated,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('trash'),
|
||||||
|
icon: mdiTrashCanOutline,
|
||||||
|
onAction: () => goto(Route.trash()),
|
||||||
|
$if: () => authManager.authenticated && featureFlagsManager.value.trash,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('admin.user_settings'),
|
||||||
|
icon: mdiCog,
|
||||||
|
onAction: () => goto(Route.userSettings()),
|
||||||
|
$if: () => authManager.authenticated,
|
||||||
|
},
|
||||||
|
].map((route) => ({ $if: () => authManager.authenticated, ...route }));
|
||||||
|
|
||||||
|
const utilityPages: ActionItem[] = [
|
||||||
|
{
|
||||||
|
title: $t('review_duplicates'),
|
||||||
|
icon: mdiContentDuplicate,
|
||||||
|
onAction: () => goto(Route.duplicatesUtility()),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('review_large_files'),
|
||||||
|
icon: mdiImageSizeSelectLarge,
|
||||||
|
onAction: () => goto(Route.largeFileUtility()),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('manage_geolocation'),
|
||||||
|
icon: mdiCrosshairsGps,
|
||||||
|
onAction: () => goto(Route.geolocationUtility()),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: $t('workflows'),
|
||||||
|
icon: mdiStateMachine,
|
||||||
|
onAction: () => goto(Route.workflows()),
|
||||||
|
},
|
||||||
|
].map((route) => ({ ...route, $if: () => authManager.authenticated }));
|
||||||
|
|
||||||
|
return defaultProvider({ name: $t('page'), actions: [...userPages, ...utilityPages, ...adminPages] });
|
||||||
};
|
};
|
||||||
|
|
||||||
const getMyImmichLink = () => {
|
const getMyImmichLink = () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user