From 3d3232eedcb92879203f9b5d0a2d12835c3bcae1 Mon Sep 17 00:00:00 2001
From: Isaac <>
Date: Fri, 13 Mar 2026 09:00:55 +0100
Subject: [PATCH] Temp
---
.bazelrc | 35 +++-
.vscode/settings.json | 4 +-
BUILD.bazel | 7 +-
Telegram/BUILD | 24 ++-
Tests/TelegramCoreBuildTest/BUILD | 21 ++-
build-system/Make/Make.py | 1 -
build-system/bazel-rules/rules_apple | 2 +-
build-system/bazel-utils/plist_fragment.bzl | 3 +
scripts/lldb_build_common.sh | 3 -
.../TelegramUI/Sources/AppDelegate.swift | 152 ++++++++++--------
.../Sources/ChatHistoryEntriesForView.swift | 6 +
.../Sources/ChatHistoryViewForLocation.swift | 8 +-
.../Sources/SharedWakeupManager.swift | 52 ++++--
13 files changed, 205 insertions(+), 113 deletions(-)
diff --git a/.bazelrc b/.bazelrc
index 1ce9174344..9127415f6a 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -22,14 +22,36 @@ build --strategy=SwiftCompile=worker
#common --registry=https://raw.githubusercontent.com/bazelbuild/bazel-central-registry/main/
-# SourceKit BSP: Swift indexing features
-common --features=swift.index_while_building
-common --features=swift.use_global_index_store
-common --features=swift.use_global_module_cache
-common --features=oso_prefix_is_pwd
+# rules_swift flags migration
+# --swiftcopt and --host_swiftcopt are deprecated
+common --flag_alias=swiftcopt=@build_bazel_rules_swift//swift:copt
+common --flag_alias=host_swiftcopt=@build_bazel_rules_swift//swift:exec_copt
+#common --swiftcopt=-whole-module-optimization
+#common --host_swiftcopt=-whole-module-optimization
-# SourceKit BSP: Index build config (used for background indexing)
+common --check_visibility=false
+
+# All of the following are Debug/Index setup configs inspired by the default rules_xcodeproj template
+
+common --verbose_failures
+common --cache_computed_file_digests=500000
+common --action_cache_store_output_metadata
+common --experimental_use_cpp_compile_action_args_params_file
+common --define=apple.experimental.tree_artifact_outputs=1
+common --features=apple.swizzle_absolute_xcttestsourcelocation
+common --features=oso_prefix_is_pwd
+common --features=relative_ast_path
+common --features=swift.cacheable_swiftmodules
+common --features=swift.index_while_building
+common --features=swift.use_global_module_cache
+common --features=swift.emit_swiftsourceinfo
+common --nolegacy_important_outputs
+build --noworker_sandboxing
+build --spawn_strategy=remote,worker,local
+
+# Only for BSP builds
common:index_build --experimental_convenience_symlinks=ignore
+common:index_build --bes_backend= --bes_results_url=
common:index_build --show_result=0
common:index_build --noshow_loading_progress
common:index_build --noshow_progress
@@ -37,3 +59,4 @@ common:index_build --noannounce_rc
common:index_build --noshow_timestamps
common:index_build --curses=no
common:index_build --color=no
+
diff --git a/.vscode/settings.json b/.vscode/settings.json
index d1e808574b..ba34a33e56 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -23,5 +23,7 @@
]
}
},
- "swift.sourcekit-lsp.serverPath": "${workspaceFolder}/build-input/sourcekit-lsp"
+ "swift.sourcekit-lsp.serverPath": "${workspaceFolder}/build-input/sourcekit-lsp",
+ "sourcekit-bazel-bsp.rulesAppleName": "build_bazel_rules_apple",
+ "cmake.sourceDirectory": "/Users/ali/build/telegram/telegram-ios/submodules/rlottie/rlottie/test"
}
diff --git a/BUILD.bazel b/BUILD.bazel
index 05e5d1c325..4292181ff1 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -1,5 +1,7 @@
load("@sourcekit_bazel_bsp//rules:setup_sourcekit_bsp.bzl", "setup_sourcekit_bsp")
+exports_files(["versions.json"])
+
setup_sourcekit_bsp(
name = "setup_sourcekit_bsp",
bazel_wrapper = "./build-input/bazel-8.4.2-darwin-arm64",
@@ -18,17 +20,12 @@ setup_sourcekit_bsp(
"submodules/**/*.cpp",
],
aquery_flags = [
- "define=telegramVersion=12.5",
- "define=buildNumber=100000",
],
index_flags = [
"config=index_build",
- "define=telegramVersion=12.5",
- "define=buildNumber=100000",
],
index_build_batch_size = 10,
targets = [
"//Telegram:Telegram",
],
- merge_lsp_config = False,
)
diff --git a/Telegram/BUILD b/Telegram/BUILD
index 15f6fe2c5f..a1cf7d9524 100644
--- a/Telegram/BUILD
+++ b/Telegram/BUILD
@@ -385,7 +385,8 @@ plist_fragment(
"""
CFBundleVersion
{buildNumber}
- """
+ """,
+ defaults = {"buildNumber": "1"},
)
plist_fragment(
@@ -574,14 +575,23 @@ plist_fragment(
])
)
-plist_fragment(
+genrule(
name = "VersionInfoPlist",
- extension = "plist",
- template =
- """
+ srcs = ["//:versions.json"],
+ outs = ["VersionInfoPlist.plist"],
+ cmd = """
+ version=$$(python3 -c "import json; print(json.load(open('$(location //:versions.json)'))['app'])")
+ cat > $@ <
+
+
+
CFBundleShortVersionString
- {telegramVersion}
- """
+ $$version
+
+
+PLIST
+ """,
)
plist_fragment(
diff --git a/Tests/TelegramCoreBuildTest/BUILD b/Tests/TelegramCoreBuildTest/BUILD
index 8b4227a100..e5038bea6f 100644
--- a/Tests/TelegramCoreBuildTest/BUILD
+++ b/Tests/TelegramCoreBuildTest/BUILD
@@ -43,14 +43,23 @@ plist_fragment(
"""
)
-plist_fragment(
+genrule(
name = "VersionInfoPlist",
- extension = "plist",
- template =
- """
+ srcs = ["//:versions.json"],
+ outs = ["VersionInfoPlist.plist"],
+ cmd = """
+ version=$$(python3 -c "import json; print(json.load(open('$(location //:versions.json)'))['app'])")
+ cat > $@ <
+
+
+
CFBundleShortVersionString
- {telegramVersion}
- """
+ $$version
+
+
+PLIST
+ """,
)
plist_fragment(
diff --git a/build-system/Make/Make.py b/build-system/Make/Make.py
index ebff8097e5..457e5d9517 100644
--- a/build-system/Make/Make.py
+++ b/build-system/Make/Make.py
@@ -212,7 +212,6 @@ class BazelCommandLine:
def get_define_arguments(self):
return [
'--define=buildNumber={}'.format(self.build_number),
- '--define=telegramVersion={}'.format(self.build_environment.app_version)
]
def get_project_generation_arguments(self):
diff --git a/build-system/bazel-rules/rules_apple b/build-system/bazel-rules/rules_apple
index 39cc252924..f6aef7db5b 160000
--- a/build-system/bazel-rules/rules_apple
+++ b/build-system/bazel-rules/rules_apple
@@ -1 +1 @@
-Subproject commit 39cc2529241335d20afcb6700c587d064e7a2870
+Subproject commit f6aef7db5b649ffc3b7497ecc83a08ad3ab19559
diff --git a/build-system/bazel-utils/plist_fragment.bzl b/build-system/bazel-utils/plist_fragment.bzl
index ac40575332..64ef8d4076 100644
--- a/build-system/bazel-utils/plist_fragment.bzl
+++ b/build-system/bazel-utils/plist_fragment.bzl
@@ -18,6 +18,8 @@ def _plist_fragment(ctx):
resolved_values = dict()
for key in found_keys:
value = ctx.var.get(key, None)
+ if value == None:
+ value = ctx.attr.defaults.get(key, None)
if value == None:
fail("Expected value for --define={} was not found".format(key))
resolved_values[key] = value
@@ -38,6 +40,7 @@ plist_fragment = rule(
attrs = {
"extension": attr.string(mandatory = True),
"template": attr.string(mandatory = True),
+ "defaults": attr.string_dict(),
},
outputs = {
"out": "%{name}.%{extension}"
diff --git a/scripts/lldb_build_common.sh b/scripts/lldb_build_common.sh
index 8633902f40..223417bc5b 100755
--- a/scripts/lldb_build_common.sh
+++ b/scripts/lldb_build_common.sh
@@ -10,12 +10,9 @@ WORKSPACE_ROOT=$(pwd)
BAZEL_CMD="./build-input/bazel-8.4.2-darwin-arm64"
export ADDITIONAL_FLAGS=()
-TELEGRAM_VERSION=$(python3 -c "import json; print(json.load(open('${WORKSPACE_ROOT}/versions.json'))['app'])")
ADDITIONAL_FLAGS+=("--keep_going")
ADDITIONAL_FLAGS+=("--color=yes")
-ADDITIONAL_FLAGS+=("--define=telegramVersion=${TELEGRAM_VERSION}")
-ADDITIONAL_FLAGS+=("--define=buildNumber=100000")
if [ -n "${BAZEL_EXTRA_BUILD_FLAGS:-}" ]; then
ADDITIONAL_FLAGS+=("${BAZEL_EXTRA_BUILD_FLAGS[@]}")
diff --git a/submodules/TelegramUI/Sources/AppDelegate.swift b/submodules/TelegramUI/Sources/AppDelegate.swift
index f28a25671b..042bcda543 100644
--- a/submodules/TelegramUI/Sources/AppDelegate.swift
+++ b/submodules/TelegramUI/Sources/AppDelegate.swift
@@ -551,80 +551,94 @@ private func extractAccountManagerState(records: AccountRecordsView CallSessionManagerImplementationVersion in
- CallSessionManagerImplementationVersion(version: version, supportsVideo: supportsVideo)
- }, appData: self.regularDeviceToken.get()
- |> map { token in
- let tokenEnvironment: String
- #if DEBUG
- tokenEnvironment = "sandbox"
- #else
- tokenEnvironment = "production"
- #endif
-
- let data = buildConfig.bundleData(withAppToken: token, tokenType: "apns", tokenEnvironment: tokenEnvironment, signatureDict: signatureDict)
- if let data = data, let _ = String(data: data, encoding: .utf8) {
- } else {
- Logger.shared.log("data", "can't deserialize")
- }
- return data
- }, externalRequestVerificationStream: self.firebaseRequestVerificationSecretStream.get(), externalRecaptchaRequestVerification: { method, siteKey in
- return Signal { subscriber in
- let recaptchaClient: Promise
- if let current = self.recaptchaClientsBySiteKey[siteKey] {
- recaptchaClient = current
- } else {
- recaptchaClient = Promise()
- self.recaptchaClientsBySiteKey[siteKey] = recaptchaClient
-
- Recaptcha.fetchClient(withSiteKey: siteKey) { client, error in
- Queue.mainQueue().async {
- guard let client else {
- Logger.shared.log("App \(self.episodeId)", "RecaptchaClient creation error: \(String(describing: error)).")
- return
- }
- recaptchaClient.set(.single(client))
- }
- }
- }
+ let networkArguments = NetworkInitializationArguments(
+ apiId: apiId,
+ apiHash: apiHash,
+ languagesCategory: languagesCategory,
+ appVersion: appVersion,
+ voipMaxLayer: PresentationCallManagerImpl.voipMaxLayer,
+ voipVersions: PresentationCallManagerImpl.voipVersions(includeExperimental: true, includeReference: false).map { version, supportsVideo -> CallSessionManagerImplementationVersion in
+ CallSessionManagerImplementationVersion(version: version, supportsVideo: supportsVideo)
+ },
+ appData: self.regularDeviceToken.get() |> map { token in
+ let tokenEnvironment: String
+ #if DEBUG
+ tokenEnvironment = "sandbox"
+ #else
+ tokenEnvironment = "production"
+ #endif
- return (recaptchaClient.get()
- |> take(1)
- |> mapToSignal { recaptchaClient -> Signal in
- return Signal { subscriber in
- var recaptchaAction: RecaptchaAction?
- switch method {
- case "signup":
- recaptchaAction = RecaptchaAction.signup
- default:
- break
- }
+ let data = buildConfig.bundleData(withAppToken: token, tokenType: "apns", tokenEnvironment: tokenEnvironment, signatureDict: signatureDict)
+ if let data = data, let _ = String(data: data, encoding: .utf8) {
+ } else {
+ Logger.shared.log("data", "can't deserialize")
+ }
+ return data
+ },
+ externalRequestVerificationStream: self.firebaseRequestVerificationSecretStream.get(),
+ externalRecaptchaRequestVerification: { method, siteKey in
+ return Signal { subscriber in
+ let recaptchaClient: Promise
+ if let current = self.recaptchaClientsBySiteKey[siteKey] {
+ recaptchaClient = current
+ } else {
+ recaptchaClient = Promise()
+ self.recaptchaClientsBySiteKey[siteKey] = recaptchaClient
- guard let recaptchaAction else {
- subscriber.putNext(nil)
- subscriber.putCompletion()
-
- return EmptyDisposable
- }
- recaptchaClient.execute(withAction: recaptchaAction) { token, error in
- if let token {
- subscriber.putNext(token)
- Logger.shared.log("App \(self.episodeId)", "RecaptchaClient executed successfully")
- } else {
- subscriber.putNext(nil)
- Logger.shared.log("App \(self.episodeId)", "RecaptchaClient execute error: \(String(describing: error))")
+ Recaptcha.fetchClient(withSiteKey: siteKey) { client, error in
+ Queue.mainQueue().async {
+ guard let client else {
+ Logger.shared.log("App \(self.episodeId)", "RecaptchaClient creation error: \(String(describing: error)).")
+ return
+ }
+ recaptchaClient.set(.single(client))
}
- subscriber.putCompletion()
- }
-
- return ActionDisposable {
}
}
- |> runOn(Queue.mainQueue())
- }).startStandalone(next: subscriber.putNext, error: subscriber.putError, completed: subscriber.putCompletion)
- }
- |> runOn(Queue.mainQueue())
- }, autolockDeadine: autolockDeadine, encryptionProvider: OpenSSLEncryptionProvider(), deviceModelName: nil, useBetaFeatures: !buildConfig.isAppStoreBuild, isICloudEnabled: buildConfig.isICloudEnabled)
+
+ return (recaptchaClient.get()
+ |> take(1)
+ |> mapToSignal { recaptchaClient -> Signal in
+ return Signal { subscriber in
+ var recaptchaAction: RecaptchaAction?
+ switch method {
+ case "signup":
+ recaptchaAction = RecaptchaAction.signup
+ default:
+ break
+ }
+
+ guard let recaptchaAction else {
+ subscriber.putNext(nil)
+ subscriber.putCompletion()
+
+ return EmptyDisposable
+ }
+ recaptchaClient.execute(withAction: recaptchaAction) { token, error in
+ if let token {
+ subscriber.putNext(token)
+ Logger.shared.log("App \(self.episodeId)", "RecaptchaClient executed successfully")
+ } else {
+ subscriber.putNext(nil)
+ Logger.shared.log("App \(self.episodeId)", "RecaptchaClient execute error: \(String(describing: error))")
+ }
+ subscriber.putCompletion()
+ }
+
+ return ActionDisposable {
+ }
+ }
+ |> runOn(Queue.mainQueue())
+ }).startStandalone(next: subscriber.putNext, error: subscriber.putError, completed: subscriber.putCompletion)
+ }
+ |> runOn(Queue.mainQueue())
+ },
+ autolockDeadine: autolockDeadine,
+ encryptionProvider: OpenSSLEncryptionProvider(),
+ deviceModelName: nil,
+ useBetaFeatures: !buildConfig.isAppStoreBuild,
+ isICloudEnabled: buildConfig.isICloudEnabled
+ )
guard let appGroupUrl = maybeAppGroupUrl else {
self.mainWindow?.presentNative(UIAlertController(title: nil, message: "Error 2", preferredStyle: .alert))
diff --git a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift
index 0bf833a029..15bbad296b 100644
--- a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift
+++ b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift
@@ -433,6 +433,12 @@ func chatHistoryEntriesForView(
var i = 0
let unreadEntry: ChatHistoryEntry = .UnreadEntry(maxReadIndex, presentationData)
for entry in entries {
+ if case let .MessageGroupEntry(_, messages, _) = entry {
+ if !messages.isEmpty && maxReadIndex >= messages[0].0.index {
+ i += 1
+ continue
+ }
+ }
if entry > unreadEntry {
if i != 0 {
entries.insert(unreadEntry, at: i)
diff --git a/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift b/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift
index 00ba078433..b990c02468 100644
--- a/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift
+++ b/submodules/TelegramUI/Sources/ChatHistoryViewForLocation.swift
@@ -65,7 +65,7 @@ func chatHistoryViewForLocation(
let combinedInitialData = ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData)
- if view.isLoading {
+ if view.isLoading || (view.entries.isEmpty && (view.holeEarlier || view.holeLater)) {
return .Loading(initialData: combinedInitialData, type: .Generic(type: updateType))
}
@@ -147,7 +147,7 @@ func chatHistoryViewForLocation(
if preloaded {
return .HistoryView(view: view, type: .Generic(type: updateType), scrollPosition: nil, flashIndicators: false, originalScrollPosition: nil, initialData: combinedInitialData, id: location.id)
} else {
- if view.isLoading {
+ if view.isLoading || (view.entries.isEmpty && (view.holeEarlier || view.holeLater)) {
return .Loading(initialData: combinedInitialData, type: .Generic(type: updateType))
}
var scrollPosition: ChatHistoryViewScrollPosition?
@@ -311,7 +311,7 @@ func chatHistoryViewForLocation(
let combinedInitialData = ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData)
- if view.isLoading {
+ if view.isLoading || (view.entries.isEmpty && (view.holeEarlier || view.holeLater)) {
return ChatHistoryViewUpdate.Loading(initialData: combinedInitialData, type: .Generic(type: updateType))
}
@@ -461,7 +461,7 @@ func fetchAndPreloadReplyThreadInfo(context: AccountContext, subject: ReplyThrea
case .Loading:
return nil
case let .HistoryView(view, _, _, _, _, _, _):
- if view.isLoading {
+ if view.isLoading || (view.entries.isEmpty && (view.holeEarlier || view.holeLater)) {
return nil
}
return view.entries.isEmpty
diff --git a/submodules/TelegramUI/Sources/SharedWakeupManager.swift b/submodules/TelegramUI/Sources/SharedWakeupManager.swift
index e259fd8693..4e6bb1fcc7 100644
--- a/submodules/TelegramUI/Sources/SharedWakeupManager.swift
+++ b/submodules/TelegramUI/Sources/SharedWakeupManager.swift
@@ -50,6 +50,8 @@ private struct AccountTasks {
}
}
+private let backgroundTaskSubmissionDelay: Double = 10.0
+
private struct PendingMediaUploadKey: Hashable {
let accountId: AccountRecordId
let messageId: MessageId
@@ -99,7 +101,8 @@ public final class SharedWakeupManager {
private var backgroundProcessingTaskId: String?
private var backgroundProcessingTaskLaunched: Bool = false
private var backgroundProcessingTaskCancellationRequestedByApp: Bool = false
-
+ private var pendingBackgroundProcessingTaskTimer: SwiftSignalKit.Timer?
+
private var pendingStoryUploadsByKey: [PendingStoryUploadKey: Float] = [:]
private var pendingStoryUploadStatusesByKey: [PendingStoryUploadKey: PendingStoryUploadStatus] = [:]
private var backgroundStoryProcessingTaskProgressByKey: [PendingStoryUploadKey: Float] = [:]
@@ -107,7 +110,8 @@ public final class SharedWakeupManager {
private var backgroundStoryProcessingTaskId: String?
private var backgroundStoryProcessingTaskLaunched: Bool = false
private var backgroundStoryProcessingTaskCancellationRequestedByApp: Bool = false
-
+ private var pendingBackgroundStoryProcessingTaskTimer: SwiftSignalKit.Timer?
+
public init(beginBackgroundTask: @escaping (String, @escaping () -> Void) -> UIBackgroundTaskIdentifier?, endBackgroundTask: @escaping (UIBackgroundTaskIdentifier) -> Void, backgroundTimeRemaining: @escaping () -> Double, acquireIdleExtension: @escaping () -> Disposable?, activeAccounts: Signal<(primary: Account?, accounts: [(AccountRecordId, Account)]), NoError>, liveLocationPolling: Signal, watchTasks: Signal, inForeground: Signal, hasActiveAudioSession: Signal, notificationManager: SharedNotificationManager?, mediaManager: MediaManager, callManager: PresentationCallManager?, accountUserInterfaceInUse: @escaping (AccountRecordId) -> Signal, presentationData: @escaping () -> PresentationData?) {
assert(Queue.mainQueue().isCurrent())
@@ -155,6 +159,10 @@ public final class SharedWakeupManager {
}
strongSelf.allowBackgroundTimeExtensionDeadlineTimer?.invalidate()
strongSelf.allowBackgroundTimeExtensionDeadlineTimer = nil
+ strongSelf.pendingBackgroundProcessingTaskTimer?.invalidate()
+ strongSelf.pendingBackgroundProcessingTaskTimer = nil
+ strongSelf.pendingBackgroundStoryProcessingTaskTimer?.invalidate()
+ strongSelf.pendingBackgroundStoryProcessingTaskTimer = nil
}
strongSelf.updateBackgroundProcessingTaskStateFromPendingMediaUploads()
strongSelf.updateBackgroundProcessingTaskStateFromPendingStoryUploads()
@@ -356,6 +364,8 @@ public final class SharedWakeupManager {
self.pendingStoryUploadsDisposable?.dispose()
self.managedPausedInBackgroundPlayer?.dispose()
self.keepIdleDisposable?.dispose()
+ self.pendingBackgroundProcessingTaskTimer?.invalidate()
+ self.pendingBackgroundStoryProcessingTaskTimer?.invalidate()
if let (taskId, _, timer) = self.currentTask {
timer.invalidate()
self.endBackgroundTask(taskId)
@@ -369,19 +379,30 @@ public final class SharedWakeupManager {
let shouldHaveTask = !self.pendingMediaUploadsByKey.isEmpty && !self.inForeground
let hadTask = self.backgroundProcessingTaskId != nil
-
+
if shouldHaveTask {
- if !hadTask {
- self.startBackgroundProcessingTaskIfNeeded()
+ if !hadTask && self.pendingBackgroundProcessingTaskTimer == nil {
+ let timer = SwiftSignalKit.Timer(timeout: backgroundTaskSubmissionDelay, repeat: false, completion: { [weak self] in
+ guard let self else {
+ return
+ }
+ self.pendingBackgroundProcessingTaskTimer = nil
+ self.startBackgroundProcessingTaskIfNeeded()
+ }, queue: .mainQueue())
+ self.pendingBackgroundProcessingTaskTimer = timer
+ timer.start()
}
} else {
+ self.pendingBackgroundProcessingTaskTimer?.invalidate()
+ self.pendingBackgroundProcessingTaskTimer = nil
+
if let backgroundProcessingTaskId = self.backgroundProcessingTaskId {
if !self.backgroundProcessingTaskCancellationRequestedByApp {
self.backgroundProcessingTaskCancellationRequestedByApp = true
BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: backgroundProcessingTaskId)
Logger.shared.log("Wakeup", "Requested BG task cancellation by app: \(backgroundProcessingTaskId)")
}
-
+
if !self.backgroundProcessingTaskLaunched {
self.backgroundProcessingTaskId = nil
self.backgroundProcessingTaskProgressByKey = [:]
@@ -399,19 +420,30 @@ public final class SharedWakeupManager {
let shouldHaveTask = !self.pendingStoryUploadStatusesByKey.isEmpty && !self.inForeground
let hadTask = self.backgroundStoryProcessingTaskId != nil
-
+
if shouldHaveTask {
- if !hadTask {
- self.startBackgroundStoryProcessingTaskIfNeeded()
+ if !hadTask && self.pendingBackgroundStoryProcessingTaskTimer == nil {
+ let timer = SwiftSignalKit.Timer(timeout: backgroundTaskSubmissionDelay, repeat: false, completion: { [weak self] in
+ guard let self else {
+ return
+ }
+ self.pendingBackgroundStoryProcessingTaskTimer = nil
+ self.startBackgroundStoryProcessingTaskIfNeeded()
+ }, queue: .mainQueue())
+ self.pendingBackgroundStoryProcessingTaskTimer = timer
+ timer.start()
}
} else {
+ self.pendingBackgroundStoryProcessingTaskTimer?.invalidate()
+ self.pendingBackgroundStoryProcessingTaskTimer = nil
+
if let backgroundStoryProcessingTaskId = self.backgroundStoryProcessingTaskId {
if !self.backgroundStoryProcessingTaskCancellationRequestedByApp {
self.backgroundStoryProcessingTaskCancellationRequestedByApp = true
BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: backgroundStoryProcessingTaskId)
Logger.shared.log("Wakeup", "Requested story BG task cancellation by app: \(backgroundStoryProcessingTaskId)")
}
-
+
if !self.backgroundStoryProcessingTaskLaunched {
self.backgroundStoryProcessingTaskId = nil
self.backgroundStoryProcessingTaskProgressByKey = [:]